Mybatis映射文件 增删改查 简单地增删改查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="selectUser" resultType ="User" > select * from `user` where id = #{id} </select > <insert id ="addUser" > insert into `user` (`name`,account) values (#{name},#{account}) </insert > <update id ="updateUser" > update `user` set `name` = #{name}, account = #{account} where id = #{id} </update > <delete id ="deleteUser" > delete from `user` where id = #{id} </delete >
使用factory.openSession()得到的sqlSession默认不会自动提交,需要手动的提交事务
使用factory.openSession(true)得到的sqlSession自动提交
select详细属性 查询语句是Mybatis中用的最多的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <select id ="selectUser" parameterType ="int" resultType ="hashmap" resultMap ="personResultMap" flushCache ="false" useCache ="true" timeout ="10" fetchSize ="256" statementType ="PREPARED" resultSetType ="FORWARD_ONLY" > select * from `user` where id = #{id} </select >
insert/update/delete详细属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <insert id ="insertAuthor" parameterType ="domain.blog.Author" flushCache ="true" statementType ="PREPARED" keyProperty ="" keyColumn ="" useGeneratedKeys ="" timeout ="20" > <update id ="updateAuthor" parameterType ="domain.blog.Author" flushCache ="true" statementType ="PREPARED" timeout ="20" > <delete id ="deleteAuthor" parameterType ="domain.blog.Author" flushCache ="true" statementType ="PREPARED" timeout ="20" >
插入扩展 获取自增id 默认情况下,插入数据后无法获取自增属性的主键id
1 2 3 4 5 6 7 8 <insert id ="addUserReturnGeneratedKey" useGeneratedKeys ="true" keyProperty ="id" > insert into `user` (`name`,account) values (#{name},#{account}) </insert >
不支持自增主键的方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <insert id ="addUserReturnGeneratedKey" databaseId ="oracle" > <selectKey keyProperty ="id" order ="BEFORE" resultType ="Integer" > select user_seq.nextval from dual </selectKey > insert into `user` (id,`name`,account) values (#{id},#{name},#{account}) </insert >
参数处理 普通的数据类型 1 User selectUserByIdAndName (@Param("id") int id,@Param("name") String name) ;
1 2 3 4 5 6 7 8 9 10 11 12 <select id ="selectUserByIdAndName" resultType ="User" > select * from user where id = #{id} and name = #{name} </select >
自定义的java对象数据类型 对于很多入参的情况,不希望方法的入参那么多,而且需要指定@Param参数,可以将这些入参封装为一个对象.
对于对象,可以直接使用字段来进行获取
1 User selectUserByCondition (User user) ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <select id ="selectUserByCondition" resultType ="User" > select * from user <where > <if test ="id != null and id != 0" > and id = #{id} </if > <if test ="name != null" > and name = #{name} </if > <if test ="account != null and account != 0" > and account = #{account} </if > </where > </select >
集合属性 对于List,mybatis会映射为list,可以通过list来获取集合中的值
1 List<User> selectByIds (List<Integer> ids) ;
1 2 3 4 5 6 7 8 9 <select id ="selectByIds" resultType ="User" > select * from user <where > id in <foreach collection ="list" index ="index" item ="item" open ="(" separator ="," close =")" > #{item} </foreach > </where > </select >
结果映射 resultMap和resultType都是作为结果集返回映射
ResultType 使用map 很多情况下使用map作为返回是可以支持的,但是map不是一个很好的领域模型,在获取到数据库结果之后,还需要再去人工的从map中取值给业务需要的字段去赋值,是一件痛苦而繁琐的事情
1 2 3 <select id ="selectUser" resultType ="map" > select * from user where id = #{id} </select >
使用PO 使用PO进行接收结果集时,考虑到数据库中的列名可能与po中的字段名不一致,需要为每个字段起别名,sql写起来就变长了很多
1 2 3 4 <select id ="selectUser" resultType ="User" > select user_id as id,user_name as userName, from user where id = #{id} </select >
ResultMap 由于在使用ResultType时有一些的问题,而且ResultType对于一些复杂的查询结果来说处理起来也并不友好,ResultMap自定义映射的好处就凸显出来了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <resultMap id ="user" type ="com.zhanghe.study.mybatis.model.User" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="account" property ="account" /> </resultMap > <select id ="selectUserReturnResultMap" resultMap ="user" > select * from `user` where id = #{id} </select >
resultMap是支持继承的
1 2 3 4 5 6 7 8 9 <resultMap id ="base" type ="com.zhanghe.study.mybatis.model.User" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> </resultMap > <resultMap id ="user01" type ="com.zhanghe.study.mybatis.model.User" extends ="base" > <result column ="account" property ="account" /> </resultMap >
关联查询一对一 association代表一对一关系
1 2 3 4 5 6 7 8 9 10 11 public class Employee { private Integer id; private String name; private double salary; private Department department; } public class Department { private Integer id; private String name; }
级联属性封装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <resultMap id ="emp1" type ="com.zhanghe.study.mybatis.model.Employee" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="salary" property ="salary" /> <result column ="did" property ="department.id" /> <result column ="dname" property ="department.name" /> </resultMap > <select id ="getEmpAndDep" resultMap ="emp1" > select emp.id id,emp.name name,emp.salary salary,emp.dep_id did,dep.name dname from employee emp join department dep on emp.dep_id = dep.id where emp.id = #{id} </select >
使用association进行join查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <resultMap id ="emp2" type ="com.zhanghe.study.mybatis.model.Employee" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="salary" property ="salary" /> <association property ="department" javaType ="com.zhanghe.study.mybatis.model.Department" > <id column ="did" property ="id" /> <result column ="dname" property ="name" /> </association > </resultMap > <select id ="getEmpAndDep" resultMap ="emp2" > select emp.id id,emp.name name,emp.salary salary,emp.dep_id did,dep.name dname from employee emp join department dep on emp.dep_id = dep.id where emp.id = #{id} </select >
使用association进行分步查询 使用分步查询会执行多条sql语句,先查询出主表,之后将关联列作为条件去通过select来查询子表信息
EmployeeMapper的映射文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <resultMap id ="emp3" type ="com.zhanghe.study.mybatis.model.Employee" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="salary" property ="salary" /> <association property ="department" column ="dep_id" select ="com.zhanghe.study.mybatis.mapper.DepartmentMapper.selectDepById" > <id column ="did" property ="id" /> <result column ="dname" property ="name" /> </association > </resultMap > <select id ="getEmpAndDep" resultMap ="emp3" > select * from employee where id = #{id} </select >
DepartmentMapper的映射文件
1 2 3 4 5 6 7 8 <resultMap id ="dep" type ="com.zhanghe.study.mybatis.model.Department" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> </resultMap > <select id ="selectDepById" resultMap ="dep" > select * from department where id = #{id} </select >
分步查询延迟加载
在使用子表信息的时候在进行查询
在全局配置中开启延迟加载
1 2 3 4 5 6 7 <settings > <setting name ="logImpl" value ="STDOUT_LOGGING" /> <setting name ="lazyLoadingEnabled" value ="true" /> <setting name ="aggressiveLazyLoading" value ="false" /> </settings >
关联查询一对多 使用collection标签代表一对多关系
DepartmentMapper的映射文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <resultMap id ="dep1" type ="com.zhanghe.study.mybatis.model.Department" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <collection property ="employeeList" select ="com.zhanghe.study.mybatis.mapper.EmployeeMapper.getEmployeeByDid" column ="id" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="salary" property ="salary" /> <result column ="did" property ="department.id" /> </collection > </resultMap > <select id ="getDepAndEmps" resultMap ="dep1" > select * from department where id = #{id} </select >
EmployeeMapper的映射文件
1 2 3 4 5 6 7 8 9 <resultMap id ="emp" type ="com.zhanghe.study.mybatis.model.Employee" > <id column ="id" property ="id" /> <result column ="name" property ="name" /> <result column ="salary" property ="salary" /> </resultMap > <select id ="getEmployeeByDid" resultMap ="emp" > select * from employee where dep_id = #{did} </select >
鉴别器 discriminator鉴别器可以根据某个字段的不同值来进行不同的操作,就像是java中的switch和sql中的case
1 2 3 4 5 6 7 8 9 10 11 12 13 <resultMap id ="baseResultMap" type ="Vehicle" > <id property ="id" column ="id" /> <result property ="name" column ="name" /> <result property ="color" column ="color" /> <discriminator javaType ="int" column ="type" > <case value ="1" resultType ="Car" > <result property ="doorCount" column ="door_count" /> </case > <case value ="2" resultMap ="vanResult" > <result property ="powerSlidingDoor" column ="power_sliding_door" /> </case > </discriminator > </resultMap >
${}和#{}之间的区别
${}:简单字符串替换,把${}直接替换成变量的值,不做任何转换,这种是取值以后再去编译SQL语句
#{}:预编译处理,sql中的#{}替换成?,补全预编译语句,调用PreparedStatement的set方法来赋值,有效的防止Sql语句注入,这种取值是编译好SQL语句再取值
sql块 可重用的sql块,可以被其他语句引用
1 2 3 4 5 6 7 <sql id ="userColumns" > id,username,password</sql > <select id ="selectUsers" parameterType ="int" resultMap ="baseResultMap" > select <include refid ="userColumns" /> from users where id = #{id} </select >
缓存 默认情况下是没有开启二级缓存的,如果要开启二级缓存,则需要使用<cache/>
cache 配置给定命名空间的缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <cache eviction ="FIFO" flushInterval ="60000" readOnly ="true" size ="1024" />
cache-ref 从其他命名空间引用缓存配置
1 <cache-ref namespace ="com.someone.application.data.SomeMapper" >