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 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);
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的简化版,带有下面功能:
<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>
@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>
创建两个类,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>