【Mybatis】笔记
【Mybatis】笔记(一)
六、日志
6.1、日志工厂
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
6.2、Log4j
- Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件
- 控制每一条日志的输出格式;
- 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
- 通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
导包
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
log4j.properties
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/log4j.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
mybatis-config.xml
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
七、分页
减少数据的处理量
7.1、limit 分页
接口
List<User> getUserByLimit(Map<String,Integer> map);
mapper
<select id="getUserByLimit" parameterType="map" resultType="user">
select * from mybatis.user limit #{startIndex},#{pagesize}
</select>
测试
public void getUserByLimit(){
SqlSession sqlsession = mybatisutils.getSqlSession();
//执行sql
UserDao userDao=sqlsession.getMapper(UserDao.class);
Map<String,Integer> map=new HashMap<>();
map.put("startIndex",0);
map.put("pagesize",2);
List<User> userList=userDao.getUserByLimit(map);
for (User user : userList) {
System.out.println(user.getName());
}
sqlsession.close();
}
八、注解开发
注解在接口上实现
@Select("select * from user")
List<User> userList();
需要再核心配置文件中绑定接口
<mappers>
<mapper class="com.demo02.dao.UserDao"></mapper>
</mappers>
本质 : 反射机制实现
底层 : 动态代理
九、Lombok
使用
1、在IDEA中安装Lombok插件
2、导包
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
3、注解
@Data:无参构造,get、set、tostring.hashcode,equals
@AllArgsConstructor:有参构造
十、复杂环境搭建
10.1、多对一处理
10.1.1、按照子查询处理
<mapper namespace="com.demo02.dao.StudentMapper">
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name" />
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id}
</select>
</mapper>
10.1.2、按照结果处理
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from student s,teacher t
where s.tid = t.id;
</select>
10.2、一对多处理
javaType="”指定属性的类型!
集合中的泛型信息,我们使用ofType获取
10.2.1、按照结果处理
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name tname,t.id tid
from student s,teacher t
where s.tid = t.id and t.id=${tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid" />
<result property="name" column="tname" />
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
</collection>
</resultMap>
10.2.2、按照查询处理
<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>
10.3、总结
- 关联- association【多对一】
- 集合- collection【一对多】
- javaType & ofType
JavaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!
十一、动态SQL
动态SQL就是指根据不同的条件生成不同的SQL语句
where 标签是防止条件刷选后出现 where and id=xxx的现象
11.1、if 语句
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<if test="title l= nu1i">
and title = #{title}</if>
<if test="author != nul1">
and author = #{author}
</if>
</where>
</select>
11.2、choose
有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis提供了choose元素,它有点像Java 中的 switch语句。
<select id="findActiveBlogLike"resultType="B1og">
SELECT * FROM BLOG WHERE state = 'ACTIVE'
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
11.3、foreach
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT*
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator=", " close=") ">
#{item}
</foreach>
</select>
11.4、sql片段
有的时候,我们可能会将一些功能的部分抽取出来,方便复用!
- 使用SQL标签抽取公共的部分
- 在需要使用的地方使用Include标签引用即可
12、缓存
12.1、缓存[ Cache ]?
。存在内存中的临时数据。
。将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
12.2、mybatis缓存
- 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
- 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
12.2.1、一级缓存
-
映射语句文件中的所有select语句的结果将会被缓存。
-
映射语句文件中的所有insert、update和delete语句会刷新缓存。
-
缓存会使用最近最少使用算法 (LRU, Least Recently Used)算法来清除不需要的缓存。。缓存不会- 定时进行刷新(也就是说,没有刷新间隔)。
-
缓存会保存列表或对象(无论查询方法返回哪种)的1024个引用。
-
缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
缓存失效的情况:
1.查询不同的东西
2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
3.查询不同的Mapper.xml
4.手动清理缓存!
sqlsession.clearCache();//手动清理级们
一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间段!
12.2.2、二级缓存
开启全局只需添加如下代码到Mapper里
<cache/>
也可以更改cache属性
<cache
eviction="FIFO"
flushInterval="688ee"
size="512"
readonly="true" />
虽然默认开起了cacheEnabled但最好还是写出来
<settings>
<setting name="cacheEnabled" value="true" />
</settings>
12.3、自定义缓存-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>
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="./tmpdir/Tmp_EhCache"/>
<defaultCache
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="cloud_user"
eternal="false"
maxElementsInMemory="5000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>