新聞中心
環(huán)境:springboot2.6.12 + MyBatis3.5.6 + MySQL

MyBatis是一種優(yōu)秀的持久層框架,它支持自定義類(lèi)型轉(zhuǎn)換和數(shù)據(jù)加密解密。通過(guò)自定義類(lèi)型轉(zhuǎn)換,你可以輕松地將數(shù)據(jù)庫(kù)中的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為Java對(duì)象中的數(shù)據(jù)類(lèi)型,以及將Java對(duì)象中的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為數(shù)據(jù)庫(kù)中的數(shù)據(jù)類(lèi)型。而數(shù)據(jù)加密解密則可以提高數(shù)據(jù)的安全性,保護(hù)敏感信息不被泄露。在MyBatis中,你可以使用類(lèi)型處理器(TypeHandler)來(lái)實(shí)現(xiàn)自定義類(lèi)型轉(zhuǎn)換,使用加密和解密算法來(lái)實(shí)現(xiàn)數(shù)據(jù)加密解密。
本案例使用自定義類(lèi)型轉(zhuǎn)換器對(duì)數(shù)據(jù)列進(jìn)行加解密
1. 依賴(lài)及相關(guān)配置
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
runtime
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.4
com.github.pagehelper
pagehelper-spring-boot-starter
1.3.0
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實(shí)體對(duì)象
@Entity
@Table(name = "BC_PERSON")
public class Person extends BaseEntity {
private String name ;
private String idNo ;
}這里是用JPA來(lái)幫助我們生成數(shù)據(jù)表。
2. 自定義類(lèi)型轉(zhuǎn)換器及數(shù)據(jù)加解密工具
public class EncryptTypeHandler implements TypeHandler {
@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);
}
} 加解密工具類(lèi)
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進(jìn)制數(shù)據(jù)錯(cuò)誤");
}
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 queryPersons() ;
int insertPerson(Person person) ;
}
insert into bc_person (id, name, id_no, create_time) values (#{id}, #{name}, #{idNo, typeHandler=com.pack.mybatis.EncryptTypeHandler}, #{createTime})
查詢(xún)數(shù)據(jù)時(shí)在resultMap中的result中配置typeHandler="com.pack.mybatis.EncryptTypeHandler",指明該列的類(lèi)型轉(zhuǎn)換。
在insert中對(duì)具體的列進(jìn)行指明類(lèi)型轉(zhuǎn)換。
3. 測(cè)試
@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("中國(guó)") ;
personMapper.insertPerson(person) ;
}
@Test
public void testQueryUers() {
System.out.println(personMapper.queryPersons()) ;
}
}圖片
插入數(shù)據(jù)時(shí)數(shù)據(jù)已經(jīng)被我們自定義的類(lèi)型轉(zhuǎn)換器進(jìn)行了加密處理。
圖片
查詢(xún)數(shù)據(jù)進(jìn)行了解密處理。
完畢?。。?/p>
本文題目:Mybatis自定義類(lèi)型轉(zhuǎn)換,數(shù)據(jù)加密解密全攻略【實(shí)戰(zhàn)】
轉(zhuǎn)載來(lái)于:http://fisionsoft.com.cn/article/dppgses.html


咨詢(xún)
建站咨詢(xún)
