文章目录
1 Mybatis的Dao层实现
1.1 传统开发方式
仍然在Dao层编写接口并实现,将Dao层对象和Service层对象配置成Bean,在Controller层使用Servcie层对象完成业务的处理
1.2 代理开发介绍
采用Mybatis的代理开发方式实现Dao层的开发,这种方式也是企业中的主流,Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同Dao接口的实现类方法
Mapper接口开发需要遵循的规范:
Dao层接口需要与Mapper.xml映射起来:
1,编写Dao层接口UserMapper:
public interface UserMapper {
List<User> findAll() throws IOException;
User findById(int id);
}
2,在UserMapper.xml中根据要求重新配置:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace对应Dao层某个接口的全限定名 -->
<mapper namespace="com.coisini.dao.UserMapper">
<!-- id为findAll 对应接口中一定要存在findAll()方法 返回值类型和参数类型都需要是全限定名 -->
<select id="findAll" resultType="com.coisini.domain.User">
SELECT * FROM user
</select>
<select id="findById" resultType="com.coisini.domain.User" parameterType="int">
SELECT * FROM user WHERE id=#{id}
</select>
</mapper>
3,测试:
2 Mybatis映射文件深入
2.1 动态SQL语句
当业务逻辑复杂时,SQL语句可能是变化的,比如根据客户端传来的条件查询时,如果客户端传来了一个参数,则SQL可能是SELECT * FROM user WHERE id=#{id}
但如果传来两个参数
可能就会是SELECT * FROM user WHERE id=#{id} AND password=#{password}
,这个查询的SQL语句就是不能确定的
2.1.1 动态SQL的if标签
在UserMapper.xml中配置一个模糊查询的SQL语句:
<select id="findByCondition" resultType="com.coisini.domain.User" parameterType="com.coisini.domain.User">
SELECT * FROM user
<where>
<if test="id!=0">
AND id=#{id}
</if>
<if test="username!=null">
AND username=#{username}
</if>
<if test="password!=null">
AND password=#{password}
</if>
</where>
</select>
测试:
2.1.2 动态SQL的foreach标签
如SELECT * FROM user WHERE id IN(1, 2, 4)
这样的SQL语句也是不确定的,括号中的参数是可以不定的,这类SQL语句同样是不能确定的
在UserMapper.xml中配置一个动态SQL:
<select id="findByIds" resultType="com.coisini.domain.User" parameterType="list">
SELECT * FROM user
<where>
<foreach collection="list" open="id IN(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
测试:
2.2 SQL片段抽取
可以将多次重复出现的SQL语句抽取出来,使用时通过include标签,来引用
如在查询操作中,经常以SELECT * FROM user
开头,这部分SQL语句就可以被抽取出来:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.coisini.dao.UserMapper">
<!-- SQL语句的抽取 -->
<sql id="selectUser">SELECT * FROM user</sql>
<select id="findByCondition" resultType="com.coisini.domain.User" parameterType="com.coisini.domain.User">
<include refid="selectUser"></include>
<where>
<if test="id!=0">
AND id=#{id}
</if>
<if test="username!=null">
AND username=#{username}
</if>
<if test="password!=null">
AND password=#{password}
</if>
</where>
</select>
<select id="findByIds" resultType="com.coisini.domain.User" parameterType="list">
<include refid="selectUser"></include>
<where>
<foreach collection="list" open="id IN(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
</mapper>
3 Mybatis核心配置文件深入
3.1 typeHandlers标签
无论是Mybatis在PreparedStatement中设置一个参数,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成Java类型,一些默认的类型处理器如下:
可以重写类型处理器或自定义类型处理器满足自己的需求,如一个Java中的Date数据类型,存到数据库时想存成一个1970至今的毫秒数,取出来时再转换成Date,即完成Date和varchar的相互转换,开发步骤:
1,定义转换继承类BasetypeHandle<T>
2,覆盖4个未实现方法
其中setNonNullPointer为Java程序设置数据到数据库的回调方法
getNullableResult为查询时mysql的字符串类型转换成Java的Type类型方法
3,在SqlMapConfig.xml配置文件中进行注册
4,测试转换是否正确
3.2 plugins标签
Mybatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
开发步骤:
1,导入PageHelper相关jar包
2,在SqlMapConfig.xml中使用plugins标签配置插件
3,测试分页数据获取
1,导入PageHelper相关jar包:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>1.0</version>
</dependency>
2,在SqlMapConfig.xml中使用plugins标签配置插件:
<!-- 配置分页助手插件 -->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"></property>
</plugin>
</plugins>
sqlMapConfig.xml中标签之间存在一定的先后顺序,报错了调整顺序即可
3,测试分页数据获取:
通过PageHelper.startPage()就可以获取不同页中的若干条数据
还可以通过PageInfo来获取关于分页的信息:
// 获得与分页相关的参数
PageInfo<User> pageInfo = new PageInfo<>(userList);
System.out.println("当前页: " + pageInfo.getPageNum());
System.out.println("每页显示条数: " + pageInfo.getPageSize());
System.out.println("总条数: " + pageInfo.getTotal());
System.out.println("总页数: " + pageInfo.getPages());
System.out.println("上一页: " + pageInfo.getPrePage());
4 Mybatis的注解开发
Mybatis常用的注解:
@Insert: 插入
@Update: 更新
@Delete: 删除
@Select: 查询
@Result: 实现结果集封装
@Results: 可以与@Result一起使用,封装多个结果集
@One: 实现一对一结果集封装
@Many: 实现一对多结果集封装
1,编写接口并在接口中使用注解完成持久层操作:
public interface UserMapper {
@Insert("INSERT INTO user VALUES(#{id}, #{username}, #{password})")
void save(User user);
@Update("UPDATE user SET username=#{username}, password=#{password} WHERE id=#{id}")
void update(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
void delete(int id);
@Select("SELECT * FROM user WHERE id=#{id}")
User findById(int id);
@Select("SELECT * FROM user")
List<User> findAll();
}
2,在sqlMapConfig.xml中加载映射关系:
<!-- 加载映射关系 -->
<mappers>
<!-- 指定接口所在的包 这些带注解的接口会被扫描 -->
<package name="com.coisini.mapper"/>
</mappers>