SpringBoot整合MyBatis自定义类型转换实现数据加解密

导读:本篇文章讲解 SpringBoot整合MyBatis自定义类型转换实现数据加解密,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

环境:springboot2.3.9.RELEASE + MyBatis3.5.6 + MySQL + Java8


这里我们只是讲解MyBatis的自定义类型转换如何使用。

本案例使用自定义类型转换器对数据列进行加解密

依赖及相关配置

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
  </dependency>
  <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
  </dependency>
  <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.3.0</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
      <exclusion>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
  </dependency>
</dependencies>
spring:
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/testjpa?serverTimezone=GMT%2B8
    username: root
    password: 123123
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimumIdle: 10
      maximumPoolSize: 200
      autoCommit: true
      idleTimeout: 30000
      poolName: MasterDatabookHikariCP
      maxLifetime: 1800000
      connectionTimeout: 30000
      connectionTestQuery: SELECT 1
---
spring:
  jpa:
    generateDdl: false
    hibernate:
      ddlAuto: update
    openInView: true
    show-sql: true
---
pagehelper:
  helperDialect: mysql
  reasonable: true
  pageSizeZero: true
  offsetAsPageNum: true
  rowBoundsWithCount: true
---
mybatis:
  type-aliases-package: com.pack.domain
  mapper-locations:
  - classpath:/mappers/*.xml
  configuration:
    lazy-loading-enabled: true
    aggressive-lazy-loading: false
---
logging:
  level:
    com.pack.mapper: debug

实体对象

@Entity
@Table(name = "BC_PERSON")
public class Person extends BaseEntity {
  private String name ;
  private String idNo ;
}

这里是用JPA来帮助我们生成数据表。

自定义类型转换器及数据加解密工具

public class EncryptTypeHandler implements TypeHandler<String> {
  @Override
  public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
    ps.setString(i, EncryptUtils.encrypt(parameter)) ;
  }
  @Override
  public String getResult(ResultSet rs, String columnName) throws SQLException {
    String value = rs.getString(columnName) ;
    if (value == null || value.length() == 0) {
      return null ;
    }
    return EncryptUtils.decrypt(value);
  }

  @Override
  public String getResult(ResultSet rs, int columnIndex) throws SQLException {
    String value = rs.getString(columnIndex) ;
    if (value == null || value.length() == 0) {
      return null ;
    }
    return EncryptUtils.decrypt(value);
  }

  @Override
  public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
    String value = cs.getString(columnIndex) ;
    if (value == null || value.length() == 0) {
      return null ;
    }
    return EncryptUtils.decrypt(value);
  }
}

加解密工具类

public class EncryptUtils {
	
  private static final String secretKey = "1111222244445555" ;
  private static final String ALGORITHM  = "AES" ;
	
  public static String encrypt(String data) {
    try {
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding") ;
      cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secretKey.getBytes(), ALGORITHM)) ;
      return Hex.encode(cipher.doFinal(data.getBytes())) ;
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
      e.printStackTrace();
      return null ;
    }
  }
	
  public static String decrypt(String secretText) {
    try {
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding") ;
      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey.getBytes(), ALGORITHM)) ;
      return new String(cipher.doFinal(Hex.decode(secretText))) ;
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
      e.printStackTrace();
      return null ;
    }
  }
	
  private static class Hex {
		
    private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
		
    public static byte[] decode(CharSequence s) {
      int nChars = s.length();
      if (nChars % 2 != 0) {
        throw new IllegalArgumentException("16进制数据错误");
      }
      byte[] result = new byte[nChars / 2];
      for (int i = 0; i < nChars; i += 2) {
        int msb = Character.digit(s.charAt(i), 16);
        int lsb = Character.digit(s.charAt(i + 1), 16);
        if (msb < 0 || lsb < 0) {
          throw new IllegalArgumentException("Detected a Non-hex character at " + (i + 1) + " or " + (i + 2) + " position");
        }
        result[i / 2] = (byte) ((msb << 4) | lsb);
      }
      return result;
    }
		
    public static String encode(byte[] buf) {
      StringBuilder sb = new StringBuilder() ;
      for (int i = 0, leng = buf.length; i < leng; i++) {
        sb.append(HEX[(buf[i] & 0xF0) >>> 4]).append(HEX[buf[i] & 0x0F]) ;
      }
      return sb.toString() ;
    }
		
  }
	
}

Mapper及XML文件

@Mapper
public interface PersonMapper {
  List<Person> queryPersons() ;
	
  int insertPerson(Person person) ;
}
<mapper namespace="com.pack.mapper.PersonMapper">
	<resultMap type="com.pack.domain.Person" id="PersonMap">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		<result column="id_no" property="idNo" typeHandler="com.pack.mybatis.EncryptTypeHandler"/>
		<result column="create_time" property="createTime"/>
	</resultMap>
	<select id="queryPersons" resultMap="PersonMap">
		SELECT * FROM bc_person
	</select>
	<insert id="insertPerson" parameterType="com.pack.domain.Person">
		insert into bc_person (id, name, id_no, create_time) values (#{id}, #{name}, #{idNo, typeHandler=com.pack.mybatis.EncryptTypeHandler}, #{createTime})
	</insert>
</mapper>

查询数据时在resultMap中的result中配置typeHandler=”com.pack.mybatis.EncryptTypeHandler”,指明该列的类型转换。

在insert中对具体的列进行指明类型转换。

测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootComprehensiveApplicationTests {

  @Resource
  private PersonMapper personMapper ;
  @Test
  public void testInsertMapper() {
    com.pack.domain.Person person = new com.pack.domain.Person() ;
    person.setId("0001") ;
    person.setCreateTime(new Date()) ;
    person.setIdNo("111111") ;
    person.setName("中国") ;
    personMapper.insertPerson(person) ;
  }
  @Test
  public void testQueryUers() {
    System.out.println(personMapper.queryPersons()) ;
  }
}

SpringBoot整合MyBatis自定义类型转换实现数据加解密

 

插入数据时数据已经被我们自定义的类型转换器进行了加密处理。

SpringBoot整合MyBatis自定义类型转换实现数据加解密

 

查询数据进行了解密处理。

完毕!!!

创作不易,给个关注+转发如何?

SpringBoot整合MyBatis自定义类型转换实现数据加解密

 

SpringBoot整合MyBatis自定义类型转换实现数据加解密

 

SpringBoot整合MyBatis自定义类型转换实现数据加解密

 

SpringBoot整合MyBatis自定义类型转换实现数据加解密

SpringBoot整合MyBatis自定义类型转换实现数据加解密

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80037.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!