上篇提到mybatis的基本架构,那么到底如何去用mybatis开发Dao呢?
使用 Mybatis 开发 Dao,通常有两个方法,即原始 Dao 开发方法和Mapper 接口开发方法。原始的方法在这里我们就不再赘述,下面主要是谈谈Mapper 接口开发方法。
原始 Dao 开发中存在以下问题:
Dao 方法体存在重复代码:通过 SqlSessionFactory 创建 SqlSession,调用SqlSession 的数据库操作方法
调用 sqlSession 的数据库操作方法需要指定 statement 的 id,这里存在硬编码,不得于开发维护。
mapper的动态代理就可以解决这些问题。
Mapper 接口开发方法只需要程序员编写 Mapper 接口(相当于 Dao 接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao 接口实现类方法。Mapper 接口开发需要遵循以下规范:
1、 Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同。
2、 Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
3、 Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的parameterType 的类型相同
4、 Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的resultType 的类型相同
定义 mapper 映射文件 UserMapper.xml(内容同 Users.xml),需要修改namespace 的值为 UserMapper 接口路径。将 UserMapper.xml 放在 resources 下 mapper 目录下。
<?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">
<mapper namespace="edu.etime.mybatis.mapper.UserMapper">
<!-- 根据id获取用户信息 -->
<select id="findUserById" parameterType="int"
resultType="edu.etime.mybatis.po.User">
select * from user where id = #{id}
</select>
<!-- 自定义条件查询用户列表 -->
<select id="findUserByUsername" parameterType="java.lang.String"
resultType="edu.etime.mybatis.po.User">
select * from user where username like '%${value}%'
</select>
<!-- 添加用户 -->
<insert id="insertUser" parameterType="edu.etime.mybatis.po.User"><selectKey keyProperty="id" order="AFTER"
resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
接口定义有如下特点:
1、 Mapper 接口方法名和 Mapper.xml 中定义的 statement 的 id 相同2、 Mapper 接口方法的输入参数类型和 mapper.xml 中定义的 statement 的parameterType 的类型相同
3、 Mapper 接口方法的输出参数类型和 mapper.xml 中定义的 statement 的resultType 的类型相同
package com.etime.mapper;
import com.etime.pojo.Student;
import java.util.List;
public interface StudentMapper {
//根据用户id查询用户信息
public Student findStudentById(int id);
//根据用户名查询用户列表
public List<Student> findStudentBySname(String sname);
//添加用户信息
public int insertStudent(Student student);
}
修改 mybatis-config.xml 文件:
<!-- 加载映射文件 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
Mapper.xml 映射文件中定义了操作数据库的 sql,每个 sql 是一个statement,映射文件是 mybatis 的核心。
1 #表示占位符,可以预防sql注入,mybatis会自动进行java类型和jdbc类型的转换。
2 $ 可以将参数传入的内容拼接在 sql 中且不进行 jdbc 类型转换
3 如果参数是简单数据类型,#{任何值},${value}
4 在sql语句中不能使用#,只能使用 $ 的情况,如:排序方式关键字asc/desc,tablename(表名),字段名。
1.传递简单类型
2.传递 pojo 对象
3.传递 pojo 包装对象
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。
4.定义包装对象
public class QueryVo { private User user; //自定义用户扩展类 private UserCustom userCustom;
5.mapper.xml 映射文件
6.传递 hashmap
1.输出pojo对象和pojo列表,resultType的类型是一致的;
2.输出pojo对象要求查询结果只有一条或0条,内部sqlSession.selectOne;
3.输出pojo列表要求输出结果是多条,内部sqlSession.selectList;
1.输出简单类型
2.输出 pojo 对象
3.输出 pojo 列表
4.输出 hashmap
输出 pojo 对象可以改用 hashmap 输出类型,将输出的字段名称作为map 的key,value 为字段值。
注意:输出hashmap,要求查询结果只能是一条或者0条记录(内部使用的是session.selectOne方法)。如果没有查询结果,那么返回一个 null。
1.当sql列名和pojo属性名一致时,可以用resultType映射查询结果;
2.当sql列名和pojo属性名不一致时,就只能用resultMap来映射查询结果,并且可以使用association将一对一关联查询信息映射到一个pojo对象中,用collection将多对多(包含一对多)关联查询信息映射到一个pojo列表。
通过 mybatis 提供的各种标签方法实现动态拼接 sql。
1.if
!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">select * from user
where 1=1
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</select>
2.where
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
3.foreach
向 sql 传递数组或 List,mybatis 使用 foreach 解析。
此文章为学习记录文章,参考多篇文章,如有不正之处请指教