mybatis学习笔记
- 配置
- sql语句的输入输出
- 万能的map(多字段时写入参数)
- 结果集映射map
- 写sql语句
- 6.日志
- 9. lombok
- 复杂查询
- 10.多对一
- 查询学生并得到其老师信息
- 11.一对多处理
- 12.动态Sql
- 13.缓存
- 一级缓存
- 二级缓存
- 缓存原理
- 自定义缓存
Mybatis官网
配置
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="db.properties"/>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- <setting name="logImpl" value="LOG4J"/>-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<package name="com.liang.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.liang.dao.UserMapper"/>
</mappers>
</configuration>
db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=123456
sql语句的输入输出
万能的map(多字段时写入参数)
结果集映射map
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<!-- <result property="name" column="name"/>-->
<result property="password" column="pwd"/> 将表中中的pwd列对应上User的password
</resultMap>
<select id="getUserById" resultMap="userResultMap" parameterType="int">
select * from mybatis.user where id = #{id};
</select>
写sql语句
- 使用xml开发
- 使用注解开发
6.日志
logImpl
LOG4J
STDOUT_LOGGING
9. lombok
- 使用lombok实现pojo类的编写
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
复杂查询
10.多对一
查询学生并得到其老师信息
- 方式一
查询学生表,根据查询到的tid查询教师表
<select id="getStudent" resultMap="StudentTeacher"> 先查学生 使用结果集映射到StudentTeacher
select * from mybatis.student
</select>
<resultMap id="StudentTeacher" type="Student" > 其它属性映射不变 teacher属性对应根据表中tid查询教师表得到的值(对应getTeacher的select)
<!--复杂的属性,我们需要单独出来 对象:association 集合:collection-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher"> 查询教师表语句
select * from mybatis.teacher where id=#{tid}
</select>
- 方式二
按照结果嵌套处理
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,s.tid tid,t.name tname from mybatis.student s, mybatis.teacher t where s.tid=t.id
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher"> 定义teacher里的属性
<result property="id" column="tid"/> 映射
<result property="name" column="tname"/>
</association>
</resultMap>
11.一对多处理
- 方式一
按照结果嵌套处理
<select id="getTeacher" resultMap="TeacherStudent">
select t.id tid, t.name tname, s.id sid, s.name sname from mybatis.teacher t,mybatis.student s where t.id=s.tid and t.id=#{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--复杂的属性,我们需要单独处理 对象:association 集合:collection
javaType=""指定属性的类型!
ofType 集合中的泛型
-->
<collection property="students" ofType="student"> # 可加javaType="ArrayList" 或"List"
<result property="id" column="sid"/>
<result property="name" column="sname"/>
</collection>
</resultMap>
- 方式二
按照查询嵌套处理
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id = #{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from mybatis.student where tid = #{tid}
</select>
12.动态Sql
- 使用<if 对map是否含做判断
- 直接放进去 或者也可以使用<sql定义语句片段, <include 包含定义的片段
<sql id="if-title-author"> //片段
<if test="title !=null">
and title=#{title}
</if>
<if test="author !=null">
and author=#{author}
</if>
</sql>
<select id="queryBlogIf" parameterType="map" resultType="Blog">
<!-- select * from mybatis.blog where 1=1-->
<!-- <include refid="if-title-author"/>-->
select * from mybatis.blog
<where>
<include refid="if-title-author"/>
</where>
</select>
- foreach 迭代集合
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from mybatis.blog
<foreach item="id" collection="ids"
open="where " separator=" or " close=""> //定义开始为 where 间隔为 or 结束为空
id=#{id}
</foreach>
</select>
13.缓存
一级缓存
sqlSession级别缓存
缓存消失的几种情况
- 映射语句文件中的所有 select 语句的结果将会被缓存。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
二级缓存
- 开启二级缓存
- 开启全局缓存,默认是开启
mybatis-config.xml
<setting name="cacheEnabled" value="true"/>
- mapper xml中开启
<cache/>
或者
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
- 工作机制
- 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容;
- 不同的mapper查出的数据就会放在自己对应的缓存(map)中
- 问题
使用简单cache,即<cache/>
报错: Caused by: java.io.NotSerializableException: com.liang.pojo.User
原因:未序列化实体类
方案:
类实现Serializable接口public class User implements Serializable
缓存原理
sqlSession关闭后将一级缓存数据保存至二级缓存中
自定义缓存
Ehcache
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version>
</dependency>