环境:springboot2.6.12 + MyBatis3.5.6 + MySQL
MyBatis是一种优秀的持久层框架,它支持自定义类型转换和数据加密解密。通过自定义类型转换,你可以轻松地将数据库中的数据类型转换为Java对象中的数据类型,以及将Java对象中的数据类型转换为数据库中的数据类型。而数据加密解密则可以提高数据的安全性,保护敏感信息不被泄露。在MyBatis中,你可以使用类型处理器(TypeHandler)来实现自定义类型转换,使用加密和解密算法来实现数据加密解密。
本案例使用自定义类型转换器对数据列进行加解密
<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></dependencies>
spring: datasource: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/testjpa?serverTimezone=GMT%2B8 username: root password: xxxxx 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() ; } }}
@Mapperpublic 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)@SpringBootTestpublic 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()) ; }}
图片
插入数据时数据已经被我们自定义的类型转换器进行了加密处理。
图片
查询数据进行了解密处理。
完毕!!!
本文链接:http://www.28at.com/showinfo-26-12115-0.htmlMybatis自定义类型转换,数据加密解密全攻略【实战】
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
下一篇: 尤雨溪:Vite 的现状与未来展望