MyBatis接口代理方式实现Dao层
-
接口代理方式-实现规则
- 传统方式实现 Dao 层,我们既要写接口,还要写实现类。而 MyBatis 框架可以帮助我们省略编写 Dao 层接口实现类的步骤。我们只需要编写接口,由 MyBatis 框架根据接口的定义来创建该接口的动态代理对象。
- 实现规则
- 映射配置文件中的名称空间必须和 Dao 层接口的全类名相同。
- 映射配置文件中的增删改查标签的 id 属性必须和 Dao 层接口的方法名相同。
- 映射配置文件中的增删改查标签的 parameterType 属性必须和 Dao 层接口方法的参数相同。
- 映射配置文件中的增删改查标签的 resultType 属性必须和 Dao 层接口方法的返回值相同。
- 接口代理方式-代码实现
- 删除 mapper 层接口的实现类。
- 修改映射配置文件
- 修改 service 层接口的实现类,采用接口代理方式实现功能。
-
核心配置文件(MyBatisConfig.xml)
<?xml version="1.0" encoding="UTF-8" ?> <!--MyBatis的DTD约束--> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--configuration 核心根标签--> <configuration> <!--引入数据库连接的配置文件--> <properties resource="jdbc.properties"/> <!--配置LOG4J--> <settings> <setting name="logImpl" value="log4j"/> </settings> <!--起别名--> <typeAliases> <typeAlias type="com.xxxxxxx.bean.Student" alias="student"/> <!--<package name="com.itheima.bean"/>--> </typeAliases> <!--集成分页助手插件--> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins> <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个--> <environments default="mysql"> <!--environment配置数据库环境 id属性唯一标识--> <environment id="mysql"> <!-- transactionManager事务管理。 type属性,采用JDBC默认的事务--> <transactionManager type="JDBC"></transactionManager> <!-- dataSource数据源信息 type属性 连接池--> <dataSource type="POOLED"> <!-- property获取数据库连接的配置信息 --> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> </environments> <!-- mappers引入映射配置文件 --> <mappers> <!-- mapper 引入指定的映射配置文件 resource属性指定映射配置文件的名称 --> <mapper resource="StudentMapper.xml"/> </mappers> </configuration>
-
映射配置文件(StudentMapper.xml)
<?xml version="1.0" encoding="UTF-8" ?> <!--MyBatis的DTD约束--> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- mapper:核心根标签 namespace属性:名称空间 --> <mapper namespace="com.xxxxxxx.mapper.StudentMapper"> <!--sql片段抽取,达到复用性 抽取:<sql id=“片段唯一标识”>抽取的 SQL 语句</sql> 引用:<include refid=“片段唯一标识”/> --> <sql id="select" >SELECT * FROM student</sql> <!-- select:查询功能的标签 id属性:唯一标识 resultType属性:指定结果映射对象类型 parameterType属性:指定参数映射对象类型 --> <select id="selectAll" resultType="student"> <include refid="select"/> </select> <!--省略其他方法,大致是一样的--> </mapper>
-
mapper层(StudentMapper)
package com.xxxxxxx.mapper; /* 持久层接口 */ public interface StudentMapper { //查询全部 public abstract List<Student> selectAll(); //省略其他方法, }
小结
- 接口代理方式可以让我们只编写接口即可,而实现类对象由 MyBatis 生成
- 实现规则(如上 实现规则)
- 获取动态代理对象
- SqlSession 功能类中的 getMapper() 方法
MyBatis 映射配置文件 – 动态 SQL
动态 SQL 介绍
-
MyBatis 映射配置文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL 就是 动态变化的,此时简单的 SQL 就不能满足要求了。
-
多条件查询
-
动态SQL标签
- :条件判断标签
- :循环遍历标签
-
标签
- :条件标签。如果有动态条件,则使用该标签代替 where 关键字。
- :条件判断标签。
*
-
:循环遍历标签
- :循环遍历标签。适用于多个参数或者的关系。
- 属性
- collection:参数容器类型,(list-集合,array-数组)。
- open:开始的 SQL 语句。
- close:结束的 SQL 语句。
- item:参数变量名。
- separator:分隔符。
- :循环遍历标签。适用于多个参数或者的关系。
-
SQL片段抽取
- :条件标签。如果有动态条件,则使用该标签代替 where 关键字。
- :条件判断标签。
*
-
举例
<?xml version="1.0" encoding="UTF-8" ?> <!--MyBatis的DTD约束--> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- mapper:核心根标签 namespace属性:名称空间 --> <mapper namespace="com.xxxxxxx.mapper.StudentMapper"> <!--SQL片段抽取--> <sql id="select" >SELECT * FROM student</sql> <!-- select:查询功能的标签 id属性:唯一标识 resultType属性:指定结果映射对象类型 parameterType属性:指定参数映射对象类型 --> <select id="selectCondition" resultType="student" parameterType="student"> <include refid="select"/> <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="selectByIds" resultType="student" parameterType="list"> <!--使用sql片段抽取--> <include refid="select"/> <where> <foreach collection="list" open="id IN (" close=")" item="id" separator=","> #{id} </foreach> </where> </select> </mapper>
MyBatis 核心配置文件 – 分页插件
-
分页插件介绍
- 在企业级开发中,分页也是一种常见的技术。而目前使用的 MyBatis 是不带分页功能的,如果想实现分页的功能,需要我们手动编写 LIMIT 语句。但是不同的数据库实现分页的 SQL 语句也是不同的。这个时候就可以借助分页插件来帮助我们实现分页功能。
- PageHelper:第三方分页助手。将复杂的分页操作进行封装,从而让分页功能变得非常简单。
-
分页插件实现步骤
-
导入jar包
-
在核心配置文件中集成分页助手插件
<!--集成分页助手插件--> <!--注意核心配置文件的编写是有结构的--> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
-
-
分页插件相关
- 分页:可以将很多条结果进行分页显示。
- 分页插件 jar 包:pagehelper-5.1.10.jar jsqlparser-3.1.jar
- :集成插件标签。
- 分页助手相关 API
- PageHelper:分页助手功能类。
- startPage():设置分页参数
- PageInfo:分页相关参数功能类。
- getTotal():获取总条数
- getPages():获取总页数
- getPageNum():获取当前页
- getPageSize():获取每页显示条数
- getPrePage():获取上一页
- getNextPage():获取下一页
- isIsFirstPage():获取是否是第一页
- isIsLastPage():获取是否是最后一页
MyBatis 多表操作
多表模型
-
在实际开发中,随着业务难度的加深,肯定是需要多表操作的
-
多表模型分类
- 一对一:在任意一方建立外键,关联对方的主键。
- 一对多:在多的一方建立外键,关联一的一方的主键。
- 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。
-
一对一
- 一对一模型:例如人和身份证,一个人只有一个身份证。
<!--省略其他信息--> <mapper namespace="com.xxxxxxx.table01.OneToOneMapper"> <!--配置字段和实体对象属性的映射关系--> <resultMap id="oneToOne" type="card"> <!-- association:配置被包含对象的映射关系 property:被包含对象的变量名 javaType:被包含对象的数据类型 --> <id column="cid" property="id"/> <result column="number" property="number"/> <association property="p" column="person"> <id column="pid" property="id"/> <result column="name" property="name"/> <result column="age" property="age"/> </association> </resultMap> <select id="selectAll" resultMap="oneToOne"> SELECT c.id cid,c.number, p.id pid,p.age,p.`NAME` from card c,person p where c.pid=p.id; </select> </mapper>
- :配置字段和对象属性的映射关系标签。
- id 属性:唯一标识
- type 属性:实体对象类型
- :配置主键映射关系标签。
- :配置非主键映射关系标签。
- column 属性:表中字段名称
- property 属性: 实体对象变量名称
- :配置被包含对象的映射关系标签。
- property 属性:被包含对象的变量名
- javaType 属性:被包含对象的数据类型
-
一对多
- 一对多模型:班级和学生,一个班级可以有多个学生
<!--省略其他信息--> <mapper namespace="com.xxxxxxx.table02.OneToManyMapper"> <resultMap id="oneToMany" type="Classes"> <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="selectAll" resultMap="oneToMany"> 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>
- :配置字段和对象属性的映射关系标签。
- id 属性:唯一标识
- type 属性:实体对象类型
- :配置主键映射关系标签。
- :配置非主键映射关系标签
- column 属性:表中字段名称
- property 属性: 实体对象变量名称
- :配置被包含集合对象的映射关系标签。
- property 属性:被包含集合对象的变量名
- ofType 属性:集合中保存的对象数据类型
-
多对多
- 多对多模型:学生和课程,一个学生可以选择多门课程、一个课程也可以被多个学生所选择。
<!--省略其他信息--> <mapper namespace="com.xxxxxxx.table03.ManyToManyMapper"> <resultMap id="manyToMany" 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="selectAll" resultMap="manyToMany"> 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> </mapper>
-
:配置字段和对象属性的映射关系标签。
- id 属性:唯一标识
- type 属性:实体对象类型
-
:配置主键映射关系标签
-
:配置非主键映射关系标签。
- column 属性:表中字段名
- property 属性: 实体对象变量名称
-
:配置被包含集合对象的映射关系标签。
-
property 属性:被包含集合对象的变量名
-
ofType 属性:集合中保存的对象数据类型
-
sc
WHERE sc.sid=s.id AND sc.cid=c.id
* <resultMap>:配置字段和对象属性的映射关系标签。
* id 属性:唯一标识
* type 属性:实体对象类型
* <id>:配置主键映射关系标签
* <result>:配置非主键映射关系标签。
* column 属性:表中字段名
* property 属性: 实体对象变量名称
* <collection>:配置被包含集合对象的映射关系标签。
* property 属性:被包含集合对象的变量名
* ofType 属性:集合中保存的对象数据类型