mybatis的SQL映射(加强)
1.SQL映射器Mapper
a) 引入MyBatis基于动态代理机制,让我们无需再编写Dao的实现。
传统Dao接口,现在名称统一以Mapper结尾,还有我们映射器配置文件要和映射器在同一个包。
b) 映射器使用步骤
i. 根据数据库表创建domain类(User.java)
ii.
根据domain类创建Mapper接口(UserMapper.java)
增删改查和一些其他的方法
可以在Mapper的方法上面通过注解来写SQL,但是不建议使用
iii.
编写配置xml映射文件(UserMapper.xml)
SQL语句标签的id必须和接口中方法的名字一致
iv. 获取session—>session获取Mapper--> mapper调用方法
- 高级查询功能
a) 模糊查询拼接字符串的时候用concat来拼接 like concat(“%”,#{name},“%”)
b) >=可以正常使用,而<=不能,需要对” <”进行一个转译”<”,但是开发时可能很多的<符号,就是CDATA断来表示<![CDATA[条件]]>
<![CDATA[
age <= #{maxAge}
]]>
c) 多条件查询的时候,在xml映射文件里面使用一个<where>标签后会将后面的第一个and自动转换成where
d)
条件的抽取
<sql id=”sqlWhere”>查询条件</sql>,然后在SQL语句里引入这个条件<include refid=” sqlWhere”>
- 嵌套结果映射(resultMap手动映射):多对一和一对一实现
a)
为什么使用结果映射:解决表字段名和对象属性名不一样的情况.关联对象查询,在mybatis不会默认查询出来,需要自己查询结果并且通过resultMap来配置,
property属性名,column列名
b) 关联映射的分类:
多对一,一对一是一样的,都只是处理一个对象(association )。而一对多、多对多也是一样处理的都是集合(collection)
Association:对象映射,自动映射就失效
c) 关联映射的处理方式
i. 嵌套结果:发送一条SQL查询所有信息
- 查询所有关联对象的值
- 进行一个结果的映射,通过ResultMap映射结果
- 在ResultMap映射里面使用了association自动映射就失效了,就需要手动映射<association property=”” column=”” javaType=”关联对象的完全限定名”>
再映射关联对象的属性
<id property = “id” column=”did”>
<property property = “name” column=”dname”>
</association >
<!--嵌套结果--> <resultMap id="resultmap" type="cn.itsource.mapper02.domain.Product"> <id property="id" column="id"/> <result property="name" column="name"/> <association property="dir" column="dir_id" javaType="cn.itsource.mapper02.domain.ProductDir"> <id property="id" column="id"/> <result property="name" column="name"/> </association> </resultMap> <select id="findAll" resultMap="resultmap"> select p.id,p.name,d.id did,d.name dname from t_product p left join t_productdir d on d.id = p.dir_id </select>
ii. 嵌套查询映射:发送1+N条SQL
- 先写一个select查询数据,用resultMap映射
<select id="queryAll" resultMap="queryAllMap">
select * from t_product
</select> - 在<resultmap里的映射里面引用另一个查询语句>
<resultMap id="queryAllMap"type="cn.itsource.mapper02.domain.Product">
<id property="id" column="id"/>
<result property="name" column="name"/>
<association property="dir" column="dir_id" select="queryProductDirByiId"
javaType="cn.itsource.mapper02.domain.ProductDir">
</association>
</resultMap> - 再根据查询结果的外键写一个查询查到另一个的对象的值<select id="queryProductDirByiId"parameterType="long"
resultType="cn.itsource.mapper02.domain.ProductDir">
select * from t_productdir where id = #{id}
</select>
- 嵌套结果映射和嵌套查询映射(resultMap手动映射):一对多,多对多实现
嵌套结果
a)在一方定义多方,
package cn.itsource.mapper03onetomany.domain; import java.util.ArrayList; import java.util.List; public class Dept { private Long id; private String name; private List<User> users = new ArrayList<>(); } } <!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 这个Mapper的主要功能就是写sql mapper:根 namespace:命令空间 (用来确定唯一) 以前这个是可以不加的,现在必需加 namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper --> <mapper namespace="cn.itsource.mapper03onetomany.mapper.DeptMapper"> <!--嵌套结果映射--> <resultMap id="deptMap" type="cn.itsource.mapper03onetomany.domain.Dept"> <id property="id" column="id"/> <result property="name" column="name"/> <collection property="users" javaType="arraylist" ofType="cn.itsource.mapper03onetomany.domain.User"> <id property="id" column="uid"/> <result property="username" column="uusername"/> <result property="password" column="upassword"/> </collection> </resultMap> <select id="findAll" resultMap="deptMap"> select d.id,d.name,u.id uid,u.username uusername,u.password upassword from dept d left join user u on u.dept_id = d.id </select>
b) 嵌套查询
<!--嵌套查询映射-->
<resultMap id="deptQueryMap"
type="cn.itsource.mapper03onetomany.domain.Dept">
<id property="id"
column="id"/>
<result property="name"
column="name"/>
<collection property="users"
column="id"ofType="cn.itsource.mapper03onetomany.domain.User"
select="findByDeptId">
</collection>
</resultMap>
<select id="findByDeptId"
parameterType="long" resultType="cn.itsource.mapper03onetomany.domain.User">
select * from user where dept_id = #{id}
</select>
<select id="queryAll"
resultMap="deptQueryMap">
select * from dept
</select>
</mapper>
结论:在一对多的时候,如果想要分页,就在一方的SQL语句后面加一个limit(0,10),就必须使用嵌套查询的方式来映射。如果是用嵌套结果的话就是完成不了分页的
- 延迟加载、
- Mybatis的缓存
a) Mybatis的一级缓存:在SqlSession里面
b) Mybatis默认是没有二级缓存:在SqlSessionFactory中不存在,要使其在mybatis中启用二级缓存,在映射文件里面加一个标签” <cache/>”就行了。