Mybatis进阶
MyBatis 接口代理方式实现 Dao 层
接口代理方式-实现规则
传统方式实现 Dao 层,我们既要写接口,还要写实现类。而 MyBatis 框架可以帮助我们省略编写 Dao 层接
实现类的步骤。程序员只需要编写接口,由 MyBatis 框架根据接口的定义来创建该接口的动态代理对象。
实现规则
- 映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。
- 映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。
- 映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。
- 映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同
- 自己写的接口StudentDao.java
public interface StudentDao {
List<Student> findAll();
}
- 在映射配置文件中的映射StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:命名空间,指定接口的完全限定名字-->
<mapper namespace="dao.StudentDao">
<select id="findAll" resultType="student">
select * from student
</select>
<!--
id:表示接口中方法名
resultType:表示方法返回的数据类型,如果返回的是集合,这里指定集合中每个元素类型
select标签标签体就是SQL语句
-->
</mapper>
接口代理方式-源码分析
- 分析动态代理对象如何生成的?
通过动态代理开发模式,我们只编写一个接口,不写实现类,我们通过 getMapper() 方法最终获取到
org.apache.ibatis.binding.MapperProxy 代理对象,然后执行功能,而这个代理对象正是 MyBatis 使用了
JDK 的动态代理技术,帮助我们生成了代理实现类对象。从而可以进行相关持久化操作。 - 分析方法是如何执行的?
动态代理实现类对象在执行方法的时候最终调用了 mapperMethod.execute() 方法,这个方法中通过
switch 语句根据操作类型来判断是新增、修改、删除、查询操作,最后一步回到了 MyBatis 最原生的
SqlSession 方式来执行增删改查。
MyBatis 映射配置文件 – 动态 SQL
简单介绍:实现动态SQL之前我们先来看看要使用到的标签。
- if标签的介绍
- foreach标签的介绍
- SQL片段抽取用到的两个标签:sql标签和include标签
- 下面是在配置文件中的实际配置
<!--where标签就相当于sql语句中的where关键字,只不过MyBatis将它强化了,可以帮我们去掉sql语句中多余的and-->
<select id="findByCondition" resultType="student" parameterType="student">
select * from student
<where>
<if test="id!=null">
id = #{id}
</if>
<if test="name!=null">
and name=#{name}
</if>
<if test="age!=null">
and age=#{age}
</if>
</where>
</select>
<select id="findInCondition" resultType="student" parameterType="list">
select * from student
<where>
id in
<foreach collection="list" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
MyBatis 多表操作
在实际开发中,随着业务难度的加深,肯定需要多表操作的。
多表模型分类
- 一对一:在任意一方建立外键,关联对方的主键。
先定义一个接口:
public interface OneToOneMapper {
List<Card> findCard();
}
在配置文件中配置接口相关的信息:
<mapper namespace="onetoone.OneToOneMapper">
<resultMap id="cardAndPerson" type="card" autoMapping="true">
<id column="cid" property="id"/>
<!--<result column="number" property="number"/>-->
<association property="p" javaType="person" autoMapping="true">
<id column="pid" property="id"/>
<!--<result column="name" property="name"/>-->
<!--<result column="age" property="age"/>-->
</association>
</resultMap>
<select id="findCard" resultMap="cardAndPerson">
select c.id cid,c.number,p.id pid,p.name,p.age from card c,person p where c.id=p.id;
</select>
</mapper>
- 一对多:在多的一方建立外键,关联一的一方的主键。
先定义一个借口:
public interface OneToManyMapper {
List<Classes> findClasses();
}
在配置文件中配置接口相关的信息:
<mapper namespace="ontomany.OneToManyMapper">
<resultMap id="classesToStudent" type="classes" autoMapping="true">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
<collection property="students" ofType="student" autoMapping="true">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="sage" property="age"/>
</collection>
</resultMap>
<select id="findClasses" resultMap="classesToStudent">
select c.id cid,c.name cname,s.id sid,s.name sname,s.age sage
from classes c,student s
where c.id=s.cid;
</select>
</mapper>
- 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。
先定义一个接口:
public interface ManyToMany {
List<Course> findCourse();
List<Student> findStudent();
}
在配置文件中配置与接口相关的信息:
<mapper namespace="manytomany.ManyToMany">
<!--多对多查找课程所在的学生-->
<resultMap id="CourseToStudent" type="course">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
<collection property="students" ofType="student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="sage" property="age"/>
</collection>
</resultMap>
<select id="findCourse" resultMap="CourseToStudent">
SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname
FROM student s,course c,stu_cr sc
WHERE sc.sid=s.id AND sc.cid=c.id;
</select>
<!--多对多查找学生选择的课程-->
<resultMap id="StudentToCourse" type="student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="sage" property="age"/>
<collection property="courses" ofType="course">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</collection>
</resultMap>
<select id="findStudent" resultMap="StudentToCourse">
SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname
FROM student s,course c,stu_cr sc
WHERE sc.sid=s.id AND sc.cid=c.id;
</select>
以上就是本次关于MayBatis的介绍,如果有不恰当的地方,欢迎指正。