MyBatis实现自定义TypeHandler进行数据转换

场景

在 Java 实体类中,定义时间的属性一般是Date 类型,但数据库中却是字符串类型,每次查询、新增等操作都要做类型转换,但如果使用 Mybatis 提供的自定义 TypeHandler 的功能就能完美的解决这个问题。
实体类User.java

package com.lks.domain;

import java.io.Serializable;
import java.util.Date;

/**
 * Created by likaisong on 2019/2/24.
 */
public class User implements Serializable {
    private int id;
    private String name;
    private int age;
    private String county;
    private Date date;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getCounty() {
        return county;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date= date;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", age=" + age + ", county=" + county + ", date=" + date + "]";
    }
}

自定义TypeHandle,有两种实现方式:直接实现 TypeHandler 也可以继承 BaseTypeHandler,这里我选择直接实现 TypeHandler :
DateToStringTypeHandler.java

package com.lks.handler;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by likaisong on 2019/2/25.
 */
public class DateToStringTypeHandler implements TypeHandler{
    /**
     * 将时间戳传入数据库
     * @param preparedStatement
     * @param i
     * @param o
     * @param jdbcType
     * @throws java.sql.SQLException
     */
    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
        Date date = (Date) o;
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(date);
        preparedStatement.setString(i, dateString);
    }

    /**
     * 将字符串类型的时间戳转换为Date
     * @param resultSet
     * @param s
     * @return
     * @throws SQLException
     */
    @Override
    public Object getResult(ResultSet resultSet, String s) throws SQLException {
        String timeStr = resultSet.getString(s);
        if (timeStr != null || "".equals(timeStr)){
            return stringToDate(timeStr);
        }
        return null;
    }

    @Override
    public Object getResult(ResultSet resultSet, int i) throws SQLException {
        String timeStr = resultSet.getString(i);
        if (timeStr != null || "".equals(timeStr)){
            return stringToDate(timeStr);
        }
        return null;
    }

    @Override
    public Object getResult(CallableStatement callableStatement, int i) throws SQLException {
        String timeStr = callableStatement.getString(i);
        if (timeStr != null || "".equals(timeStr)){
            return stringToDate(timeStr);
        }
        return null;
    }

    private Date stringToDate(String timeStr) {
        if (timeStr != null || "".equals(timeStr)) {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            ParsePosition pos = new ParsePosition(0);
            Date date = formatter.parse(timeStr, pos);
            return date;
        }
        return null;
    }
}

mybatis配置文件中配置自定义typeHandler,主要看typeHandler标签:
mybatis-config:




    
        
    
    
        
            
            
                
                
                
                
            
        
    
    
        
    

mapper文件中新增或查询操作:





    
    
        insert into users (id, name, age, county, date)
        values (#{id},#{name},#{age},#{county},#{date, typeHandler=com.lks.handler.DateToStringTypeHandler})
    
    
        
    
    

新增数据的操作只要对需要进行类型转换的字段添加相关配置即可,但查询操作需要借助resultMap来实现转换。
对操作执行测试方法:
TestMain.java

package com.lks.test;

import com.lks.domain.User;
import com.lks.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.testng.annotations.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

/**
 * Created by likaisong on 2019/2/24.
 */
public class TestMain {
    private static SqlSession getSqlSession(String resource){
        if (resource == null || "".equals(resource)){
            return null;
        }
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        return session;
    }
    @Test
    public static void testDateToString(){
        String resource = "mybatis-config.xml";
        SqlSession session = getSqlSession(resource);
        try {
            String statement = "userMapper.dateToString";
            User user = new User();
            user.setName("阿飞");
            user.setAge(20);
            user.setCounty("中国");
            user.setDate(new Date());
            session.insert(statement, user);
            session.commit();
            System.out.println("插入数据后返回的自增ID:" + user.getId());
        } finally {
            session.close();
        }
    }

    @Test
    public static void testStringToDate(){
        String resource = "mybatis-config.xml";
        SqlSession session = getSqlSession(resource);
        try {
            //先插入一条数据
            String insertStatement = "userMapper.dateToString";
            User user = new User();
            user.setName("阿飞");
            user.setAge(20);
            user.setCounty("中国");
            user.setDate(new Date());
            session.insert(insertStatement, user);
            session.commit();
            System.out.println("插入数据后返回的自增ID:" + user.getId());
            //查询刚插入的数据
            String selectStatement = "userMapper.stringToDate";
            User resUser = session.selectOne(selectStatement, user.getId());
            System.out.println(resUser);
        } finally {
            session.close();
        }
    }
}

通过查表或由直接打印出来对内容可以看到时间字段可以在Date和String中实现灵活准换,自定义的 TypeHandler 也经常用来解决项目中的枚举类型,也是比较方便的。

你可能感兴趣的:(mybatis)