typeHandlers标签
无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获得的值以合适的方式转换为Java类型,下表描述了一些默认的类型处理器(截取部分)
在进行项目开发时,一般情况下需要将Java对象中的数据转移到有占位符的位置,将查询出的数据转移到对象当中,在转换过程当中,会涉及到数据类型的转换,因为jdbc类型和Java类型不是一样的,但是这种转换关系不用我们去做,因为MyBatis会提供一系列的类型处理器,但在有些情况下,Java类型的数据可以需要自定义一些类型转换器或者没有这种对应的类型转换器
你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型,具体做法为:实现org.apache.ibatis.type.TypeHandler接口,或继承一个很便利的类org.apache.ibatis.type.BaseTypeHandler,然后可以选择性地将它映射到一个JDBC类型。例如需求:一个Java中的Date数据类型,我想将之存到数据库的时候存成一个1970年至今的毫秒数,取出来时转换成java的Date,即java的Date与数据库的varchar毫秒值之间转换。
开发步骤:
0、使用普通方法进行日期时间的插入
UserMapper接口类
package com.zg.mapper;
import com.zg.domain.User;
public interface UserMapper {
public void save(User user);
}
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.zg.mapper.UserMapper" >
<insert id="save" parameterType="user" >
insert into user values (#{id},#{username},#{password},#{birthday})
</insert>
</mapper>
测试类
package com.zg.test;
import com.zg.domain.User;
import com.zg.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.Date;
public class MybatisTest {
@Test
public void test1() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//模拟一个user对象
User user = new User();
user.setId(6);
user.setUsername("haha");
user.setPassword("123");
user.setBirthday(new Date());
//执行保存操作
mapper.save(user);
sqlSession.commit();
sqlSession.close();
}
}
这里会因为类型转换为题报错,Data truncated for column 'birthday' at row 1
所以我们需要以下步骤
1、定义转换类继承类BaseTypeHandler<T>
其中给定的泛型就是要转换的java类型(将data转换为数字类型存储到数据库中)
package com.zg.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;
public class DateTypeHandler extends BaseTypeHandler<Date> {
@Override
//将Java转换为数据库需要的类型
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i,time);
}
@Override
//将数据库中的类型转换为Java类型
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
//String参数,表的字段的名称(要转换的字段名称)
//ResultSet 查询出的结果集
//获取结果集中需要的数据(long)转换为Date类型,返回
long aLong = resultSet.getLong(s);
Date date = new Date(aLong);
return date;
}
@Override
//将数据库中的类型转换为Java类型
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
//i为字段的位置
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
@Override
//将数据库中的类型转换为Java类型
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
}
2、覆盖4个未实现的方法,其中setNonNullarameter为java程序设置数据到数据库的回调方法(Java–>数据库需要的数据),getNullableResult为查询时mysql的字符串类型转换成java的Type类型的方法
3、在MyBatis核心配置文件中进行注册
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--主要配置mybatis的核心配置-->
<configuration>
<!--通过properties标签加载外部properties文件-->
<properties resource="jdbc.properties"></properties>
<!--自定义别名-->
<typeAliases>
<typeAlias type="com.zg.domain.User" alias="user"></typeAlias>
</typeAliases>
<!--自定义类型处理器-->
<typeHandlers>
<typeHandler handler="com.zg.handler.DateTypeHandler"></typeHandler>
</typeHandlers>
<!--配置当前数据源的环境-->
<environments default="developement">
<environment id="developement">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="com.zg.mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
4、测试转换是否正确
@Test
//将数据库的毫秒值查询到Java中的date
public void test2() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findById(6);
System.out.println("user中的birthday:" + user.getBirthday());
sqlSession.commit();
sqlSession.close();
}
plugins标签
MyBatis可以使用第三方插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即课获得分页的相关数据
开发步骤
1、导入通用的PageHelper的坐标
<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>0.9.1</version>
</dependency>
2、在mybatis核心配置文件中配置PageHelper插件
<!--配置分页助手插件,需要配置通用mapper之前-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!--设置方言,因为不同的sql语言使用的结构化语言是不一样的-->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
3、测试分页数据获取
@Test
//查询全部
public void test3() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//设置分页的相关参数 当前页和每页显示的条数
PageHelper.startPage(1,3);
List<User> all = mapper.findAll();
for (User user : all) {
System.out.println(user);
}
sqlSession.close();
}
获得分页相关的其它参数
@Test
//查询全部
public void test3() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.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<>(all);
System.out.println("当前页:"+pageInfo.getPageNum());//当前页:1
System.out.println("每页显示条数:"+pageInfo.getSize());//每页显示条数:3
System.out.println("总条数:"+pageInfo.getTotal());//总条数:6
System.out.println("总页数:"+pageInfo.getPages());//总页数:2
System.out.println("上一页:"+pageInfo.getPrePage());//上一页:0
System.out.println("下一页:"+pageInfo.getNextPage());//下一页:2
System.out.println("是否是第一个:"+pageInfo.isIsFirstPage());//是否是第一个:true
System.out.println("是否是最后一个:"+pageInfo.isIsLastPage());//是否是最后一个:false
sqlSession.close();
}
MyBatis核心配置文件常用标签
1、propertids标签:该标签可以加载外部的properties文件
2、typeAliases标签:设置类型别名
3、environments标签:数据源环境配置标签
4、typeHandlers标签:配置自定义类型处理器
5、plugins标签:配置MyBatis的插件