概述
学习Mybatis之02-->配置文件开发之代理开发模式
- 一、代理开发以及案例
- 概述
- 开发步骤
- 二、动态SQL语句
- if
- foreach
- 三、SQL片段抽取
- 四、核心配置文件深入
- TypeHandlers(类型转换器)标签
- 五、plugins标签
这一篇主要讲的是通过代理开发模式来进行配置文件的深入学习,其中的知识点有动态SQL语句、typeHandler类型处理、plugins插件标签、SQL片段抽取、pagehelper分页助手 |
一、代理开发以及案例
概述
在代理开发模式中,我们不在使用DAO层,而是用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的类型相同
开发步骤
前言
关于坐标导入、以及SqlMapConfig.xml里面的详细配置、javaBean的创建都是必要的前提,在上一篇文章中有详细提到,这里就不在赘述了 |
Mybatis之01—>配置文件(????查看请点我)
1、创建Mapper所需的interface,并在Mapper文件中修改namespace与mapper接口的全限定名相同
创建Mapper所需的interface
修改namespace(需要是路径名称+接口名称)
<mapper namespace="Z.S.mapper.UserMapper">
2、在配置文件中编写SQL语句并让id与下面的接口方法名相同
SQL语句
<?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="Z.S.mapper.UserMapper">
<!--插入操作-->
<insert id="save" parameterType="user"> <!--parameterType(参数类型):应该与接口名的参数类型一致-->
insert into user values (#{id},#{username},#{password},#{birthday})
</insert>
<!--查询操作-->
<select id="findAll" resultType="user"> <!--resultType(结果类型):应该与接口方法的返回值类型保持一致-->
select * from user
</select>
</mapper>
接口方法
/**
* @author 朱霸霸
* @date 2022/5/26 17:12
*/
public interface UserMapper {
public void save(User user); //参数是user
public List<User> findAll() throws IOException; //返回值类型为集合中的User
}
我们从上面可以看出,mapper的接口方法名是与statement的id名称是相对应的,Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同, Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同,这样可使我们的mybatis对其进行映射。
3、编写实现类并实现代理模式开发
public class Test {
@org.junit.Test
public void Test() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//模拟新对象
User user = new User();
user.setUsername("wanwan");
user.setPassword("123456");
user.setBirthday(new Date());
mapper.save(user);
}
}
4、实现成功
二、动态SQL语句
前言
首先我们应该了解什么是动态语句,动态语句的适用场景啊、以及动态语句的实现方式 |
what(是什么)?
动态SQL就是指根据不同的条件生成不同的SQL语句
environment(使用场景)?
if:
比如在用到多条件查询时,前端页面会提供三个条件输入框、但用户有可能只输入两个条件进行查询。这个条件的个数是变化的、那么对应SQL语句的查询字段也是变化的,这时候就可以使用动态SQL。
可以对应于SQL语句中的 where <条件> and <条件>and…去配套理解
foreach:
当用户输入查询条件时,查询满足这个条件的所有结果
可以对应SQL语句中的 where <条件> or <条件> or 或者 where
realize(如何实现)?
实现动态SQL的方式这里会介绍两种:
1️⃣if 2️⃣ foreach
if
SQL语句的编写
<!--动态语句查询-->
<select id="findByCondition" parameterType="user" resultType="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>
实现测试类
public class Test {
@org.junit.Test
public void Test() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//模拟条件
User condition = new User();
condition.setId(1);//只根据id进行查询
List<User> userList = mapper.ffindByCondition(codition);
for(User user : userList){
System.out.println(user)
}
}
}
只根据id进行查询所执行的SQL语句
foreach
SQL语句编写
<!--动态语句查询-->
<select id="findByIds" parameterType="list" resultType="user" >
<include refid="selectUser"></include>
<where>
<foreach collection="list" open="id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
实现测试类
public class Test {
@org.junit.Test
public void Test() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//模拟ids的数据
List<Integer> ids = new ArrayList<Integer>();
idsList.add(1);
idsList.add(2);
List<User> userList = mapper.findByIds(idsList);
for(User user:userList){
sout(user)
}
执行的SQL语句
foreach标签内参数说明:
参数 | 描述 |
---|---|
item | 循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。具体说明:在list和数组中是其中的对象,在map中是value。 |
collection | 要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。 当然在作为入参时可以使用@Param(“keyName”)来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List ids。入参是User对象,那么这个collection = "ids"如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"上面只是举例,具体collection等于什么,就看你想对那个元素做循环。该参数为必选 |
separator | 元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。 |
open | foreach代码的开始符号,一般设置为“(“和close=")"合用。常用在in(),values()时。该参数可选。 |
close | oreach代码的关闭符号,一般设置为“)“和open="("合用。常用在in(),values()时。该参数可选。 |
index | 在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。 |
三、SQL片段抽取
前言
SQL中可将重复的SQL语句抽取出来,使用include引用即可,最终达到重用SQL语句的目的,一般来说:select * from 表 是最常用的 ,下面就是该语句作为案例
1.定义一个SQL标签,指定标签id,后期直接在include里面引用该id
2.在标签体类进行SQL语句的编写
<!--sql语句抽取-->
<sql id="selectUser">select * from user</sql>
3.在别处进行建立include标签进行引用
<!--动态语句查询-->
<select id="findByCondition" parameterType="user" resultType="user">
<include refid="selectUser"></include> //引用SQL语句
<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>
四、核心配置文件深入
TypeHandlers(类型转换器)标签
因为数据的数据类型与java数据类型并不统一、因此该标签的功能主要是进行数据库与java之间的数据类型转换。
通过该标签可以自己处理不支持的或非标准的类型。具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个JDBC类型。
开发步骤:
- 定义转换类继承类BaseTypeHandler T为要转换的java类型
- 覆盖4个未实现的方法,其中setNonNullParameter(java转数据库)为java程序设置数据到数据库的回调方法,getNullableResult(数据库转java)为查询时 mysql的字符串类型转换成 java的Type类型的方法
- 在MyBatis核心配置文件中进行注册
- 测试转换是否正确
实际操作:
需求:一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,取出来时转换成iava的Date,即iava的Date与数据库存储的毫秒值之间转换。
1、数据库设计:
在数据建立一个bigint类型(为什么是bigint?因为根据需求,要存储毫秒值在数据库内,毫秒值是一长串整数值,是一个java的long的类型,对应的数据库应是bigint)的字段
2.在实体类创建一个类型为Date的成员变量
3.定义转换类继承类BaseTypeHandler
public class DataTypeHandler extends BaseTypeHandler<Date> {
//将java类型转换成数据库需要的类型
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i,time);
}
//将数据库中的数据类型转换成java类型
//String参数 要转换的字段名称(数据库)
//ResultSet 查询结果集
@Override
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
//获取结果集中需要的数据(long)将其转换成Date类型并返回
long aLong = resultSet.getLong(s);
Date date = new Date(aLong);
return date;
}
//将数据库中的数据类型转换成java类型
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
//将数据库中的数据类型转换成java类型
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
3、在核心配置文件中注册
<!--自定义类型处理器-->
<typeHandlers>
<typeHandler handler="Z.S.handler.DataTypeHandler"></typeHandler>
</typeHandlers>
4.编写测试类
User user = new User();
user.setUsername("wanwan");
user.setPassword("123456");
user.setBirthday(new Date());
mapper.save(user);
mapper.findById(15);
五、plugins标签
下面以PageHelper为案例进行介绍
MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
开发步骤:
- 导入通用PageHelper的坐标(pox.xml中导入)
- 在mybatis核心配置文件中配置PageHelper插件
- 测试分页数据获取
具体实现:
1、导入坐标(两个)
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.6</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
2.在mybatis核心配置文件中配置PageHelper插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!--方言的指定-->
<property name="dialect" value="mysql"></property>
</plugin>
</plugins>
3.编写测试类
public class Test {
@org.junit.Test
public void Test() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//设置分页相关参数 当前页、每页显示的条数
PageHelper.startPage(1,3);
List<User> userList = mapper.findAll();
for (User user : userList) {
System.out.println(user);
}
//获取与分页相关参数
PageInfo<User> pageInfo = new PageInfo<User>(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());
System.out.println("下一页:"+pageInfo.getNextPage());
System.out.println("是否是第一页:"+pageInfo.isIsFirstPage());
sqlSession.close();
}
}
最后
以上就是活泼画笔为你收集整理的学习Mybatis之02-->配置文件开发之代理开发模式一、代理开发以及案例二、动态SQL语句三、SQL片段抽取四、核心配置文件深入五、plugins标签的全部内容,希望文章能够帮你解决学习Mybatis之02-->配置文件开发之代理开发模式一、代理开发以及案例二、动态SQL语句三、SQL片段抽取四、核心配置文件深入五、plugins标签所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复