中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

山西建設(shè)執(zhí)業(yè)注冊管理中心網(wǎng)站怎么推廣比較好

山西建設(shè)執(zhí)業(yè)注冊管理中心網(wǎng)站,怎么推廣比較好,如何建設(shè)購物網(wǎng)站,晉城 網(wǎng)站建設(shè)目錄1.場景介紹2.Maven依賴2.AESUtil.java 加解密工具類3.字段處理類4.修改 MyBatis Plus 查詢4.1 修改表對應(yīng)實(shí)體類4.2 修改加密字段對應(yīng)屬性4.3 修改 xml 使用 ResultMap4.4 修改 xml 中 el 表達(dá)式5.測試結(jié)果6.MyBatis Plus 缺陷補(bǔ)充:測試實(shí)例1 查詢測試1.1 查詢信…

目錄

    • 1.場景介紹
    • 2.Maven依賴
    • 2.AESUtil.java 加解密工具類
    • 3.字段處理類
    • 4.修改 MyBatis Plus 查詢
      • 4.1 修改表對應(yīng)實(shí)體類
      • 4.2 修改加密字段對應(yīng)屬性
      • 4.3 修改 xml 使用 ResultMap
      • 4.4 修改 xml 中 el 表達(dá)式
    • 5.測試結(jié)果
    • 6.MyBatis Plus 缺陷
    • 補(bǔ)充:測試實(shí)例
      • 1 查詢測試
        • 1.1 查詢信息,SQL實(shí)現(xiàn)
        • 1.2 查詢信息,QueryWrapper實(shí)現(xiàn)
        • 1.3 查詢信息,根據(jù)加密字段查詢,SQL實(shí)現(xiàn)
        • 1.4 查詢信息,根據(jù)加密字段查詢,QueryWrapper實(shí)現(xiàn)
      • 2.測試更新
        • 2.1 更新信息,SQL實(shí)現(xiàn)
        • 2.2 更新信息,UpdateWrapper實(shí)現(xiàn)
        • 2.3 更新信息,LambdaUpdateWrapper實(shí)現(xiàn)
        • 2.4 更新信息,updateById實(shí)現(xiàn)
      • 3.測試插入
        • 7.3.1 插入信息,SQL實(shí)現(xiàn)
        • 3.2 插入信息,Service實(shí)現(xiàn)

1.場景介紹

  • 當(dāng)項(xiàng)目開發(fā)到一半,可能突然客戶會(huì)要求對數(shù)據(jù)庫里面比如手機(jī)號、身份證號的字段進(jìn)行加密;
  • 在保證開發(fā)最快、影響范圍最小的情況下,我們需要選擇一種介于數(shù)據(jù)庫和代碼之間的工具來幫我們實(shí)現(xiàn)自動(dòng)加解密;

2.Maven依賴

<!-- mybatis-plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version>
</dependency><!-- mybatis的分頁插件 -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.11</version><!-- pagehelper 包含該依賴存在版本沖突,因此不建議和 mp 一起混用 --><exclusions><exclusion><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId></exclusion></exclusions>
</dependency>

2.AESUtil.java 加解密工具類

這里我們選用AES對稱加密算法,因?yàn)樗强赡嫠惴ā?/p>

AES加密介紹: https://blog.csdn.net/qq_33204709/article/details/126930720

具體實(shí)現(xiàn)代碼如下:

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;/*** AES加密工具類** @author ACGkaka* @since 2021-06-18 19:11:03*/
public class AESUtil {/*** 日志相關(guān)*/private static final Logger LOGGER = LoggerFactory.getLogger(AESUtil.class);/*** 編碼*/private static final String ENCODING = "UTF-8";/*** 算法定義*/private static final String AES_ALGORITHM = "AES";/*** 指定填充方式*/private static final String CIPHER_PADDING = "AES/ECB/PKCS5Padding";private static final String CIPHER_CBC_PADDING = "AES/CBC/PKCS5Padding";/*** 偏移量(CBC中使用,增強(qiáng)加密算法強(qiáng)度)*/private static final String IV_SEED = "1234567812345678";/*** AES加密* @param content 待加密內(nèi)容* @param aesKey  密碼* @return*/public static String encrypt(String content, String aesKey){if(StringUtils.isBlank(content)){LOGGER.info("AES encrypt: the content is null!");return null;}//判斷秘鑰是否為16位if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){try {//對密碼進(jìn)行編碼byte[] bytes = aesKey.getBytes(ENCODING);//設(shè)置加密算法,生成秘鑰SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);// "算法/模式/補(bǔ)碼方式"Cipher cipher = Cipher.getInstance(CIPHER_PADDING);//選擇加密cipher.init(Cipher.ENCRYPT_MODE, skeySpec);//根據(jù)待加密內(nèi)容生成字節(jié)數(shù)組byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));//返回base64字符串return Base64Utils.encodeToString(encrypted);} catch (Exception e) {LOGGER.info("AES encrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES encrypt: the aesKey is null or error!");return null;}}/*** 解密* * @param content 待解密內(nèi)容* @param aesKey  密碼* @return*/public static String decrypt(String content, String aesKey){if(StringUtils.isBlank(content)){LOGGER.info("AES decrypt: the content is null!");return null;}//判斷秘鑰是否為16位if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){try {//對密碼進(jìn)行編碼byte[] bytes = aesKey.getBytes(ENCODING);//設(shè)置解密算法,生成秘鑰SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);// "算法/模式/補(bǔ)碼方式"Cipher cipher = Cipher.getInstance(CIPHER_PADDING);//選擇解密cipher.init(Cipher.DECRYPT_MODE, skeySpec);//先進(jìn)行Base64解碼byte[] decodeBase64 = Base64Utils.decodeFromString(content);//根據(jù)待解密內(nèi)容進(jìn)行解密byte[] decrypted = cipher.doFinal(decodeBase64);//將字節(jié)數(shù)組轉(zhuǎn)成字符串return new String(decrypted, ENCODING);} catch (Exception e) {LOGGER.info("AES decrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES decrypt: the aesKey is null or error!");return null;}}/*** AES_CBC加密* * @param content 待加密內(nèi)容* @param aesKey  密碼* @return*/public static String encryptCBC(String content, String aesKey){if(StringUtils.isBlank(content)){LOGGER.info("AES_CBC encrypt: the content is null!");return null;}//判斷秘鑰是否為16位if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){try {//對密碼進(jìn)行編碼byte[] bytes = aesKey.getBytes(ENCODING);//設(shè)置加密算法,生成秘鑰SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);// "算法/模式/補(bǔ)碼方式"Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);//偏移IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));//選擇加密cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);//根據(jù)待加密內(nèi)容生成字節(jié)數(shù)組byte[] encrypted = cipher.doFinal(content.getBytes(ENCODING));//返回base64字符串return Base64Utils.encodeToString(encrypted);} catch (Exception e) {LOGGER.info("AES_CBC encrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES_CBC encrypt: the aesKey is null or error!");return null;}}/*** AES_CBC解密* * @param content 待解密內(nèi)容* @param aesKey  密碼* @return*/public static String decryptCBC(String content, String aesKey){if(StringUtils.isBlank(content)){LOGGER.info("AES_CBC decrypt: the content is null!");return null;}//判斷秘鑰是否為16位if(StringUtils.isNotBlank(aesKey) && aesKey.length() == 16){try {//對密碼進(jìn)行編碼byte[] bytes = aesKey.getBytes(ENCODING);//設(shè)置解密算法,生成秘鑰SecretKeySpec skeySpec = new SecretKeySpec(bytes, AES_ALGORITHM);//偏移IvParameterSpec iv = new IvParameterSpec(IV_SEED.getBytes(ENCODING));// "算法/模式/補(bǔ)碼方式"Cipher cipher = Cipher.getInstance(CIPHER_CBC_PADDING);//選擇解密cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);//先進(jìn)行Base64解碼byte[] decodeBase64 = Base64Utils.decodeFromString(content);//根據(jù)待解密內(nèi)容進(jìn)行解密byte[] decrypted = cipher.doFinal(decodeBase64);//將字節(jié)數(shù)組轉(zhuǎn)成字符串return new String(decrypted, ENCODING);} catch (Exception e) {LOGGER.info("AES_CBC decrypt exception:" + e.getMessage());throw new RuntimeException(e);}}else {LOGGER.info("AES_CBC decrypt: the aesKey is null or error!");return null;}}public static void main(String[] args) {// AES支持三種長度的密鑰:128位、192位、256位。// 代碼中這種就是128位的加密密鑰,16字節(jié) * 8位/字節(jié) = 128位。String random = RandomStringUtils.random(16, "abcdefghijklmnopqrstuvwxyz1234567890");System.out.println("隨機(jī)key:" + random);System.out.println();System.out.println("---------加密---------");String aesResult = encrypt("測試AES加密12", random);System.out.println("aes加密結(jié)果:" + aesResult);System.out.println();System.out.println("---------解密---------");String decrypt = decrypt(aesResult, random);System.out.println("aes解密結(jié)果:" + decrypt);System.out.println();System.out.println("--------AES_CBC加密解密---------");String cbcResult = encryptCBC("測試AES加密12456", random);System.out.println("aes_cbc加密結(jié)果:" + cbcResult);System.out.println();System.out.println("---------解密CBC---------");String cbcDecrypt = decryptCBC(cbcResult, random);System.out.println("aes解密結(jié)果:" + cbcDecrypt);System.out.println();}
}

3.字段處理類

import com.demo.util.AESUtil;
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;/*** <p> @Title MyEncryptTypeHandler* <p> @Description 字段加密處理** @author ACGkaka* @date 2023/2/21 17:20*/
public class MyEncryptTypeHandler extends BaseTypeHandler<String> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, AESUtil.defaultEncrypt(parameter));}@Overridepublic String getNullableResult(ResultSet rs, String column) throws SQLException {return AESUtil.defaultDecrypt(rs.getString(column));}@Overridepublic String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return AESUtil.defaultDecrypt(rs.getString(columnIndex));}@Overridepublic String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return AESUtil.defaultDecrypt(cs.getString(columnIndex));}
}

4.修改 MyBatis Plus 查詢

4.1 修改表對應(yīng)實(shí)體類

設(shè)置 @TableName 注解的 autoResultMap 為 true,默認(rèn) false。

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;/*** 用戶表** @author ACGkaka* @date 2023/2/21 17:20*/
@Data
@TableName(value = "t_user_info", autoResultMap = true)
public class UserInfo implements Serializable {}

4.2 修改加密字段對應(yīng)屬性

設(shè)置 @TableField 注解的 typeHandlerMyEncryptTypeHandler.class

import com.demo.encrypt.MyEncryptTypeHandler;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;/*** 用戶表** @author ACGkaka* @date 2023/2/21 17:20*/
@Data
@TableName(value = "t_user_info", autoResultMap = true)
public class UserInfo implements Serializable {/*** 手機(jī)號碼*/@TableField(value = "PHONE", typeHandler = MyEncryptTypeHandler.class)private String phone;
}

4.3 修改 xml 使用 ResultMap

1)創(chuàng)建 ResultMap 映射,指定 typeHandler

2)查詢語句使用 ResultMap 返回。

<!-- 通用查詢映射結(jié)果 -->
<resultMap id="BaseResultMap" type="com.demo.model.UserInfo"><id column="ID" property="id" /><result column="ACCOUNT" property="staffCode" /><result column="PHONE" property="phone" typeHandler="com.demo.encrypt.MyEncryptTypeHandler" />
</resultMap><!-- 查詢?nèi)?-->
<select id="findAll" resultMap="BaseResultMap">SELECT * FROM t_user_info
</select>

4.4 修改 xml 中 el 表達(dá)式

設(shè)置好 4.1 和 4.2 就可以保證

修改前:

<!-- 更新手機(jī)號 -->
<update id="updatePhoneById">update t_user_info set phone = #{phone} where id = #{id}
</update><!-- 根據(jù)手機(jī)號查詢 -->
<select id="findByPhone" resultMap="BaseResultMap">SELECT * FROM t_user_info where phone = #{phone}
</select>

修改后:

<!-- 更新手機(jī)號 -->
<update id="updatePhoneById">update t_user_info set phone = #{phone, typeHandler=com.demo.encrypt.MyEncryptTypeHandler} where id = #{id}
</update><!-- 根據(jù)手機(jī)號查詢 -->
<select id="findByPhone" resultMap="BaseResultMap">SELECT * FROM t_user_info where phone = #{phone, typeHandler=com.demo.encrypt.MyEncryptTypeHandler}
</select>

5.測試結(jié)果

由于測試內(nèi)容較多,這里先直接展示測試結(jié)果,具體測試示例可以看 補(bǔ)充:測試實(shí)例

操作實(shí)現(xiàn)方式入?yún)?/th>測試結(jié)果
SELECT原生SQL非加密字段出參解密成功
SELECTQueryWrapper非加密字段出參解密成功
SELECT原生SQL加密字段入?yún)⒓用艹晒?/font>
SELECTQueryWrapper加密字段入?yún)⒓用苁?/font>
UPDATE原生SQL加密字段入?yún)⒓用艹晒?/font>
UPDATEUpdateWrapper加密字段入?yún)⒓用苁?/font>
UPDATELambdaUpdateWrapper加密字段入?yún)⒓用艹晒?/font>
UPDATEupdateById加密字段入?yún)⒓用艹晒?/font>
INSERTService加密字段入?yún)⒓用艹晒?/font>

說明:

  • 官方的解答是 QueryWrapper、UpdateWrapper 底層是通過 @Param 來實(shí)現(xiàn)的,目前沒有做到入?yún)⒅С?typeHandler,如果做的話會(huì)影響性能。

6.MyBatis Plus 缺陷

  • QueryWrapper 不支持入?yún)⒓用?#xff1b;

  • UpdateWrapper 不支持入?yún)⒓用?#xff1b;

  • 加密字段不支持模糊查詢。

補(bǔ)充:測試實(shí)例

1 查詢測試

1.1 查詢信息,SQL實(shí)現(xiàn)

@Test
public void getUserInfoTest1() {UserInfo userInfo = userInfoService.findByAccount("testAccount");System.out.println("userInfo:" + userInfo);System.out.println("phone:" + userInfo.getPhone());
}

測試結(jié)果:出參解密成功

1.2 查詢信息,QueryWrapper實(shí)現(xiàn)

@Test
public void getUserInfoTest2() {QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();wrapper.eq("account", "testAccount");List<UserInfo> users = userInfoService.list(wrapper);System.out.println("userInfo:" + users);System.out.println("phone:" + users.get(0).getPhone());
}

測試結(jié)果:出參解密成功

1.3 查詢信息,根據(jù)加密字段查詢,SQL實(shí)現(xiàn)

@Test
public void getUserInfoTest3() {UserInfo user = userInfoService.findByPhone("13888888888");System.out.println("userInfo:" + user);System.out.println("phone:" + user.getPhone());
}

(注意:入?yún)⑿枰褂胑l表達(dá)式指定 typeHandler)

測試結(jié)果:入?yún)⒓用艹晒?/font>

1.4 查詢信息,根據(jù)加密字段查詢,QueryWrapper實(shí)現(xiàn)

@Test
public void getUserInfoTest3() {QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();wrapper.lambda().eq(UserInfo::getPhone, "13888888888");List<UserInfo> users = userInfoService.list(wrapper);System.out.println("userInfo:" + users);System.out.println("phone:" + users.get(0).getPhone());
}

測試結(jié)果:入?yún)⒓用苁?#xff0c;QueryWrapper底層使用 @Param 實(shí)現(xiàn),無法像 SQL 實(shí)現(xiàn)一樣指定 typeHandler。

2.測試更新

2.1 更新信息,SQL實(shí)現(xiàn)

@Test
public void updateUserInfoTest1() {userInfoService.updatePhoneByAccount("testAccount", "13888888888");
}

測試結(jié)果:入?yún)⒓用艹晒?/font>

2.2 更新信息,UpdateWrapper實(shí)現(xiàn)

@Test
public void updateUserInfoTest2() {UpdateWrapper<UserInfo> wrapper = new UpdateWrapper<>();wrapper.set("phone", "13888888888");wrapper.eq("account", "testAccount");userInfoService.update(wrapper);getUserInfoTest1();
}

測試結(jié)果:入?yún)⒓用苁?#xff0c;UpdateWrapper底層使用 @Param 實(shí)現(xiàn),無法像 SQL 實(shí)現(xiàn)一樣指定 typeHandler。

2.3 更新信息,LambdaUpdateWrapper實(shí)現(xiàn)

@Test
public void updateUserInfoTest3() {LambdaUpdateWrapper<UserInfo> wrapper = Wrappers.<UserInfo>lambdaUpdate().set(UserInfo::getPhone, "13888888888", "typeHandler=com.demo.encrypt.MyEncryptTypeHandler");wrapper.eq(UserInfo::getAccount, "testAccount");userInfoService.update(wrapper);getUserInfoTest1();
}

測試結(jié)果:入?yún)⒓用艹晒?/font>

2.4 更新信息,updateById實(shí)現(xiàn)

@Test
public void updateUserInfoTest4() {UserInfo userInfo = userInfoService.findByAccount("testAccount");userInfo.setPhone("13888888888");userInfoService.updateById(userInfo);
}

測試結(jié)果:入?yún)⒓用艹晒?/font>

3.測試插入

7.3.1 插入信息,SQL實(shí)現(xiàn)

@Test
public void insertUserInfoTest1() {UserInfo userInfo = userInfoService.findByAccount("testAccount");userInfo.setAccount("testAccount_002");userInfo.setPhone("13888888888");userInfoService.save(userInfo);UserInfo newUserInfo = userInfoService.findByAccount("testAccount_002");System.out.println("userInfo:" + newUserInfo);System.out.println("phone:" + newUserInfo.getPhone());
}

測試結(jié)果:入?yún)⒓用艹晒?/font>

3.2 插入信息,Service實(shí)現(xiàn)

@Test
public void insertUserInfoTest1() {UserInfo userInfo = userInfoService.findByAccount("testAccount");userInfo.setAccount("testAccount_002");userInfo.setPhone("13888888888");userInfoService.save(userInfo);UserInfo newUserInfo = userInfoService.findByAccount("testAccount_002");System.out.println("userInfo:" + newUserInfo);System.out.println("phone:" + newUserInfo.getPhone());
}

測試結(jié)果:入?yún)⒓用艹晒?/font>

整理完畢,完結(jié)撒花~





參考地址:

1.mybaits plus 字段加密與解密,https://blog.csdn.net/qq_21134059/article/details/121752978

2.mybatis plus 官方問題頁面,https://github.com/baomidou/mybatis-plus/issues

3.更新時(shí)自定義的TypeHandler不生效,https://github.com/baomidou/mybatis-plus/issues/794

4.lambdaUpdate() 無法更新Json對象字段,https://github.com/baomidou/mybatis-plus/issues/5031

5.LambdaUpdateWrapper不支持自定義BaseTypeHandler,https://github.com/baomidou/mybatis-plus/issues/3317

http://www.risenshineclean.com/news/53100.html

相關(guān)文章:

  • 優(yōu)化公司流程制度百度seo關(guān)鍵詞排名 s
  • 旗袍網(wǎng)頁制作模板嘉興seo優(yōu)化
  • 網(wǎng)站建設(shè)方案 安全新媒體營銷成功案例
  • 手表網(wǎng)站有哪個(gè)比較好刷外鏈網(wǎng)站
  • WordPress的文本編輯器福建seo
  • 網(wǎng)站開發(fā)的開題任務(wù)書武漢搜索引擎排名優(yōu)化
  • 做紋身注冊什么網(wǎng)站好頭條新聞 最新消息條
  • 二級域名指向 獨(dú)立網(wǎng)站營銷型企業(yè)網(wǎng)站
  • 東莞網(wǎng)站哪家好鄭州粒米seo外包
  • 在線做logo的網(wǎng)站惡意點(diǎn)擊軟件哪幾種
  • 支付網(wǎng)站搭建業(yè)務(wù)推廣網(wǎng)站
  • 做網(wǎng)站前臺用什么軟件軟文營銷是什么
  • 上海建設(shè)網(wǎng)站浦東新區(qū)污水管網(wǎng)工程鄭州網(wǎng)站seo推廣
  • 日本插畫網(wǎng)站中國十大搜索引擎排名
  • 做網(wǎng)站在圖片里加文字流量平臺
  • 做傳奇網(wǎng)站報(bào)毒怎么處理bing搜索引擎入口
  • 用QQ群做網(wǎng)站排名現(xiàn)在最火的推廣平臺有哪些
  • 網(wǎng)站建設(shè)制作視頻長沙seo步驟
  • 做網(wǎng)站怎么每天更新內(nèi)容旺道優(yōu)化軟件
  • 福州做網(wǎng)站互聯(lián)網(wǎng)公司做百度推廣的公司電話號碼
  • 鄭州做網(wǎng)站的公司哪家專業(yè)seo網(wǎng)站
  • 做特賣的網(wǎng)站愛庫存seo診斷優(yōu)化方案
  • 企業(yè)做網(wǎng)站的流程深圳網(wǎng)絡(luò)營銷推廣渠道
  • 建筑人才網(wǎng)招聘官網(wǎng)登錄深圳seo優(yōu)化排名公司
  • 智能建站系統(tǒng)怎么更換網(wǎng)站模板東莞互聯(lián)網(wǎng)推廣
  • 手機(jī)版網(wǎng)站開發(fā)框架關(guān)鍵詞怎么找出來
  • 天津單位網(wǎng)站建設(shè)獲取排名
  • wordpress 性能分析凱里seo排名優(yōu)化
  • 新鄉(xiāng)河南網(wǎng)站建設(shè)頂尖文案
  • 山東mip網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷屬于哪個(gè)專業(yè)