1.Mybatis工作流程

2.封装方法
SqlSessionFactoryUtils 里面的openSession
3.采用映射方法实现接口查询
UserMapper userMapper =session.getMapper(UserMapper.class); List<User> userList =userMapper.getList();
4.接口配置文件 讲述增删改查(源代码)

(1)模糊查询的方法

(2)Mapper生命周期

5.pojo实体类中的字段和数据库中的字段不一样
(1)换一个别名

(2)、使用返回类型 resultMap
结果集映射
只需要映射需要修改的

6.Mybatis分页查询
(1).通过UserMapper.xml配置来实现
UserMapper.xml配置:
<resultMap id="LimitType" type="User">
<result column="address" property="addes"/>
</resultMap>
<select id="getUserByLimit" parameterType="map" resultMap="LimitType">
select * from user limit #{startIndex},#{pageSize}
</select>
测试类:
@Test
public void getUserByLimit(){
SqlSession sqlSession = SqlSessionFactoryUtil.openSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Map map = new HashMap<String , Integer>();
map.put("startIndex", 0);
map.put("pageSize",2);
List <User> list=userMapper.getUserByLimit(map);
for (User s :list) {
System.out.println(s);
}
sqlSession.close();
}
(2).通过Java代码实现分页 (不建议使用,但是快)
RowBounds rowBoun RowBounds rowBounds= new RowBounds(0,5);
List<User> list = sqlSession.selectList("com.ybzn.dao.UserMapper.getUserByLimit", null,rowBounds);
两行代码即可查询出分页,在UserMapper.xml配置中:仅需如下
<resultMap id="LimitType" type="User">
<result column="address" property="addes"/>
</resultMap>
<select id="getUserByLimit" parameterType="map" resultMap="LimitType">
select * from user
</select>
(3)分页可以使用其他方法
7.按照查询嵌套处理(多对一复杂查询)
(1).通过子查询来完成
StudentMapper.xml配置
思路:
1.查询所有学生信息
2.根据查询出来的学生tid,寻找对应的老师! 类似于子查询
<select id="getStudent" resultMap="StudentTeacher">
select * from new_user;
</select>
<resultMap id="StudentTeacher" type="Student">
<result column="id" property="id"></result>
<result column="stuname" property="stuname"></result>
<result column="id" property="id"></result>
<!-- 复杂的属性 需要单独处理 对象:association 集合:collection -->
<association property="teacher" column="tid"
javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where tid=#{tid}
</select>
(2).按照结果嵌套查询--联表查询
类似于联表查询 多对一
StudentMapper.xml
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.stuname sname,s.stuclass sclass,t.teaname tname from new_user s,teacher t where s.tid=t.tid;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result column="sid" property="id"></result>
<result column="sname" property="stuname"></result>
<result column="sclass" property="stuclass"></result>
<association property="teacher" javaType="Teacher">
<result property="teaname" column="tname"></result>
</association>
//其中association 里面的property对应Pojo中的字段名
//javaType 对应pojo中的字段名类型
//配置中所有property 表示数据库中的字段名,Column表示程序中的别名或者字段名
</resultMap>
POJO下的:Student.java
@Data public class Student {
private int id; private String stuname;
private String stuclass;
private Teacher teacher; }
8.类似于联表查询 一对多
1 <!--按照结果来嵌套查询-->
2 <select id="getTeacher" resultMap="TeacherStudent">
3 select s.id sid, s.stuname sname, s.stuclass sclass, t.teaname tname , t.tid tid
4 from new_user s , teacher t
5 where s.tid = t.tid and t.tid = #{tid};
6 </select>
7 <resultMap id="TeacherStudent" type="Teacher">
8 <result column="tname" property="teaname"></result>
9 <!-- 复杂的属性 需要单独处理 对象:association 集合:collection
10 javaType="" 指定属性的类型
11 集合中的泛型信息 ,我们可以通过ofType获取
12 -->
13 <collection property="student" ofType="Student">
14 <result property="id" column="sid"></result>
15 <result property="stuname" column="sname"></result>
16 <result property="tid" column="tid"></result>
17 <result property="stuclass" column="sclass"></result>
18 </collection>
19 </resultMap>
POJO下的:Teacher.java
@Data
public class Teacher{
private int tid;
private String teaname;
private List<Student> student;
}
联表查询 小结
1. 关联:- association 【多对一】
2. 集合: -collection 【一对多】
3. javaType && ofType
- javaType 用来指定实体类中属性的类
- ofType 用来指定映射到LIst《ofType=""》或者集合中的pojo类型,泛型中的约束类型
9.动态SQL查询
- 利用IF 来完成查询
BlogMapper.xml 配置 通过传递map 的方式来完成查询
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
- 利用Choose来完成查询
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from blog
<where>
<choose>
<when test="title !=null">
title=#{title}
</when>
<when test="author != null">
and author=#{author}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
- 利用Set来完成更新操作
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title !=null">
title = #{title},
</if>
<if test="author !=null ">
author = #{author},
</if>
</set>
where id= #{id}
</update>
- SQL片段
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。
提取SQL片段:
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
引用SQL片段:
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
<include refid="if-title-author"></include>
<!-- 在这里还可以引用其他的 sql 片段 -->
</where>
</select>
注意:
①、最好基于 单表来定义 sql 片段,提高片段的可重用性
②、在 sql 片段中不要包括 where
- 利用Foreach 完成动态SQL的拼接
BlogMapper.xml 配置
<!-- 传递一个万能的map, 这个Map可以存在一个集合-->
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from blog
<where>
<foreach collection="ids" item="flagid"
open="and (" close=")" separator="or">
id=#{flagid}
</foreach>
</where>
</select>
测试 如下
@Test
public void sqlSelect(){
SqlSession session = SqlSessionFactoryUtil.openSqlSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap map = new HashMap();
ArrayList <String> ids = new ArrayList <>();
ids.add("1");
ids.add("2");
ids.add("3");
ids.add("4");
map.put("ids", ids);
List <Blog> blogs = mapper.queryBlogForeach(map);
for (Blog blog : blogs) {
System.out.println(blog);
}
}
10.二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
- 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
- 工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容;
- 不同的mapper查出的数据会放在自己对应的缓存(map)中;
使用步骤
- 开启全局缓存 【mybatis-config.xml】
<setting name="cacheEnabled" value="true"/>
2.去每个mapper.xml中配置使用二级缓存,这个配置非常简单;【xxxMapper.xml】
<cache/> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,
注意:采用了二级缓存会出现序列化的问题
应该令POJO中的实体类 实现Serializable 接口
public class Blog implements Serializable {}
缓存工作流程图

结论
- 只要开启了二级缓存,我们在同一个Mapper中的查询,可以在二级缓存中拿到数据
- 查出的数据都会被默认先放在一级缓存中
- 只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中
来源:https://www.cnblogs.com/blogger-Li/p/12298299.html