Mybatis 自动类型转换

1、新建类xxxTypeHandler,实现TypeHandler接口 或 继承 BaseTypeHandler类

package com.william.typehandler;

import com.william.mapper.IdCardType;
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.util.Base64;

/**
 * 身份证加密解密类型转换器
 */

public class EncryptTypeHandler implements TypeHandler<IdCardType> {

    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, IdCardType idCardType, JdbcType jdbcType) throws SQLException {
        String cryptIdCard = Base64.getEncoder().encodeToString(idCardType.getIdCard().getBytes());
        preparedStatement.setString(i, cryptIdCard);
    }

    @Override
    public IdCardType getResult(ResultSet resultSet, String s) throws SQLException {
        String cryptIdCard = resultSet.getString(s);
        String idCard = new String(Base64.getDecoder().decode(cryptIdCard));
        IdCardType idCardType = new IdCardType(idCard);
        return idCardType;
    }

    @Override
    public IdCardType getResult(ResultSet resultSet, int i) throws SQLException {
        String cryptIdCard = resultSet.getString(i);
        String idCard = new String(Base64.getDecoder().decode(cryptIdCard));
        IdCardType idCardType = new IdCardType(idCard);
        return idCardType;
    }

    @Override
    public IdCardType getResult(CallableStatement callableStatement, int i) throws SQLException {
        String cryptIdCard = callableStatement.getString(i);
        String idCard = new String(Base64.getDecoder().decode(cryptIdCard));
        IdCardType idCardType = new IdCardType(idCard);
        return idCardType;
    }
}

2、在Mybatis-config.xml中注册类型转换器

<typeHandlers>
        <typeHandler handler="com.william.typehandler.EncryptTypeHandler" javaType="IdCardType"></typeHandler>
    </typeHandlers>

3、直接使用

package com.william;

import com.william.mapper.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Data
public class Main {
    static public void main(String[] args) throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        System.out.println(inputStream.toString());
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession(true);
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        Student student = new Student();
        student.setAddress("Beijing");
        student.setAge(99);
        student.setName("FUCK");
        student.setPassword("123123");
        student.setIdCardType(new IdCardType("this is unencryptedPassword!"));
        mapper.insertTestTypeHandler(student);
        System.out.printf("自增主键为: %d\n", student.getId());
        student = mapper.selectTestTypeHandler(4);
        System.out.println(student);
    }
}

结果:

==>  Preparing: INSERT INTO students(`password`, `age`, `salary`, `address`, `name`, `idcard`) VALUES (?, ?, ?, ?, ?, ?)
==> Parameters: 123123(String), 99(Integer), null, Beijing(String), FUCK(String), dGhpcyBpcyB1bmVuY3J5cHRlZFBhc3N3b3JkIQ==(String)
<==    Updates: 1
自增主键为: 9
==>  Preparing: select * from students where id=?
==> Parameters: 4(Integer)
<==    Columns: id, password, age, salary, address, name, idcard
<==        Row: 4, 123123, 99, null, Beijing, FUCK, dGhpcyBpcyB1bmVuY3J5cHRlZFBhc3N3b3JkIQ==
<==      Total: 1
Student{idCardType=IdCardType(idCard=this is unencryptedPassword!), roles=null, id=4, password='123123', age=99, salary=null, address='Beijing', name='FUCK'}

 

### 实现 Spring Boot 整合 MyBatis 并实现类型转换的方法 在 Spring Boot 项目中整合 MyBatis 并实现类型转换,主要涉及以下几个方面: #### 1. 配置 MyBatis类型处理器 MyBatis 提供了 `TypeHandler` 接口,用于实现 Java 类型与 JDBC 类型之间的换。通过自定义 `TypeHandler`,可以实现特定业务场景下的数据换逻辑。例如,在数据插入或查询时,对数据库字段进行加密或解密处理。 在配置文件中可以通过 `mybatis.type-handlers-package` 指定类型处理器的包路径,这样 MyBatis自动扫描并注册这些处理器: ```properties mybatis.type-handlers-package=com.ds.handler ``` 如果需要为枚举类型指定默认的类型处理器,可以使用如下配置: ```properties mybatis.configuration.default-enum-type-handler=com.ds.handler.GenericEnumHandler ``` 这些配置确保了在操作数据库时,MyBatis 能够正确地处理自定义类型或枚举类型的数据换[^2]。 #### 2. 自定义类型处理器的实现 为了实现特定的换逻辑,需要继承 `BaseTypeHandler` 并重写其方法。例如,以下是一个用于加密和解密字段的类型处理器示例: ```java 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; public class EncryptedStringTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { // 插入数据库时进行加密 ps.setString(i, encrypt(parameter)); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { // 查询时进行解密 return decrypt(rs.getString(columnName)); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return decrypt(rs.getString(columnIndex)); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return decrypt(cs.getString(columnIndex)); } private String encrypt(String value) { // 实现加密逻辑 return value; // 示例中直接返回原值 } private String decrypt(String value) { // 实现解密逻辑 return value; // 示例中直接返回原值 } } ``` 在实际使用中,可以将 `encrypt` 和 `decrypt` 方法替换为具体的加解密算法。定义好类型处理器后,将其放置在配置的包路径下,MyBatis自动加载并应用该处理器[^1]。 #### 3. 在 MyBatis 映射文件中使用类型处理器 在 MyBatis 的 XML 映射文件中,可以直接指定字段使用的类型处理器。例如,在插入语句中,可以为特定字段指定自定义的类型处理器: ```xml <insert id="insertPerson"> INSERT INTO person (id, name, id_no, create_time) VALUES ( #{id}, #{name, typeHandler=com.ds.handler.EncryptedStringTypeHandler}, #{idNo, typeHandler=com.ds.handler.EncryptedStringTypeHandler}, #{createTime} ) </insert> ``` 通过这种方式,可以在插入或查询特定字段时,强制使用指定的类型处理器进行数据换[^1]。 #### 4. 在 Java 实体类中使用注解 除了在 XML 文件中指定类型处理器外,还可以通过注解的方式在实体类中直接绑定类型处理器。例如: ```java import org.apache.ibatis.type.TypeHandler; import org.apache.ibatis.type.JdbcType; public class Person { private String id; @TypeHandler(value = EncryptedStringTypeHandler.class) private String name; @TypeHandler(value = EncryptedStringTypeHandler.class) private String idNo; private Date createTime; // Getter and Setter } ``` 这种方式更加直观,适用于字段数量较少的实体类[^1]。 #### 5. 测试类型转换逻辑 在测试过程中,可以通过编写单元测试来验证类型处理器是否正常工作。例如,在插入数据后,检查数据库中存储的字段是否已被加密;在查询数据时,验证返回的字段是否已被正确解密。 以下是一个简单的测试类示例: ```java import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Date; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class PersonMapperTest { @Autowired private PersonMapper personMapper; @Test public void testInsertMapper() { Person person = new Person(); person.setId("0001"); person.setCreateTime(new Date()); person.setIdNo("111111"); person.setName("中国"); personMapper.insertPerson(person); } @Test public void testQueryPersons() { List<Person> persons = personMapper.queryPersons(); for (Person person : persons) { System.out.println(person); } } } ``` 通过运行这些测试方法,可以验证类型处理器是否在插入和查询过程中正确地进行了数据换[^1]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值