decryptFields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), Encryption.class);
122 | if (!CollectionUtils.isEmpty(decryptFields)) {
123 | for (Field field : decryptFields) {
124 | Object ciphertextFieldValue = FieldUtils.readField(field, obj, true);
125 | if (null == ciphertextFieldValue) continue;
126 | String decrypt = this.deduceEncryptStrategy().decrypt(ciphertextFieldValue);
127 | FieldUtils.writeField(field, obj, decrypt, true);
128 | if (logger.isDebugEnabled()) {
129 | logger.debug("Decrypt field for '{}', Ciphertext: {}, Plaintext: {}", field.getName(), ciphertextFieldValue, decrypt);
130 | }
131 | }
132 | }
133 | }
134 | }
135 | if (proceed instanceof Map) {
136 | Map, ?> map = (Map, ?>) proceed;
137 | }
138 | return proceed;
139 | }
140 |
141 | /**
142 | * Deduce encrypt strategy client
143 | *
144 | * @return The instance of {@link EncryptStrategy}
145 | */
146 | public EncryptStrategy deduceEncryptStrategy() {
147 | return STRATEGY_CLIENTS.get(mybatisEncryptProperties.getEncryptType());
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-starter/src/test/java/io/github/weasleyj/mybatis/encrypt/core/DefaultAesEncryptStrategyImplTest.java:
--------------------------------------------------------------------------------
1 | package io.github.weasleyj.mybatis.encrypt.core;
2 |
3 | import io.github.weasleyj.mybatis.encrypt.config.MybatisEncryptProperties;
4 | import org.junit.jupiter.api.Test;
5 |
6 | class DefaultAesEncryptStrategyImplTest {
7 |
8 | static EncryptStrategy encryptStrategy = new DefaultAesEncryptStrategyImpl(
9 | new MybatisEncryptProperties.AesProperties()
10 | .setKey("Jidkdp1mWL1tRyK=")
11 | .setKeyIv("Jidkdp1mWL1jijK=")
12 | );
13 |
14 | String raw = "这是一个AES的加密解密测试!Abc123,!@#$%^&*()_+,!@#¥%%……&*()";
15 |
16 | @Test
17 | void testEncrypt() {
18 | System.out.println(encryptStrategy.encrypt(raw));
19 | }
20 |
21 | @Test
22 | void testDecrypt() {
23 | String encrypt = encryptStrategy.encrypt(raw);
24 | System.out.println(encryptStrategy.decrypt(encrypt));
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-starter/src/test/java/io/github/weasleyj/mybatis/encrypt/core/DefaultBase64EncryptStrategyImplTest.java:
--------------------------------------------------------------------------------
1 | package io.github.weasleyj.mybatis.encrypt.core;
2 |
3 | import org.apache.commons.codec.binary.Base64;
4 | import org.junit.jupiter.api.DisplayName;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.util.Assert;
7 | import org.springframework.util.Base64Utils;
8 |
9 | import java.nio.charset.StandardCharsets;
10 |
11 | class DefaultBase64EncryptStrategyImplTest {
12 |
13 | static EncryptStrategy encryptStrategy = new DefaultBase64EncryptStrategyImpl();
14 |
15 | String raw = "这是一个Base64的加密解密测试!Abc123,!@#$%^&*()_+,!@#¥%%……&*()";
16 |
17 | @Test
18 | void encrypt() {
19 | String encrypt = encryptStrategy.encrypt(raw);
20 | System.out.println("encrypt = " + encrypt);
21 | }
22 |
23 | @Test
24 | void decrypt() {
25 | String encrypt = encryptStrategy.encrypt(raw);
26 | String decrypt = encryptStrategy.decrypt(encrypt);
27 | System.out.println(decrypt);
28 | Assert.isTrue(raw.equals(decrypt), "解密后的明文由于原始内容一致");
29 | }
30 |
31 | public String encrypt(Object plaintext) {
32 | Assert.notNull(plaintext, "Plaintext cannot be null");
33 | return Base64Utils.encodeToString(String.valueOf(plaintext).getBytes(StandardCharsets.UTF_8));
34 | }
35 |
36 |
37 | public String decrypt(Object ciphertext) {
38 | Assert.notNull(ciphertext, "Ciphertext cannot be null");
39 | return new String(Base64Utils.decodeFromString(String.valueOf(ciphertext)), StandardCharsets.UTF_8);
40 | }
41 |
42 | @Test
43 | @DisplayName("encoded1 == encoded2")
44 | void func1() {
45 | String encoded1 = encrypt(raw);
46 | String encoded2 = Base64.encodeBase64String(raw.getBytes(StandardCharsets.UTF_8));
47 | Assert.isTrue(encoded1.equals(encoded2), "encoded1 == encoded2");
48 | }
49 |
50 | @Test
51 | @DisplayName("decoded1 == decoded2")
52 | void func2() {
53 | String encoded1 = encrypt(raw);
54 | String encoded2 = Base64.encodeBase64String(raw.getBytes(StandardCharsets.UTF_8));
55 | Assert.isTrue(encoded1.equals(encoded2), "encoded1 == encoded2");
56 |
57 | String decrypt1 = decrypt(encoded1);
58 | String decrypt2 = new String(Base64.decodeBase64(encoded2));
59 | Assert.isTrue(decrypt1.equals(decrypt2), "decrypt1 == decrypt2");
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/h2.mv.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/julxxy/mybatis-encrypt-spring-boot-parent/2b99ff3e855e48ffdbbafd111f18ad183db85e9a/mybatis-encrypt-spring-boot-tests/h2.mv.db
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.7.6
9 |
10 |
11 |
12 | com.example
13 | mybatis-encrypt-spring-boot-tests
14 | 1.0.0-SNAPSHOT
15 | mybatis-encrypt-spring-boot-tests
16 | mybatis-encrypt-spring-boot-tests
17 |
18 |
19 | 1.8
20 |
21 |
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-starter-validation
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-configuration-processor
34 | true
35 |
36 |
37 | org.projectlombok
38 | lombok
39 | true
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 |
49 | io.github.weasley-j
50 | mybatis-encrypt-spring-boot-starter
51 | 1.0.3
52 |
53 |
54 |
55 | io.github.weasley-j
56 | dtt-spring-boot-starter
57 | 1.3.9
58 |
59 |
60 | com.github.therapi
61 | therapi-runtime-javadoc-scribe
62 | 0.15.0
63 | provided
64 |
65 |
66 |
67 |
68 | com.baomidou
69 | mybatis-plus-boot-starter
70 | 3.5.2
71 |
72 |
73 |
74 |
75 | org.mybatis.spring.boot
76 | mybatis-spring-boot-starter
77 | 3.0.0
78 |
79 |
80 |
81 |
82 | com.github.pagehelper
83 | pagehelper-spring-boot-starter
84 | 1.4.6
85 |
86 |
87 |
88 |
89 | tk.mybatis
90 | mapper-spring-boot-starter
91 | 4.2.2
92 |
93 |
94 |
95 |
96 | com.oracle.database.jdbc
97 | ojdbc8
98 | runtime
99 |
100 |
101 |
102 | mysql
103 | mysql-connector-java
104 | 8.0.30
105 | runtime
106 |
107 |
108 | com.h2database
109 | h2
110 | runtime
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | org.springframework.boot
120 | spring-boot-maven-plugin
121 |
122 |
123 |
124 | org.projectlombok
125 | lombok
126 |
127 |
128 |
129 |
130 |
131 | org.apache.maven.plugins
132 | maven-surefire-plugin
133 |
134 | true
135 |
136 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/MybatisEncryptTestsApp.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import cn.alphahub.dtt.plus.framework.annotations.EnableDtt;
4 | import io.github.weasleyj.mybatis.encrypt.annotation.EnableMybatisEncryption;
5 | import org.springframework.boot.SpringApplication;
6 | import org.springframework.boot.autoconfigure.SpringBootApplication;
7 |
8 | /**
9 | * Mybatis encrypt main class of Tests
10 | */
11 |
12 | @EnableDtt(scanBasePackages = {"com.example.demain"})
13 | @SpringBootApplication
14 | @EnableMybatisEncryption
15 | public class MybatisEncryptTestsApp {
16 |
17 | public static void main(String[] args) {
18 | SpringApplication.run(MybatisEncryptTestsApp.class, args);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/common/config/Jackson2ObjectMapperConfig.java:
--------------------------------------------------------------------------------
1 | package com.example.common.config;
2 |
3 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
4 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
6 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
7 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
9 | import org.springframework.beans.factory.annotation.Value;
10 | import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 |
14 | import java.time.LocalDate;
15 | import java.time.LocalDateTime;
16 | import java.time.LocalTime;
17 | import java.time.format.DateTimeFormatter;
18 | import java.util.TimeZone;
19 |
20 | /**
21 | * Spring Boot中LocalDateTime日期格式处理
22 | *
23 | * @author liuwenjing
24 | */
25 | @Configuration
26 | public class Jackson2ObjectMapperConfig {
27 | /**
28 | * 日期时间格式,没有在yml里面配置默认采用: yyyy-MM-dd HH:mm:ss
29 | */
30 | @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
31 | private String pattern;
32 | /**
33 | * 时区,没有在yml里面配置默认采用: GMT+8
34 | */
35 | @Value("${spring.jackson.time-zone:GMT+8}")
36 | private String timeZone;
37 |
38 | /**
39 | * @return Jackson2ObjectMapperBuilderCustomizer
40 | */
41 | @Bean
42 | public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
43 | return builder -> {
44 | builder.serializerByType(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
45 | builder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
46 | builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern)));
47 |
48 | builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
49 | builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
50 | builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern)));
51 |
52 | builder.simpleDateFormat(pattern);
53 | builder.timeZone(TimeZone.getTimeZone(timeZone));
54 | };
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/common/page/PageHandler.java:
--------------------------------------------------------------------------------
1 | package com.example.common.page;
2 |
3 | import com.github.pagehelper.Page;
4 |
5 | import java.util.List;
6 | import java.util.Objects;
7 |
8 | /**
9 | * 分页工具类
10 | *
11 | * 分页示例
12 | *
13 | * import cn.com.winning.common.basic.share.domain.ApiHisLog;
14 | * import cn.com.winning.common.basic.share.service.ApiHisLogService;
15 | * import cn.com.winning.common.entity.PageParam;
16 | * import cn.com.winning.common.page.PageHandler;
17 | * import cn.com.winning.common.page.PageWrapper;
18 | * import cn.hutool.json.JSONUtil;
19 | * import com.github.pagehelper.Page;
20 | * import com.github.pagehelper.page.PageMethod;
21 | * import lombok.extern.slf4j.Slf4j;
22 | * import org.springframework.beans.factory.annotation.Autowired;
23 | * import org.springframework.stereotype.Service;
24 | *
25 | * import java.util.List;
26 | *
27 | * {@code @Slf4j}
28 | * {@code @Service}
29 | * public class HisLogPageDemoService {
30 | *
31 | * {@code @Autowired}
32 | * private ApiHisLogService apiHisLogService;
33 | *
34 | * public PageWrapper{@code } pages(PageParam pageParam) {
35 | * log.info("分页入参 {}", JSONUtil.toJsonPrettyStr(pageParam));
36 | * Page{@code } page = PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
37 | * List{@code } apiHisLogs = apiHisLogService.list();
38 | * PageWrapper{@code } render = PageHandler.render(page, apiHisLogs);
39 | * log.info("分页数据 {}", JSONUtil.toJsonPrettyStr(render));
40 | * return render;
41 | * }
42 | * }
43 | *
44 | */
45 | public final class PageHandler {
46 |
47 | private PageHandler() {
48 | }
49 |
50 | public static PageWrapper render(Page page, List list) {
51 | PageWrapper pageWrapper = new PageWrapper<>();
52 | if (null != page) {
53 | pageWrapper.setPageNum(page.getPageNum());
54 | pageWrapper.setPageSize(page.getPageSize());
55 | pageWrapper.setTotal(page.getTotal());
56 | pageWrapper.setPages(page.getPages());
57 | pageWrapper.setList(list);
58 | }
59 | return pageWrapper;
60 | }
61 |
62 | public static PageWrapper render(int pageNum, int pageSize, long total, List list) {
63 | PageWrapper pageWrapper = new PageWrapper<>();
64 | pageWrapper.setPageNum(pageNum);
65 | pageWrapper.setPageSize(pageSize);
66 | pageWrapper.setTotal(total);
67 | if (pageSize > 0) {
68 | pageWrapper.setPages((int) (total / (long) pageSize + (long) (total % (long) pageSize == 0L ? 0 : 1)));
69 | } else {
70 | pageWrapper.setPages(0);
71 | }
72 |
73 | pageWrapper.setList(list);
74 | return pageWrapper;
75 | }
76 |
77 | public static , T> R render(Page page, List list, R result) {
78 | if (Objects.nonNull(page)) {
79 | result.setPageNum(page.getPageNum());
80 | result.setPageSize(page.getPageSize());
81 | result.setTotal(page.getTotal());
82 | result.setPages(page.getPages());
83 | result.setList(list);
84 | }
85 | return result;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/common/page/PageWrapper.java:
--------------------------------------------------------------------------------
1 | package com.example.common.page;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.io.Serializable;
8 | import java.util.List;
9 |
10 | /**
11 | * 分页返回对象
12 | *
13 | * @author weasley
14 | * @version 1.0
15 | * @date 2022/6/29
16 | */
17 | @Data
18 | @AllArgsConstructor
19 | @NoArgsConstructor
20 | public class PageWrapper implements Serializable {
21 | /**
22 | * 当前页码
23 | */
24 | private int pageNum;
25 | /**
26 | * 页大小
27 | */
28 | private int pageSize;
29 | /**
30 | * 总记录数
31 | */
32 | private long total;
33 | /**
34 | * 总页数
35 | */
36 | private int pages;
37 | /**
38 | * 列表实体数据
39 | */
40 | private List list;
41 |
42 | /**
43 | * 获取空的初始化
44 | *
45 | * @param pageNum
46 | * @param pageSize
47 | * @param
48 | * @return
49 | */
50 | public static PageWrapper instance(int pageNum, int pageSize) {
51 | PageWrapper wrapper = new PageWrapper<>();
52 | wrapper.setPageSize(pageSize);
53 | wrapper.setPageNum(pageNum);
54 | return wrapper;
55 | }
56 |
57 | /**
58 | * 判断当前页是否还有数据,用于优化减少查询list
59 | *
60 | * @return
61 | */
62 | public boolean hadData() {
63 | return (long) (pageNum - 1) * pageSize < total;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/controller/MemberController.java:
--------------------------------------------------------------------------------
1 | package com.example.controller;
2 |
3 | import cn.alphahub.dtt.plus.util.JacksonUtil;
4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 | import com.baomidou.mybatisplus.core.toolkit.Wrappers;
6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
7 | import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
8 | import com.example.common.page.PageHandler;
9 | import com.example.common.page.PageWrapper;
10 | import com.example.demain.DttMember;
11 | import com.example.service.MemberService;
12 | import com.github.pagehelper.page.PageMethod;
13 | import io.github.weasleyj.mybatis.encrypt.config.MybatisEncryptProperties;
14 | import io.github.weasleyj.mybatis.encrypt.core.EncryptStrategy;
15 | import lombok.extern.slf4j.Slf4j;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.http.ResponseEntity;
18 | import org.springframework.transaction.annotation.Transactional;
19 | import org.springframework.validation.annotation.Validated;
20 | import org.springframework.web.bind.annotation.*;
21 |
22 | import java.time.LocalDate;
23 | import java.time.LocalDateTime;
24 | import java.time.LocalTime;
25 | import java.util.Arrays;
26 | import java.util.List;
27 |
28 | /**
29 | * 用户信息
30 | *
31 | * @author Weasley
32 | */
33 | @Slf4j
34 | @RestController
35 | @RequestMapping("/api/member")
36 | public class MemberController {
37 |
38 | @Autowired
39 | private MemberService memberService;
40 | @Autowired
41 | private MybatisEncryptProperties mybatisEncryptProperties;
42 |
43 | /**
44 | * 用户信息分页查询(Pagehelper写法)
45 | *
46 | * @param member 用户信息查询参数
47 | * @param pageNum 前页码, 默认: 1
48 | * @param pageSize 每页显示条数,默认: 10
49 | * @return 用户信息分页数据
50 | * @apiNote 请求示例: 请求示例
51 | * @see 多数据源分页推荐使用pagehelper
52 | * @see pagehelper多数据源分页配置
53 | * @see PageWrapper类源码
54 | * @see PageHandler类源码
55 | */
56 | @GetMapping("/page/pagehelper")
57 | public ResponseEntity> pageByPagehelper(@RequestParam(value = "pageNum", required = false, defaultValue = "1") int pageNum,
58 | @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize,
59 | @ModelAttribute(value = "member", binding = true) DttMember member) {
60 | com.github.pagehelper.Page page = PageMethod.startPage(pageNum, pageSize);
61 | List pageResults = memberService.list(Wrappers.lambdaQuery(member));
62 | return ResponseEntity.ok(PageHandler.render(page, pageResults));
63 | }
64 |
65 | /**
66 | * 用户信息分页查询(Mybatis-Plus写法)
67 | *
68 | * @param pageParam 分页参数: current(当前页码,默认1), size(每页显示条数,默认10)
69 | * @param member 用户信息查询参数
70 | * @return 用户信息分页数据
71 | * @apiNote 请求示例: 请求示例
72 | * @see Mybatis Plus官方分页插件配置示例
73 | * @see 多数据源分页推荐使用pagehelper
74 | */
75 | @GetMapping("/page/mmp")
76 | public ResponseEntity> pageByMmp(@ModelAttribute("pageParam") PageDTO pageParam, @ModelAttribute("member") DttMember member) {
77 | Page params = new Page<>();
78 | params.setSize(pageParam.getSize());
79 | params.setCurrent(pageParam.getCurrent());
80 | Page page = memberService.page(params, Wrappers.lambdaQuery(member));
81 | return ResponseEntity.ok(page);
82 | }
83 |
84 | /**
85 | * Use encrypted fields as query criteria
86 | */
87 | @GetMapping("/lis/encrypted/fields")
88 | public ResponseEntity> selectByEncryptedFields(@ModelAttribute("member") DttMember member) {
89 | log.info("{}", JacksonUtil.toPrettyJson(member));
90 | DttMember dttMember = EncryptStrategy.convert(member, mybatisEncryptProperties.getEncryptType());
91 | log.info("EncryptStrategy.convert {}", JacksonUtil.toPrettyJson(dttMember));
92 | List members = this.memberService.list(Wrappers.lambdaQuery(DttMember.class)
93 | .eq(DttMember::getNickname, dttMember.getNickname()));
94 | return ResponseEntity.ok(members);
95 | }
96 |
97 | /**
98 | * 获取用户信息详情
99 | *
100 | * @param memberId 用户信息主键id
101 | * @return 用户信息详细信息
102 | */
103 | @GetMapping("/info/{memberId}")
104 | public ResponseEntity info(@PathVariable("memberId") Long memberId) {
105 | DttMember member = memberService.getById(memberId);
106 | return ResponseEntity.ok(member);
107 | }
108 |
109 | /**
110 | * 新增用户信息
111 | *
112 | * @param member 用户信息元数据
113 | * @return 成功返回true, 失败返回false
114 | */
115 | @PostMapping("/save")
116 | @Transactional(rollbackFor = {Exception.class})
117 | public ResponseEntity save(@RequestBody @Validated DttMember member) {
118 | boolean save = memberService.save(member);
119 | return ResponseEntity.ok(save);
120 | }
121 |
122 | /**
123 | * 新增用户信息
124 | *
125 | * @return 成功返回true, 失败返回false
126 | */
127 | @PostMapping("/save/direct")
128 | @Transactional(rollbackFor = {Exception.class})
129 | public ResponseEntity saveNoParams() {
130 | String json = "{\n" +
131 | " \"openId\": \"fawezOE5sT\",\n" +
132 | " \"nickname\": \"蒋震南\",\n" +
133 | " \"isEnable\": true,\n" +
134 | " \"balance\": 865,\n" +
135 | " \"birthday\": \"2022-08-19 22:18:51\",\n" +
136 | " \"status\": 0,\n" +
137 | " \"deleted\": 1\n" +
138 | "}";
139 | DttMember member = JacksonUtil.readValue(json, DttMember.class);
140 | member.setBirthday(LocalDateTime.now());
141 | member.setRegistrarDate(LocalDate.now());
142 | member.setUpdateTime(LocalDateTime.now());
143 | member.setAccelerateBeginTime(LocalTime.now());
144 | member.setAccelerateEndTime(LocalTime.now());
145 | DttMember dttMember = memberService.getOne(new QueryWrapper().select("MAX(member_id) memberId"));
146 | if (null != dttMember) {
147 | member.setMemberId(dttMember.getMemberId() + 1);
148 | } else member.setMemberId(1L);
149 | log.info("{}", JacksonUtil.toJson(member));
150 | boolean save = memberService.save(member);
151 | return ResponseEntity.ok(save);
152 | }
153 |
154 | /**
155 | * 修改用户信息
156 | *
157 | * @param member 用户信息, 根据id选择性更新
158 | * @return 成功返回true, 失败返回false
159 | */
160 | @PutMapping("/update")
161 | @Transactional(rollbackFor = {Exception.class})
162 | public ResponseEntity update(@RequestBody @Validated DttMember member) {
163 | boolean update = memberService.updateById(member);
164 | return ResponseEntity.ok(update);
165 | }
166 |
167 | /**
168 | * 批量删除用户信息
169 | *
170 | * @param memberIds 用户信息id集合
171 | * @return 成功返回true, 失败返回false
172 | */
173 | @DeleteMapping("/delete/{memberIds}")
174 | @Transactional(rollbackFor = {Exception.class})
175 | public ResponseEntity delete(@PathVariable("memberIds") Long[] memberIds) {
176 | boolean delete = memberService.removeByIds(Arrays.asList(memberIds));
177 | return ResponseEntity.ok(delete);
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/demain/DttMember.java:
--------------------------------------------------------------------------------
1 | package com.example.demain;
2 |
3 | import com.baomidou.mybatisplus.annotation.TableId;
4 | import io.github.weasleyj.mybatis.encrypt.annotation.Encryption;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 | import lombok.experimental.Accessors;
10 |
11 | import java.io.Serializable;
12 | import java.math.BigDecimal;
13 | import java.time.LocalDate;
14 | import java.time.LocalDateTime;
15 | import java.time.LocalTime;
16 |
17 | /**
18 | * 用户信息
19 | */
20 | @Data
21 | @Builder
22 | @AllArgsConstructor
23 | @NoArgsConstructor
24 | @Accessors(chain = true)
25 | public class DttMember implements Serializable {
26 | /**
27 | * 主键id
28 | *
29 | * @primaryKey
30 | */
31 | @TableId
32 | private Long memberId;
33 | /**
34 | * 用户openId
35 | *
36 | * @defaultValue e1be63305
37 | * @length 16
38 | */
39 | private String openId;
40 | /**
41 | * 用户昵称
42 | *
43 | * @length 32
44 | */
45 | @Encryption
46 | private String nickname;
47 | /**
48 | * 是否启用, 默认:1
49 | *
50 | * @defaultValue true
51 | */
52 | private Boolean isEnable;
53 | /**
54 | * 用户积分余额, 默认:0.00
55 | *
56 | * @precision 10
57 | * @scale 4
58 | * @defaultValue 0.01
59 | */
60 | private BigDecimal balance;
61 | /**
62 | * 出生日期,格式:yyyy-MM-dd HH:mm:ss
63 | */
64 | private LocalDateTime birthday;
65 | /**
66 | * 用户状态;0 正常(默认),1 已冻结,2 账号已封,3 账号异常
67 | *
68 | * @defaultValue 3
69 | */
70 | private Integer status;
71 | /**
72 | * 账户注销状态;0 未注销(默认),1 已销户
73 | *
74 | * @defaultValue 1
75 | * @dbDataType SMALLINT
76 | */
77 | private Integer deleted;
78 | /**
79 | * 注册时间,格式: yyyy-MM-dd
80 | */
81 | private LocalDate registrarDate;
82 | /**
83 | * 会员加速开始时间, 格式:HH:mm:ss
84 | */
85 | private LocalTime accelerateBeginTime;
86 | /**
87 | * 会员加速结束时间, 格式:HH:mm:ss
88 | */
89 | private LocalTime accelerateEndTime;
90 | /**
91 | * 修改时间
92 | */
93 | private LocalDateTime updateTime;
94 | }
95 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/mapper/MemberMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.mapper;
2 |
3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper;
4 | import com.example.demain.DttMember;
5 | import org.apache.ibatis.annotations.Mapper;
6 |
7 | /**
8 | * The mybatis mapper interface of 用户信息
9 | */
10 | @Mapper
11 | public interface MemberMapper extends BaseMapper {
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/service/MemberService.java:
--------------------------------------------------------------------------------
1 | package com.example.service;
2 |
3 | import com.baomidou.mybatisplus.extension.service.IService;
4 | import com.example.demain.DttMember;
5 |
6 | /**
7 | * 用户信息Service接口
8 | */
9 | public interface MemberService extends IService {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/java/com/example/service/impl/MemberServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.service.impl;
2 |
3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
4 | import com.example.demain.DttMember;
5 | import com.example.mapper.MemberMapper;
6 | import com.example.service.MemberService;
7 | import org.springframework.stereotype.Service;
8 |
9 | /**
10 | * 用户信息Service实现
11 | */
12 | @Service
13 | public class MemberServiceImpl extends ServiceImpl implements MemberService {
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/resources/application-h2.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | #cn.alphahub.dtt.plus.framework.core.template.DefaultTemplateResolver: debug
4 | org.springframework.jdbc.core.JdbcTemplate: debug
5 | jdbc.sqltiming: debug
6 |
7 | spring:
8 | datasource:
9 | embedded-database-connection: h2
10 | driver-class-name: org.h2.Driver
11 | #url: jdbc:h2:mem:h2;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
12 | url: jdbc:h2:/Users/weasley/Development/IdeaProjects/mybatis-encrypt-spring-boot-parent/mybatis-encrypt-spring-boot-tests/h2;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
13 | username: ""
14 | password: ""
15 |
16 | h2:
17 | console:
18 | path: /h2
19 | enabled: true
20 | settings:
21 | web-allow-others: false
22 | web-admin-password: 123456
23 |
24 | mybatis-plus:
25 | mapper-locations: classpath:mapper/**/*Mapper.xml,mapper/**/*Dao.xml
26 | type-aliases-package: com.example.domain
27 | global-config:
28 | db-config:
29 | id-type: auto
30 | configuration:
31 | map-underscore-to-camel-case: true
32 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
33 |
34 |
35 | alphahub:
36 | dtt:
37 | show-sql: on
38 | all-in-one-table:
39 | enable: true
40 | filename: all_in_one.sql
41 | filepath: /Users/weasley/Downloads
42 | code-generator:
43 | is-enable: on
44 | include-controller: on
45 | include-interface: on
46 | override-exists: off
47 | remove-prefix: dtt
48 | base-classes:
49 | - com.example.demain.DttMember
50 | module-name: example
51 | module-package: com.example
52 | module-path: /Users/weasley/Development/IdeaProjects/mybatis-encrypt-spring-boot-parent/mybatis-encrypt-spring-boot-tests
53 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/resources/application-mysql.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | org.springframework.jdbc.core.JdbcTemplate: debug
4 | jdbc.sqltiming: debug
5 |
6 | spring:
7 | datasource:
8 | driver-class-name: com.mysql.cj.jdbc.Driver
9 | url: jdbc:mysql://192.168.31.23:3306/db_demo?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true&autoReconnect=true&allowMultiQueries=true
10 | username: root
11 | password: 123456
12 |
13 | mybatis-plus:
14 | mapper-locations: classpath:mapper/**/*Mapper.xml,mapper/**/*Dao.xml
15 | type-aliases-package: com.example.domain.dtt,com.example.domain.order
16 | global-config:
17 | db-config:
18 | id-type: auto
19 | configuration:
20 | map-underscore-to-camel-case: true
21 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
22 |
23 |
24 | # mybatis encryption configuration
25 | mybatis:
26 | encrypt:
27 | enable: on
28 | encrypt-type: aes
29 | aes:
30 | key: Jidkdp1mWL1tRyK=
31 | key-iv: Poikdp1mWL1jijK=
32 |
33 | alphahub:
34 | dtt:
35 | is-enable: on
36 | banner-mode: ON
37 | show-sql: off
38 | mybatis-orm-support:
39 | is-enable: on
40 | all-in-one-table:
41 | enable: true
42 | filename: AllInOne.sql
43 | filepath: /Users/weasley/Downloads
44 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/resources/application-oracle.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | #cn.alphahub.dtt.plus.framework.core.template.DefaultTemplateResolver: debug
4 | org.springframework.jdbc.core.JdbcTemplate: debug
5 | jdbc.sqltiming: debug
6 |
7 | spring:
8 | datasource:
9 | driver-class-name: oracle.jdbc.OracleDriver
10 | #driver-class-name: oracle.jdbc.driver.OracleDriver
11 | url: jdbc:oracle:thin:@//192.168.31.23:1521/lwj
12 | username: C##DTT
13 | password: 123456
14 |
15 | mybatis-plus:
16 | mapper-locations: classpath:mapper/**/*Mapper.xml,mapper/**/*Dao.xml
17 | type-aliases-package: com.example.domain.dtt,com.example.domain.order
18 | global-config:
19 | db-config:
20 | id-type: auto
21 | configuration:
22 | map-underscore-to-camel-case: true
23 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
24 |
25 |
26 | # mybatis encryption configuration
27 | mybatis:
28 | encrypt:
29 | enable: on
30 | encrypt-type: aes
31 | aes:
32 | key: Jidkdp1mWL1tRyK=
33 | key-iv: Poikdp1mWL1jijK=
34 |
35 | alphahub:
36 | dtt:
37 | show-sql: on
38 | all-in-one-table:
39 | enable: true
40 | filename: AllInOne.sql
41 | filepath: /Users/weasley/Downloads
42 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | io.github.weasleyj.mybatis.encrypt.interceptor.DefaultMybatisEncryptInterceptor: debug
4 |
5 | server:
6 | port: 8080
7 |
8 | spring:
9 | application:
10 | name: mybatis-encrypt-spring-boot-tests
11 |
12 | profiles:
13 | active: h2
14 |
15 | jackson:
16 | date-format: yyyy-MM-dd HH:mm:ss
17 | time-zone: GMT+8
18 | locale: zh_CN
19 |
20 | mvc:
21 | format:
22 | date-time: yyyy-MM-dd HH:mm:ss
23 | date: yyyy-MM-dd
24 | time: HH:mm:ss
25 |
26 | # mybatis encryption configuration
27 | mybatis:
28 | encrypt:
29 | enable: on
30 | encrypt-type: aes
31 | aes:
32 | key: Jidkdp1mWL1tRyK=
33 | key-iv: Poikdp1mWL1jijK=
34 |
35 | # PageHelper
36 | pagehelper:
37 | reasonable: true
38 | support-methods-arguments: true
39 | params: count=countSql
40 | auto-dialect: true
41 | auto-runtime-dialect: true
42 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/resources/mapper/example/MemberMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/main/resources/member.json:
--------------------------------------------------------------------------------
1 | {
2 | "pageNum": 1,
3 | "pageSize": 10,
4 | "total": 5,
5 | "pages": 1,
6 | "list": [
7 | {
8 | "memberId": 1,
9 | "openId": "fawezOE5sT",
10 | "nickname": "蒋震南",
11 | "isEnable": true,
12 | "balance": 865.0000,
13 | "birthday": "2022-12-20 01:58:00",
14 | "status": 0,
15 | "deleted": 1,
16 | "registrarDate": "2022-12-20",
17 | "accelerateBeginTime": "01:58:01",
18 | "accelerateEndTime": "01:58:01",
19 | "updateTime": "2022-12-20 01:58:00"
20 | },
21 | {
22 | "memberId": 2,
23 | "openId": "fawezOE5sT",
24 | "nickname": "蒋震南",
25 | "isEnable": true,
26 | "balance": 865.0000,
27 | "birthday": "2022-12-20 02:00:03",
28 | "status": 0,
29 | "deleted": 1,
30 | "registrarDate": "2022-12-20",
31 | "accelerateBeginTime": "02:00:03",
32 | "accelerateEndTime": "02:00:03",
33 | "updateTime": "2022-12-20 02:00:03"
34 | },
35 | {
36 | "memberId": 3,
37 | "openId": "fawezOE5sT",
38 | "nickname": "蒋震南",
39 | "isEnable": true,
40 | "balance": 865.0000,
41 | "birthday": "2022-12-20 02:00:04",
42 | "status": 0,
43 | "deleted": 1,
44 | "registrarDate": "2022-12-20",
45 | "accelerateBeginTime": "02:00:04",
46 | "accelerateEndTime": "02:00:04",
47 | "updateTime": "2022-12-20 02:00:04"
48 | },
49 | {
50 | "memberId": 4,
51 | "openId": "fawezOE5sT",
52 | "nickname": "蒋震南",
53 | "isEnable": true,
54 | "balance": 865.0000,
55 | "birthday": "2022-12-20 02:00:04",
56 | "status": 0,
57 | "deleted": 1,
58 | "registrarDate": "2022-12-20",
59 | "accelerateBeginTime": "02:00:05",
60 | "accelerateEndTime": "02:00:05",
61 | "updateTime": "2022-12-20 02:00:04"
62 | },
63 | {
64 | "memberId": 5,
65 | "openId": "fawezOE5sT",
66 | "nickname": "蒋震南",
67 | "isEnable": true,
68 | "balance": 865.0000,
69 | "birthday": "2022-12-20 02:00:06",
70 | "status": 0,
71 | "deleted": 1,
72 | "registrarDate": "2022-12-20",
73 | "accelerateBeginTime": "02:00:06",
74 | "accelerateEndTime": "02:00:06",
75 | "updateTime": "2022-12-20 02:00:06"
76 | }
77 | ]
78 | }
79 |
--------------------------------------------------------------------------------
/mybatis-encrypt-spring-boot-tests/src/test/java/com/example/EncryptionTestsAppTests.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import cn.alphahub.dtt.plus.util.JacksonUtil;
4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
5 | import com.baomidou.mybatisplus.core.toolkit.Wrappers;
6 | import com.example.common.page.PageWrapper;
7 | import com.example.demain.DttMember;
8 | import com.example.service.MemberService;
9 | import com.fasterxml.jackson.core.type.TypeReference;
10 | import io.github.weasleyj.mybatis.encrypt.config.MybatisEncryptProperties;
11 | import io.github.weasleyj.mybatis.encrypt.core.EncryptStrategy;
12 | import lombok.extern.slf4j.Slf4j;
13 | import org.apache.commons.io.IOUtils;
14 | import org.apache.commons.lang3.RandomStringUtils;
15 | import org.junit.jupiter.api.Test;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.boot.test.context.SpringBootTest;
18 | import org.springframework.util.Assert;
19 |
20 | import java.io.IOException;
21 | import java.nio.charset.StandardCharsets;
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | @Slf4j
26 | @SpringBootTest
27 | class EncryptionTestsAppTests {
28 |
29 | @Autowired
30 | private MemberService memberService;
31 | @Autowired
32 | private MybatisEncryptProperties mybatisEncryptProperties;
33 |
34 | @Test
35 | void contextLoads() {
36 | }
37 |
38 | @Test
39 | void testBatchInsert() throws IOException {
40 | String resource = IOUtils.resourceToString("member.json", StandardCharsets.UTF_8, Thread.currentThread().getContextClassLoader());
41 | PageWrapper pageWrapper = JacksonUtil.readValue(resource, new TypeReference>() {
42 | });
43 |
44 | List list = pageWrapper.getList();
45 | List insertList = new ArrayList<>();
46 | int i = 1000;
47 | Long id = null;
48 |
49 | DttMember one = memberService.getOne(new QueryWrapper().select("MAX(member_id) memberId"));
50 | if (null != one) {
51 | id = one.getMemberId();
52 | } else id = 1L;
53 |
54 | for (DttMember dttMember : list) {
55 | i += 1;
56 | id += 1;
57 | dttMember.setOpenId(RandomStringUtils.randomAlphanumeric(16));
58 | dttMember.setMemberId(id + 1);
59 | dttMember.setNickname(dttMember.getNickname() + i);
60 | insertList.add(dttMember);
61 | }
62 |
63 | boolean batch = memberService.saveBatch(insertList);
64 | Assert.isTrue(batch);
65 | }
66 |
67 | @Test
68 | void testUpdateSingle() {
69 | DttMember member = JacksonUtil.readValue("{\n" +
70 | " \"memberId\": 3,\n" +
71 | " \"openId\": \"fawezOE5sT\",\n" +
72 | " \"nickname\": \"蒋震南1001\",\n" +
73 | " \"isEnable\": true,\n" +
74 | " \"balance\": 865.0000,\n" +
75 | " \"birthday\": \"2022-12-20 01:58:00\",\n" +
76 | " \"status\": 0,\n" +
77 | " \"deleted\": 1,\n" +
78 | " \"registrarDate\": \"2022-12-20\",\n" +
79 | " \"accelerateBeginTime\": \"01:58:01\",\n" +
80 | " \"accelerateEndTime\": \"01:58:01\",\n" +
81 | " \"updateTime\": \"2022-12-20 01:58:00\"\n" +
82 | " }", DttMember.class);
83 | member.setOpenId(RandomStringUtils.randomAlphanumeric(16));
84 | boolean update = this.memberService.update(member, Wrappers.lambdaUpdate(DttMember.class)
85 | .eq(DttMember::getMemberId, 3)
86 | );
87 | Assert.isTrue(update, "update must be success");
88 |
89 | boolean update2 = this.memberService.update(null, Wrappers.lambdaUpdate(DttMember.class)
90 | .eq(DttMember::getMemberId, 3)
91 | .set(DttMember::getIsEnable, false)
92 | );
93 | Assert.isTrue(update2, "update must be success");
94 | }
95 |
96 |
97 | /**
98 | * Use an encrypted field to query for data
99 | */
100 | @Test
101 | void testSelectByEncryptedFields() {
102 | DttMember member = new DttMember().setNickname("蒋震南1005");
103 | log.info("before {}", JacksonUtil.toJson(member));
104 | DttMember dttMember = EncryptStrategy.convert(member, mybatisEncryptProperties.getEncryptType());
105 | log.info("after {}", JacksonUtil.toJson(member));
106 | List members = this.memberService.list(Wrappers.lambdaQuery(DttMember.class)
107 | .eq(DttMember::getNickname, dttMember.getNickname()));
108 | log.info("select by encrypt filed: {}", JacksonUtil.toJson(members));
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.7.6
9 |
10 |
11 |
12 | io.github.weasley-j
13 | mybatis-encrypt-spring-boot-parent
14 | 1.0.0
15 | mybatis-encrypt-spring-boot-parent
16 | mybatis-encrypt-spring-boot-parent
17 | pom
18 |
19 |
20 | mybatis-encrypt-spring-boot-starter
21 | mybatis-encrypt-spring-boot-tests
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------