无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器(截取部分)
你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。具体做法为:实现
org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个JDBC类型。
项目环境搭建
创建项目mybatis-confing
修改tset
数据库中的user
表,添加一个brithday
字段,类型为bigint
创建com.zcl.mapper
包并创建UserMapper
接口
package com.zcl.mapper;
import com.zcl.domain.User;
import java.util.List;
/**
* 项目名称:MyBatis
* 描述:mybatis的dao层接口
*
* @author zhong
* @date 2022-05-08 11:58
*/
public interface UserMapper {
void save(User user);
}
创建com.zcl.domain
包并创建User
实体类
package com.zcl.domain;
import java.util.Date;
/**
* 项目名称:MyBatis
* 描述:对应数据User实体类
*
* @author zhong
* @date 2022-05-08 7:43
*/
public class User {
private int id;
private String username;
private String password;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
比之前的项目多了
birthday
时间类型的属性
编写resources
文件下的UserMapper.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">
<mapper namespace="com.zcl.mapper.UserMapper">
<insert id="save" parameterType="user">
insert into user values (#{id},#{username},#{password},#{birthday})
</insert>
</mapper>
在test
包下编写测试方法
package com.zcl.test;
import com.zcl.domain.User;
import com.zcl.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 项目名称:MyBatis
* 描述:测试
*
* @author zhong
* @date 2022-05-08 15:36
*/
public class MapperTest {
@Test
public void test1() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("新增");
user.setPassword("123");
user.setBirthday(new Date());
// 执行保存操作
mapper.save(user);
sqlSession.commit();
sqlSession.close();
}
}
正常启动测试是会报错的,所以需要使用下面的方法进行自定义类型转换
定义转换类继承类BaseTypeHandler
覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时 mysql的字符串类型转换成 java的Type类型的方法
结合2、3步一起
创建
com.zcl.handler
包,并创建DateTypeHandler类
package com.zcl.handler;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
/**
* 项目名称:MyBatis
* 描述:自定义类型转换
*
* @author zhong
* @date 2022-05-08 20:38
*/
public class DateTypeHandler extends BaseTypeHandler<Date> {
/**
* 将java类型转换成mysql需要的类型
* @param preparedStatement
* @param i
* @param date
* @param jdbcType
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i,time);
}
/**
* 将数据库中的类型 转换成java类型
* @param resultSet 查询出的结果集
* @param s 要转换字段的名称
* @return
* @throws SQLException
*/
@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类型
* @param resultSet
* @param
* @return
* @throws SQLException
*/
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
/**
* 将数据库中的类型 转换成java类型
* @param callableStatement
* @param i
* @return
* @throws SQLException
*/
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
}
在MyBatis核心配置文件中进行注册
在mybatis-config.xml
配置文件中进行注册
<typeHandlers>
<typeHandler handler="com.zcl.handler.DateTypeHandler"/>
typeHandlers>
测试转换是否正确
测试插入数据是可以正常的,但是出现的时候就出现不到毫秒值数据
MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
导入通用PageHelper的坐标
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>3.7.5version>
dependency>
<dependency>
<groupId>com.github.jsqlparsergroupId>
<artifactId>jsqlparserartifactId>
<version>0.9.1version>
dependency>
在mybatis核心配置文件中配置PageHelper插件
在mybatis-config.xml
配置文件中添加
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
plugin>
plugins>
测试分页数据获取
@Test
public void test3() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = build.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 设置分页的参数 当前页 + 当前页总数
PageHelper.startPage(1,3);
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
// 获取相关的分页参数
PageInfo<User> pageInfo = new PageInfo<User>(all);
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());
System.out.println("是否是最后一页:"+pageInfo.isIsLastPage());
sqlSession.close();
}
引入插件之后在测试环境里使用:
PageHelper.startPage(1,3);
设置分页的起始页和页显示总数