MyBatis
建立一个Batis项目需要:
-
配置 maven项目的xml文件,如dependency、build资源导出配置
-
创建工具类,用SqlSessionFactoryBuilder 工厂模式创建 SqlSessionFactory 对象,用于后续执行sql
-
在 resources 文件夹下创建 mybatis-config.xml 配置文件,配置driver、url、username、password,以及建立 mapper 映射,映射到接口实现类的 xml 文件中,mapper中的resource需要使用路径,非点
-
编写实体类
-
编写接口
-
编写实现接口的 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>
<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 resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
增删改 必须要 提交事务,sqlSession.commit();
如果字段或者参数过多,可以考虑使用Map;
Map 传递参数,直接在 sql 中取出 Key 即可!
对象传递参数,直接在 sql 中 取对象的属性即可!
-
属性优化:properties标签放在最上面,首先读取标签体内的属性,然后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性
-
设置标签:第二位,settings 标签的 cacheEnabled、lazyLoadingEnabled、logImpl
-
类型别名优化:typeAliases标签第三位,给实体类起别名,也可以给包起别名,包内的实体类默认首字母小写为类的别名,也可以加注解
-
环境标签: environment 。MyBatis 默认的事务管理器(transactionManager)是JDBC,数据源(dataSource) 默认 POOLED
-
映射器标签:Mappers。resource 问题小,class、package 必须要求接口名和xml文件名一样,且在同一个包下。
ResultMap
若实体类名字 和 数据库列名不一致,有两种方法处理:
<select id="getList" resultType="com.wang.pojo.People">
select * from mybatis.people
</select>
-
给不一致的起别名
<select id="getList" resultType="com.wang.pojo.People">
select id,age,name as pname from mybatis.people
</select>
-
使用ResultMap结果集映射
<resultMap id="PeopleMap" type="com.wang.pojo.People">
<result column="id" property="id"/>
<result column="age" property="age"/>
<result column="name" property="pname"/>
</resultMap>
<select id="getList" resultMap="PeopleMap">
select * from mybatis.people
</select>
注解
使用注解开发,如下:
@Select("select id,age,name as pname from mybatis.people")
public List<People> getList();
// 并在 mybatis-config.xml 里面注册绑定接口
<mappers>
<mapper class="com.wang.Dao.PeopleMapper"/>
</mappers>
带参数,如下:
@Select("select id,age,name as pname from mybatis.people where id = #{Pid}")
public People getPeoplebyId(int Pid);
// 或者
@Select("select id,age,name as pname from mybatis.people where id = #{id}")
public People getPeoplebyId(@Param("id") int Pid);
@ Param() 注解:
-
基本类型的参数或者 String 类型,需要加上@Param,SQL中引用的是Param中设置的属性名
-
引用类型不需要加@Param注解
#{} 和 ${} 区别,#{} 能够防止sql注入,后者不能
安装lombok插件,导入jar包,插入注解,如@Data,可自动生成 get、set、toString、hashcode、equals方法
多对一
子查询
<select id="getStudents" resultMap="TS">
select * from mybatis.student
</select>
<resultMap id="TS" type="com.wang.pojo.Student">
<result property="id" column="id"/>
<association property="teacher" column="tid" javaType="com.wang.pojo.Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="com.wang.pojo.Teacher">
select * from mybatis.teacher where id = #{id}
</select>
联表查询
<select id="getStudents" resultMap="ST">
select s.id sid,s.name sname,t.name tname,t.id tid
from mybatis.student as s,mybatis.teacher as t where s.tid=t.id
</select>
<resultMap id="ST" type="com.wang.pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="com.wang.pojo.Teacher">
<result property="name" column="tname"/>
<result property="id" column="tid"/>
</association>
</resultMap>
对象用 association, 即为多对一;一个集合用 collection,即为一对多
JavaType用来指定实体类中属性的类型,ofType 用来指定映射到 list 或集合中的pojo的类型,泛型中的约束类型
按照结果嵌套处理(联表查询),按照查询嵌套处理(子查询)
一对多
联表查询
<select id="getTeacher" resultMap="TS">
select s.id sid, s.name sname,t.name tname,t.id tid
from mybatis.teacher as t,mybatis.student as s
where s.tid = t.id and t.id = #{teaid}
</select>
<resultMap id="TS" type="com.wang.pojo.Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="com.wang.pojo.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
子查询
<select id="getTeacher" resultMap="TS">
select * from mybatis.teacher where id = #{teaid}
</select>
<resultMap id="TS" type="com.wang.pojo.Teacher">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="students" javaType="ArrayList" ofType="com.wang.pojo.Student" column="id" select="getStu"/>
</resultMap>
<select id="getStu" resultType="com.wang.pojo.Student">
select * from mybatis.student where tid = #{ppid}
</select>
动态SQL
动态SQL就是在拼接SQL语句,按照SQL语句的格式去排列组合。
IF
<select id="queryBlogIF" parameterType="map" resultType="com.wang.pojo.Blog">
select * from mybatis.blog where 1=1
<if test="qtitle != null">
and title = #{qtitle}
</if>
<if test="qauthor != null">
and author = #{qauthor}
</if>
</select>
choose(when,otherwise)
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<choose>
<when test="title != null"> and title = #{title} </when>
<when test="author != null"> and author = #{author} </when>
<otherwise> and views = #{views} </otherwise>
</choose>
</where>
</select>
trim(where,set)
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title != null"> title = #{title}, </if>
<if test="authhor != null"> author = #{author}, </if>
</set>
where id = #{id}
</update>
<trim prefix="WHERE" prefixOverrides="AND | OR"/>
<trim prefix="SET" suffixOverrides=","/>
SQL 片段
<sql id="sql_section">
<if test="title != null"> title = #{title}, </if>
<if test="authhor != null"> author = #{author}, </if>
</sql>
<include refid="sql_section"></include>
foreach
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="item" open="and (" close=")" separator="or">
id = #{item}
</foreach>
</where>
</select>
缓存
读写分离、主从复制
一级缓存(SqlSession 级别的缓存,默认开启)、二级缓存(需手动开启和配置,namespace级别的缓存)
MyBatis 定义了缓存接口Cache,可通过实现Cache接口来自定义二级缓存;
缓存策略:LRU、FIFO、SOFT、WEAK
一级缓存失效:
-
查询不同的东西
-
增删改可能会改变数据,会刷新缓存
-
查询不同的Mapper.xml
-
手动清理缓存 sqlSession.clearCache();
在配置文件中的settings中添加 <setting name="cacheEnabled" value="true"/>开启全局缓存,在mapper.xml中插入<cache/> 开启二级缓存,二级缓存在同一个xml下有效,会话提交或关闭会转到二级缓存
若未设置<cache readOnly="true"/>会报错,需要实体类实现序列化接口Serializable,但实现序列化为深拷贝,反序列化后的对象和原对象不是同一个对象,哈希值不同
查询先看二级缓存有没有,再看一级缓存有没有,都没有就去查询数据库
自定义缓存 : EhCache
导入依赖包,在xml中添加<cache type="com.domain.something.MyCustomCache"/>
浙公网安备 33010602011771号