maven、spring

一、maven

maven是Java项目依赖的管理仓库

1.maven的生命周期:

(1)clean:主要是清理工作

(2)default:是构建的核心部分,编译,测试,打包,部署等等,Default生命周期是Maven生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。

(3)site:生成项目的时候,会产生站点,可以理解为tomcat发布的webapp,作为一个网站

2.maven的核心概念

(1)maven的三个坐标简称GAV

groupId:公司或组织的 id,即公司或组织域名的倒序,通常也会加上项目名称

例如:groupId:com.fs.maven

artifactId:一个项目或者是项目中的一个模块的 id,即模块的名称,将来作为 Maven 工程的工程名

例如:artifactId:auth

version:版本号

例如:version:1.0.0v

(2)pom.xml文件:

项目对象模型,POM 表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。这样我们就可以用程序来管理项目了。我们在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数据作为一个对象,这样就可以在程序中计算与现实事物相关的数据。

设置编码:

(3)依赖:

3-1

complie:表示编译范围,指 A 在编译时依赖 B,该范围为默认依赖范围。编译范围的依赖会用在编译,测试,运行,由于运行时需要,所以编译范围的依赖会被打包。

provided:provied 依赖只有当 jdk 或者一个容器已提供该依赖之后才使用。provide 依赖在编译和测试时需要,在运行时不需要。例如:servlet api被Tomcat容器提供了。 runtime:runtime 依赖在运行和测试系统时需要,但在编译时不需要。例如:jdbc 的驱动包。由于运行时需要,所以 runtime 范围的依赖会被打包。 test:test 范围依赖在编译和运行时都不需要,只在测试编译和测试运行时需要。例如:Junit。由于运行时不需要,所以 test 范围依赖不会被打包。 system:system 范围依赖与 provide 类似,但是必须显示的提供一个对于本地系统中 jar 文件的路径。

3-2依赖的传递:

A 依赖 B,B 依赖 C,那么在 A 没有配置对 C 的依赖的情况下,A 里面能不能直接使用 C?以上的前提下,C 是否能够传递到 A,取决于 B 依赖 C 时使用的依赖范围。B 依赖 C 时使用 compile 范围:可以传递,B 依赖 C 时使用 test 或 provided 范围:不能传递,所以需要这样的 jar 包时,就必须在需要的地方明确配置依赖才可以。

(4)maven的继承:

子工程会继承父工程的pom配置文件。

4-1新建子工程

新建之后父工程的pom:

子项目指定父项目工程:

此时依赖才被引入,子项目的依赖不用写版本,版本通过继承可得。

对同一个框架的一组 jar 包最好使用相同的版本,为了方便升级框架,可以将 jar 包的版本信息统一提取出来,统一声明版本号 :在需要的地方使用${}的形式来引用自定义的属性名,这样子只需要修改一个地方,就可以实现处处生效。

(5)maven的聚合

5-1:聚合其实就是使用一个总工程聚合所有的模块作为一个整体的项目,实际就是module标签

5-2:build标签 在实际使用 Maven 的过程中,我们会发现 build 标签有时候有,有时候没,这是怎么回事呢?其实通过有效 POM 我们能够看到,build 标签的相关配置其实一直都在,只是在我们需要定制构建过程的时候才会通过配置 build 标签覆盖默认值或补充配置。这一点我们可以通过打印有效 POM 来看到。打印有效 pom mvn help:effective-pom。当默认配置无法满足需求的定制构建的时候,就需要使用 build 标签。

(6)profile

profile含义:项目的每一个运行环境,相当于是项目整体的一个侧面。

通常情况下,我们项目至少有三种运行环境:

开发环境:供不同开发工程师开发的各个模块之间互相调用、访问;内部使用

测试环境:供测试工程师对项目的各个模块进行功能测试;内部使用

生产环境:供最终用户访问——所以这是正式的运行环境,对外提供服务

(7)分页查询

7-1:项目搭建:

web项目结构: WEB-INF -web.xml: web相关的配置: servlet, filter,... web3.0 使用注解替换 -classes: src目录编译生成字节码文件存放在该目录,称为类路径(发布 -lib: 第三方依赖,pom.xml添加依赖(发布时)

web项目要求: 打包方式: war 发布到tomcat,自动解压war servlet+jsp实现web项目,导入 servlet-api jsp-api依赖,scope设置为provided

7-2页面要求:

1.传递当前页码(请求参数)

2.页面需要的数据(查数据库)

3.页容量(后端设定)

4.总页数:总记录数/页容量 %= 0 则不用加1,如果余数不等于0则需要+1

5.当前页码(请求参数)

注意:

Java程序把这五个数据封装作为一个对象。

get请求,通过超链接地址栏访问

post请求:jqury的post方法,注意get里写一个post方法

二、mybatis

解决dao层问题解决方案, 之前dao使用的技术: JDBC

mybatis是一个半自动化的持久层框架,
可以注解配置、映射xml文件中编写动态sql语句。通常使用xml编写sql。
mybatis是对jdbc封装的框架,几乎不需要jdbc操作
mybatis提供面向接口,持久层只需要一个接口,不需要实现类。

一、mybaits工作原理:

(1)JDBC核心对象

  1. DriverManager,数据库驱动管理对象
  2. Connection,数据库连接对象
  3. Statement | PrepareStatement ,操作数据库SQL语句对象
  4. ResultSet,结果集对象

(2)mybaits核心对象:

        1.SqlSession对象,该对象包含了执行SQL语句的所有方法,例如JDBC里面Connection

        2.Executor接口,将传递过来的参数动态生成SQL语句,负责查询缓存。

        3.MappedStatement对象,该对象负责对SQL封装,用于存储需要映射的SQL语句及参数等信息

        4.ResultHandler对象,用户返回结果集合,封装成最红想要的数据类型,可以自定义返回类型

二、配置代码

<!DOCTYPE   mapper   ...>
<mapper   namespace="com.sly.ecs.business.mapper.mission.MissionMapper">
    <insert id="insertBatch"  parameterType="list"  ...> 
    <select id="selectMission"  parameterType="int" resultMap="BaseResultMap" ...>   
</mapper>

三、参数:

(1)传入参数的情形:
mapper接口方法的参数是单个:
xml文件用#{ },来 取 值 , 需 要 注 意 { }来取值,需要注意来取值,需要注意{ }要用单引号。
{}中的名称是任意的,因为只有一个参数,无论取值时叫什么,都能够取到值。

mapper接口方法的参数是多个:
会用Map集合保存参数,键是由mybatis框架自动生成
xml文件可以用 arg0 、arg1 。。。 获取对应位置的参数
xml文件可以用 param1 、param2 。。。 获取对应位置的参数
也可以交叉使用,例如 arg0、 param2

mapper接口方法的参数是多个,可以放到一个Map集合里
键是由开发者人为设置。
在xml映射文件里根据人为设置的键获取参数。

mapper接口方法的参数是实体类
xml文件里根据实体类的属性获取属性值。

public final class GenericQueryParam extends LinkedHashMap<String, Object> 
                                implements ListQueryParam { ...  }
var param = new GenericQueryParam();
param.fill("signCode", signCode).fill("typeId", typeId).fill("labelId", labelId)
     .fill("areaId", areaId).fill("status", status).fill("userId", userId);

(2)获取参数的两种方式:(jdbc原生写法)
${} 字符串拼接。不会带上单引号。注意要手动加上单引号。
#{} 占位符赋值。会带上单引号。不需要手动加上单引号。

示例:

常规方法

username = #{username}  AND sign_code = #{signCode}

Mybatis处理模糊查询

role_name LIKE CONCAT('%',#{roleName},'%')
role_name LIKE '%${roleName}%'
role_name LIKE "%"#{roleName}"%"

总结:    

        sql语法中需要引号的 尽量使用#{},或者${} 手动加上引号。 例如字符串、日期等类型的值。
        sql语法中不需要引号的 使用${} ,不用手动加上引号。例如in范围查询、表名、字段、排序关键字。

四、mybatis的CURD

1.添加

//mapper接口方法
void add(Brand brand);

<--配置代码-->
<insert id="add">
        insert into tb_brand (brand_name, company_name, ordered, description, status)
        values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>

<--测试代码-->
 @Test
    public void testadd() throws IOException {
 
        //接收参数:
        int status = 1;
        String companyName = "波导手机";
        String brandName = "波导";
        String description = "手机中的战斗机";
        int ordered = 100;
 
 
        //封装对象
        Brand brand = new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);
        brand.setDescription(description);
        brand.setOrdered(ordered);
 
        //1.获取SqlSessionFactory
        //加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        //返回一个字节输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 
 
        //2. 获取sqlSession对象
//        SqlSession sqlSession = sqlSessionFactory.openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
 
        //4. 执行方法
        brandMapper.add(brand);
 
        //提交事务
//        sqlSession.commit();
 
        //5. 释放资源
        sqlSession.close();
    }

 Mybatis事务:

openSession():默认开启事务,进行增删改后需要使用sqlSession.commit();手动提交事务

openSession(true):可以设置为自动提交事务(默认为false:手动提交事务)

在数据添加成功后,需要获取插入数据库数据的主键的值

2.修改

//mapper接口方法

void update(Brand brand);

//编写SQL语句:编写SQL映射文件
   <update id="update">
        update tb_brand
        set brand_name = #{brandName},
            company_name = #{companyName},
            ordered = #{ordered},
            description = #{description},
            status = #{status}
        where id = #{id};
    </update>

//测试代码
/**
     * 修改
     * @throws IOException
     */
    @Test
    public void testUpdate() throws IOException {
 
        //接收参数:
        int status = 1;
        String companyName = "波导手机";
        String brandName = "波导";
        String description = "波导手机,手机中的战斗机";
        int ordered = 200;
 
        int id = 5;
 
        //封装对象
        Brand brand = new Brand();
        brand.setStatus(status);
        brand.setCompanyName(companyName);
        brand.setBrandName(brandName);
        brand.setDescription(description);
        brand.setOrdered(ordered);
        brand.setId(id);
 
        //1.获取SqlSessionFactory
        //加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        //返回一个字节输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 
 
        //2. 获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
 
        //4. 执行方法
        int count = brandMapper.update(brand);
 
        System.out.println(count);
 
        //5. 释放资源
        sqlSession.close();
    }

3.删除

(1)删除一个

//编写SQL语句:编写SQL映射文件
<select id="deleteById">
    delete from tb_brand where id = #{id};
</select>

//测试代码
/**
     * 根据Id删除一个
     * @throws IOException
     */
    @Test
    public void testDeleteById() throws IOException {
 
        //接收参数:
        int id = 9;
 
        //1.获取SqlSessionFactory
        //加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        //返回一个字节输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 
 
        //2. 获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
 
        //4. 执行方法
        brandMapper.deleteById(id);
 
 
        //5. 释放资源
        sqlSession.close();
    }

(2)批量删除

sql映射文件

<!--
        Mybatis会将数组参数封装为一个Map集合。
            *默认:array = 数组
            *可以使用@Param注解改变map集合的默认key名称
    -->
   <!-- <delete id="deleteByIds">
        delete from tb_brand where id
         in
        /*
        **separator:分隔符
        **open:循环开始前的字符
        **close:循环结束后的字符
        */
             <foreach collection="ids" item="id" separator="," open="(" close=")">
                 #{id}
             </foreach>;
    </delete>-->
<delete id="deleteByIds">
        delete from tb_brand where id
        in
        /*
        **separator:分隔符
        **open:循环开始前的字符
        **close:循环结束后的字符
        */
        <foreach collection="array" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>;
</delete>

测试代码

/**
     * 根据Id删除一个
     * @throws IOException
     */
    @Test
    public void testDeleteById() throws IOException {
 
        //接收参数:
        int id = 9;
 
        //1.获取SqlSessionFactory
        //加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        //返回一个字节输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 
 
        //2. 获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        //3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
 
        //4. 执行方法
        brandMapper.deleteById(id);
 
        //5. 释放资源
        sqlSession.close();
    }

4.查询

sql映射文件

 <select id="selectByConditionSingle" resultMap="brandResultMap">
<!--        select *-->
<!--        from tb_brand-->
<!--        where-->
<!--            <choose>&lt;!&ndash;相当于switch&ndash;&gt;-->
<!--                <when test="status != null">-->
<!--                    status = #{status}-->
<!--                </when>&lt;!&ndash;相当于case&ndash;&gt;-->
<!--                <when test="companyName != null and companyName!= ''">-->
<!--                    company_name like #{companyName}-->
<!--                </when>&lt;!&ndash;相当于case&ndash;&gt;-->
<!--                <when test="brandName != null and brandName!= ''">-->
<!--                    brand_name like #{brandName}-->
<!--                </when>&lt;!&ndash;相当于case&ndash;&gt;-->
<!--                <otherwise>&lt;!&ndash;相当于default&ndash;&gt;-->
<!--                    1 = 1-->
<!--                </otherwise>-->
<!--            </choose>-->
<!--    </select>-->
        select *
        from tb_brand
        <where>
            <choose><!--相当于switch-->
            <when test="status != null">
                status = #{status}
            </when><!--相当于case-->
            <when test="companyName != null and companyName!= ''">
                company_name like #{companyName}
            </when><!--相当于case-->
            <when test="brandName != null and brandName!= ''">
                brand_name like #{brandName}
            </when><!--相当于case-->
            </choose>
        </where>
</select>

测试代码

@Test
    public void testSelectByCondition() throws IOException {
 
        //接收参数:
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";
 
        //处理参数
        companyName = "%" + companyName + "%";
        brandName = "%" + brandName + "%";
 
        //封装对象
        Brand brand = new Brand();
        //brand.setStatus(status);
        brand.setCompanyName(companyName);
        //brand.setBrandName(brandName);
 
        //1.获取SqlSessionFactory
        //加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        //返回一个字节输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 
 
        //2. 获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
 
        //3. 获取Mapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
 
        //4. 执行方法
//      List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
//      List<Brand> brands = brandMapper.selectByCondition(brand);
        List<Brand> brands = brandMapper.selectByCondition(map);
        System.out.println(brands);
 
        //5. 释放资源
        sqlSession.close();
    }
​

五、MyBatis参数传递

(1)POJO类型:直接使用,实体类属性名 和参数占位符名称一致

(2)Map集合:直接使用,键名和参数占位符名称一致

(3)Collection:封装为Map集合

(4)List:封装为Map集合

六、mybatis缓存机制

mybatis为减轻数据库压力,提高数据库性能。提供了两级缓存机制:

实体类:

@Data
public class Student  implements Serializable {
    private Integer stuId;
    private String stuName;
    private Integer stuAge;
    private Double stuSalary;
    private Date stuBirth;
    private Date createTime;
    private Integer courseId;
}

接口studentmapper

public interface StudentMapper {
     //通过id查询学生,传递单个参数
     Student queryStudentById(Integer id);
     //删除一条信息,通过id
     Integer delete(Integer id);
}

映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace:Mapper接口的全路径,使其和Mapper对应-->
<mapper namespace="com.yjg.mapper.StudentMapper">
    <delete id="delete">
        DELETE from student where stu_id=${id}
    </delete>

    <select id="queryStudentById" parameterType="integer" resultType="Student">
          select * from student where stu_id=${id}
    </select>
</mapper>

测试代码

@Test
public void test1() throws Exception{
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
    SqlSession sqlSession1 = sqlSessionFactory.openSession();

    //只执行了一条sql语句
    StudentMapper mapper1 = sqlSession1.getMapper(StudentMapper.class);
    Student student1 = mapper1.queryStudentById(2);
    System.out.println(student1);

    Student student2 = mapper1.queryStudentById(2);
    System.out.println(student2);

    sqlSession1.close();
}

运行结果

1.一级缓存:
SqlSession级别的缓存,缓存的数据只在SqlSession内有效。
一级缓存mybatis已近为我们自动开启,不用我们手动操作,而且我们是关闭不了的!!但是我们可以手动清除缓存。
一级缓存是sqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个基于 PerpetualCache的HashMap本地缓存数据结构,用于缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互不影响的。

2.二级缓存:
mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的。
二级缓存需要我们手动开启。
二级缓存(全局级别) 是mapper级别的缓存,多个sqlSession去操作同一个Mapper的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨sqlSession的。

什么时候一级缓存失效?
第一次DQL和第二次DQL之间你做了以下两件事中的任意一件,都会让一级缓存清空:
1.执行了sqlSession的clearCache()方法,这是手动清空缓存。
2.执行了INSERT或DELETE或UPDATE语句。不管你是操作哪张表的,都会清空一级缓存。

Mybatis二级缓存
二级缓存的范围是SqlSessionFactory。

使用二级缓存需要具备以下几个条件:

<setting name="cacheEnabled" value="true"> 这个配置表示启用 MyBatis 的二级缓存功能。默认就是true,⽆需在配置文件设置。

在需要使⽤⼆级缓存的StudentMapper.xml⽂件中添加配置:<cache/>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace:Mapper接口的全路径,使其和Mapper对应-->
<mapper namespace="com.yjg.mapper.StudentMapper">

    <!--    默认情况下,二级缓存机制是开启的。-->
    <!--    只需要在对应的StudentMapper.xml文件中添加以下标签。用来表示”我"使用该二级缓存。-->
    <cache/>
    
    <delete id="delete">
        DELETE from student where stu_id=${id}
    </delete>
    <select id="queryStudentById" parameterType="integer" resultType="Student">
          select * from student where stu_id=${id}
    </select>
</mapper>

使⽤⼆级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接⼝

二级缓存使用成功,只存在一条select语句,并且缓存第二个命中率不为0

  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值