Mybatis-Springboot

打印日志

  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

分页

导入分页插件依赖

        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelper-spring-boot-starterartifactId>
            <version>1.4.6version>
        dependency>

配置yml文件

pagehelper:
  # 设置方言,此处指定 MySQL 数据库
  helper-dialect: mysql
  # 是否启动合理化,默认是 false。
  # 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages(最大页数)会查询最后一页。
  # 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据
  reasonable: true
  # 是否支持接口参数来传递分页参数,默认false
  support-methods-arguments: true
  # 为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值
  params: count=countSql
  # 默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)
  page-size-zero: true

测试

PageHelper.startPage(2,6);
List<User> all = testMapper.findAll();
PageInfo<User> userPageInfo = new PageInfo<>(all);
List<User> list = userPageInfo.getList();
System.out.println(userPageInfo.getPages());
System.out.println(userPageInfo.getTotal());

使用${}实现模糊查询

    
    <select id="like2" resultType="com.bjsxt.pojo.People">
        select * from people where name like '%${name}%'
    select>

resultMap

当数据库列名和属性名不同时是无法进行自动映射的,这时需要手动指定映射关系。

<resultMap id="myid" type="People2">
        
        
        
        <id property="peoId" column="peo_id"/>
        
        <result property="peoName" column="peo_name"/>
    resultMap>
    
    <select id="myid" resultMap="myid">
        select * from tb_people
    select>

自动主键回填

MyBatis的映射文件的标签带有自动主键回填功能,只需要设置useGeneratedKeys进行开启自动主键回填功能,同时设置keyProperty的值需要回填到对象的哪个属性。

    <insert id="insert1" useGeneratedKeys="true" keyProperty="对象.属性()">
        insert into people values(default,#{name},#{address})
    insert>
        User user = new User();
        user.setAge(12L);
        user.setUsername("aaa");
        Long insert = demoMapper.insert(user);

        System.out.println(user.getAge());
        System.out.println(insert);

动态SQL

1.if标签
name!=null : OGNL 表达式,直接写属性名可以获取到属性值。不需要添加${}或#{}

    <select id="selectIf" resultType="People">
        select * from people where 1=1
        <if test="name!=null">
            and name=#{name}
        if>
        <if test="address!=null">
            and address=#{address}
        if>
    select>

2.choose
choose标签相当于Java中的switch…case…default。在choose标签里面可以有多个when标签和一个otherwise(可以省略)标签。只要里面有一个when成立了后面的when和otherwise就不执行了。

    <select id="selectIf" resultType="People">
        select * from people where 1=1
        <choose>
            <when test="name!=null">
                and name=#{name}
            when>
            <when test="address!=null">
                and address=#{address}
            when>
            <otherwise>
                // do something
            otherwise>
        choose>
    select>

3.trim标签
上面的if标签中为了保证语法的正确性,需要在SQL中明确指定where 1=1,其中1=1存在的意义单纯为了保证语法的正确性,没有实际意义的。可以通过trim标签动态进行截取添加,省略where 1=1。

trim标签包含四个属性:
​ prefix:只要内容不是空字符串(“”),就在子内容前面添加特定字符串
​ prefixOverrides:如果里面内容是以某个内容开头,去掉这个内容。
​ suffix:只要内容不是空字符串(“”),就在子内容后面添加特定字符串。
​ suffixOverrides:如果里面内容以某个内容结尾,就去掉这个内容。

​ trim作为很多其他标签的底层。
​ 无论是开头操作还是结尾的操作,都是先去掉容,后添加。
​ trim只会对里面的子内容进行操作。如果子内容为空则不进行任何操作。
​ 后添加的内容会有空格。

	<select id="selectIf" resultType="People">
        select * from people
        <trim prefix="where" prefixOverrides="and">
            <if test="name!=null">
                and name=#{name}
            if>
            <if test="address!=null">
                and address=#{address}
            if>
        trim>
    select>

4.where标签
where标签属于trim标签的简化版,被where标签包含的内容具备:
​ 如果里面内容不为空串,在里面内容最前面添加where
如果里面内容是以and开头,去掉最前面的and

    <select id="selectIf" resultType="People">
        select * from people
        <where>
            <if test="name!=null">
                and name=#{name}
            if>
            <if test="address!=null">
                and address=#{address}
            if>
        where>
    select>

5.set标签
set标签是专门用在修改SQL中的,属于trim的简化版,带有下面功能:

  • 如果子内容不为空串,在最前面添加set
  • 去掉最后一个逗号
    set标签里面id=#{id}是非常重要的,不能不写。因为set在解析时,如果里面为空串,是不会在前面添加set的,对于SQL的修改来说,没有set关键字是不正确的语法。
    <update id="update">
        update people
        <set>
            <if test="name!=null">
                name=#{name},
            if>
            <if test="address!=null">
                address=#{address},
            if>
            id=#{id}
        set>
        where id = #{id}
    update>

6.foreach标签
foreach标签表示循环,主要用在in查询或批量新增的情况。
foreache标签的属性解释说明
collection:要遍历的数组或集合对象。如果参数没有使用@Param注解:arg0或array(数组)|list(集合).如果使用@Param注解,使用注解的名称或param1
​ open:遍历结束在前面添加的字符串
​ close:遍历结束在后面添加的字符串
​ item:迭代变量。在foreach标签里面#{迭代变量}获取到循环过程中迭代变量的值。
​ separator:分隔符。在每次循环中间添加的分割字符串。
index:迭代的索引。从0开始的数字。

由于collection属性值的重要提醒:
​ 如果方法参数前面没有添加@Param注解,只能通过array或arg0获取到数组。
​ 如果方法参数前面添加了@Param注解,只能通过注解值或param1获取到数组。

    <select id="selectByIds" resultType="People">
        select * from people where id in
        <foreach collection="array" open="(" close=")" item="id" separator=",">
            #{id}
        foreach>
    select>

7.bind标签
bind标签表示对传递进来的参数重新赋值。最多的使用场景为模糊查询。通过bind可以不用在Java代码中对属性添加%

    <select id="selectLike" resultType="People">
        <bind name="name" value="'%'+name+'%'"/>
        select * from people where name like #{name}
    select>

8.sql和include标签

在企业开发中的表可能都会有很多列,当使用多表联合查询时列的个数更多。很多功能或SQL都需要使用这些列的话,其实在做很多重复工作。及时复制粘贴,一旦碰到表结构改变或添加、删除列的时候也需要修改很多SQL。

MyBatis的sql标签用于定义SQL片段,include标签用于引用sql标签定义的片段。

    <select id="selectSQL" resultType="People">
        select <include refid="mysqlpart">include> from people
    select>
    <sql id="mysqlpart">
        id,name,address
    sql>

MyBatis中常用注解

@Select 查询
@Insert 新增
@Delete 删除
@Update 修改
@SelectKey 主键回填
@SelectProvider 调用SQL构建器。查询专用
@InsertProvider 调用SQL构建器。添加专用
@UpdateProvider 调用SQL构建器。修改专用
@DeleteProvider 调用SQL构建器。删除专用
@Param 定义参数的名称

联合查询方式

即:解决对象里面含有对象

public class Emp {
    private int id;
    private String name;
    private Dept dept;
    // 没有在文档里面粘贴getter/setter和toString(),太占地方  
}
  
    <resultMap id="un" type="com.example.hellotest.model.User">
        <id property="id" column="id">id>
        <result property="age" column="age">result>
        <result property="username" column="name">result>
        
        
        <association property="student" javaType="com.example.hellotest.model.Student">
        
            <id property="id" column="id">id>
            <result property="password" column="password">result>
        association>
    resultMap>
    <select id="select" resultMap="un">
        select u.id,u.name,u.age,s.password from user u, student s where u.student_id = s.id
    select>

N+1查询方式的(两个查询代替联表查询)

创建两个类,User类中有Student类型的属性,注意是Student,不是List

@Date
public class Student {
    private Long id;
    private String password;
}
@Data
public class User {
    private String username;
    private Long id;
    private Long age;
    private Long studentId;
    private Student student;
}
    <resultMap id="un" type="com.example.hellotest.model.User">
        <id property="id" column="id">id>
        <result property="age" column="age">result>
        <result property="username" column="name">result>
        
        <association property="student" javaType="com.example.hellotest.model.Student"
       				
                     column="student_id">
        association>
    resultMap>
    <select id="select" resultMap="un">
        select u.id,u.name,u.age,s.password from user u, student s where u.student_id = s.id
    select>

如果在User是ListStudent,则用collection,且用ofType

    <resultMap id="user" type="Dept">
        <id column="id" property="id">id>
        <result column="username" property="name">result>
        
        
       	
        <collection 
        property="listStudent"ofType="com.example.hellotest.model.Student"
        select="com.bjsxt.mapper.EmpMapper.selectByEid" 
		column="d_id"/>
    resultMap>
    <select id="select" resultMap="user">
        select * from dept
    select>

ofType的值是集合中存储元素的类
javaType的值是实体类中属性的类型

懒加载

也就是按需加载
在多表查询中(N+1),java代码里面没有用到另一个表中的内容,则不会执行令一条sql语句.
开启方式:
全局:
lazyLoadingEnabled: true 延迟加载的全局开关。当开启所有关联对象都会延迟加载。 默认值false
aggressiveLazyLoading: false (关闭积极加载)false (在 3.4.1 及之前的版本中默认为 true)

局部:
局部配置方式需要在collection或association标签中配置fetchType属性。fetchType可取值:lazy(延迟加载)和earge(立即加载)。
当配置了fetchType属性后,全局settings的配置被覆盖,对于当前标签以fetchType属性值为准。

    <resultMap id="empMap2" type="Emp">
        <id column="e_id" property="id"/>
        <result column="e_name" property="name"/>
        <association property="dept" javaType="Dept"
                     select="com.bjsxt.mapper.DeptMapper.selectById" column="e_d_id"
        fetchType="lazy">association>
    resultMap>
    <select id="selectAllN1" resultMap="empMap2">
        select e_id,e_name,e_d_id from emp
    select>

你可能感兴趣的:(mybatis,spring,boot,java)