RedisConfig:
package org.chengbing.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.time.Duration;
@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
/**
* 连接池的设置
*
* @return
*/
@Bean
public JedisPoolConfig getJedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
return jedisPoolConfig;
}
/**
* RedisTemplate
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
/**
* 缓存处理
* @param factory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
GeneratorTest (整合Mybatis-Plus):
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @author yuyongli
* @Date 2021/5/29
*/
public class GeneratorTest {
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir")+ File.separator+"";//
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("HaroldCI");
gc.setOpen(false);
gc.setSwagger2(true); //实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/cbrmarketplatform?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
//pc.setModuleName(scanner("模块名"));
pc.setParent("org.chengbing");
//pc.setXml("");
pc.setEntity("entity");//实体的包
pc.setMapper("dao");//dao的包
pc.setService("service");//service的包
pc.setServiceImpl("service.impl");//实现类的包
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
//不在java文件夹下面写入mapper文件
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
// 写于父类中的公共字段
// strategy.setSuperEntityColumns("id");
//strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.execute();
}
}
pom.xml:
# 商业转载请联系作者获得授权,非商业转载请注明出处。
# For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
# 协议(License):署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
# 作者(Author):Harold
# 链接(URL):http://cheng-bing.top/index.php/2022/01/01/spring%e9%a1%b9%e7%9b%ae%e5%b8%b8%e7%94%a8dependencies/
# 来源(Source):Chengbing Republic Embassy
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- 上传文件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- Encryption -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.56</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.1</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.2</version>
</dependency>
<!-- Swagger2 note -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!-- 认证 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.28.0</version>
</dependency>
</dependencies>
AESUtils (copyright@GuanHua Wang):
package org.chengbing.util;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
/**
* @author GuanHua Wang
* @ClassName: AESUtils
* @Description: aes对称加密解密工具类, 注意密钥不能随机生机, 不同客户端调用可能需要考虑不同Provider,
* 考虑安卓与IOS不同平台复杂度,简化不使用Provider
* @date 2019年1月15日16:00:39
*/
public class AESUtils {
/***默认向量常量**/
public static final String IV = "1234567890123456";
private final static Logger logger = LoggerFactory.getLogger(AESUtils.class);
/**
* 使用PKCS7Padding填充必须添加一个支持PKCS7Padding的Provider
* 类加载的时候就判断是否已经有支持256位的Provider,如果没有则添加进去
*/
static {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
/**
* 加密 128位
*
* @param content 需要加密的原内容
* @param pkey 密匙
* @return
*/
public static byte[] aesEncrypt(String content, String pkey) {
try {
//SecretKey secretKey = generateKey(pkey);
//byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec skey = new SecretKeySpec(pkey.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");// "算法/加密/填充"
IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, skey, iv);//初始化加密器
byte[] encrypted = cipher.doFinal(content.getBytes("UTF-8"));
return encrypted; // 加密
} catch (Exception e) {
logger.info("aesEncrypt() method error:", e);
}
return null;
}
/**
* 获得密钥
*
* @param secretKey
* @return
* @throws Exception
*/
private static SecretKey generateKey(String secretKey) throws Exception {
//防止linux下 随机生成key
Provider p = Security.getProvider("SUN");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", p);
secureRandom.setSeed(secretKey.getBytes());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(secureRandom);
// 生成密钥
return kg.generateKey();
}
/**
* @param content 加密前原内容
* @param pkey 长度为16个字符,128位
* @return base64EncodeStr aes加密完成后内容
* @throws
* @Title: aesEncryptStr
* @Description: aes对称加密
*/
public static String aesEncryptStr(String content, String pkey) {
byte[] aesEncrypt = aesEncrypt(content, pkey);
// System.out.println("加密后的byte数组:" + Arrays.toString(aesEncrypt));
String base64EncodeStr = Base64.encodeBase64String(aesEncrypt);
// System.out.println("加密后 base64EncodeStr:" + base64EncodeStr);
return base64EncodeStr;
}
/**
* @param content base64处理过的字符串
* @param pkey 密匙
* @return String 返回类型
* @throws Exception
* @throws
* @Title: aesDecodeStr
* @Description: 解密 失败将返回NULL
*/
public static String aesDecodeStr(String content, String pkey) throws Exception {
try {
//System.out.println("待解密内容:" + content);
byte[] base64DecodeStr = Base64.decodeBase64(content);
//System.out.println("base64DecodeStr:" + Arrays.toString(base64DecodeStr));
byte[] aesDecode = aesDecode(base64DecodeStr, pkey);
//System.out.println("aesDecode:" + Arrays.toString(aesDecode));
if (aesDecode == null) {
return null;
}
String result;
result = new String(aesDecode, "UTF-8");
//System.out.println("aesDecode result:" + result);
return result;
} catch (Exception e) {
System.out.println("Exception:" + e.getMessage());
throw new Exception("解密异常");
}
}
/**
* 解密 128位
*
* @param content 解密前的byte数组
* @param pkey 密匙
* @return result 解密后的byte数组
* @throws Exception
*/
public static byte[] aesDecode(byte[] content, String pkey) throws Exception {
//SecretKey secretKey = generateKey(pkey);
//byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec skey = new SecretKeySpec(pkey.getBytes(), "AES");
IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");// 创建密码器
cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化解密器
byte[] result = cipher.doFinal(content);
return result; // 解密
}
public static String getPkey()
{
return "ifyoucanhearthisvoice,youarealon";
}
public static void main(String[] args) throws Exception {
//明文
// String content = HaroldFile.readFile("resource.txt");
String content = "DLMDX720110";
//密匙
String pkey2 = "ifyoucanhearthisvoice,youarealon";
// Encrypted
String encryptedText = "CSDV08YGcBVAKNQh2DmHcg==";
System.out.println(aesDecodeStr(encryptedText, pkey2));
/*System.out.println("待加密报文:" + content);
System.out.println("密匙:" + pkey2);
String aesEncryptStr = aesEncryptStr(content, pkey2);
System.out.println("加密报文:" + aesEncryptStr);
String aesDecodeStr = aesDecodeStr(aesEncryptStr, pkey2);
System.out.println("解密报文:" + aesDecodeStr);
System.out.println("加解密前后内容是否相等:" + aesDecodeStr.equals(content));*/
}
}
Druid.properties:
driverClassName=com.mysql.jdbc.Driver
# url=jdbc:mysql://localhost:3306/qinlin_exchange?serverTimezone=Asia/Shanghai
url=jdbc:mysql://localhost:3306/xxxx?serverTimezone=Asia/Shanghai
# username=qinlin_exchange
username = root
password=root
initialSize=5
maxActive=50
maxWait=3000
application.properties:
server.port=8082
spring.application.name=cbrMarketPlatform
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cbrmarketplatform?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB
# Redis Database Index
spring.redis.database=15
# Redis Pass
spring.redis.password=harold
# Redis Host
spring.redis.host=192.168.129.131
spring.redis.port=6379
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
SecKillController:
package org.chengbing.other;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
@RestController
public class SecKillController {
@Resource
RedisTemplate redisTemplate;
@GetMapping("seckill")
public void secKill()
{
String uid = "CryoWolf" + ":" + UUID.randomUUID();
Jedis jedis = new Jedis("192.168.129.131", 6379);
jedis.select(15);
String storageKey = "storage:1";
jedis.watch(storageKey);
String s = jedis.get(storageKey);
if(s == null) {
System.out.println("The SecKill has not started yet! Thanks for your patient!");
return;
}
// if less or equal to zero : end
int num = Integer.parseInt(s);
if(num <= 0) {
System.out.println("Already Ended.");
return;
}
// If the storage is greater than zero : secKill
// Succeed: storage -1, record the user information using set
Boolean userKey = jedis.sismember("userkey", uid);
if(userKey) {
System.out.println("Already Operated");
return;
}else {
Transaction multi = jedis.multi();
multi.decr(storageKey);
multi.sadd("userkey", uid);
List<Object> exec = multi.exec();
if(exec == null || exec.size() == 0)
{
System.out.println("The Operation Failed.");
return;
}else
{
System.out.println("Succeed! The User Id is "+uid);
}
}
}
@GetMapping("seckill2")
public void secKill2() {
String uid = "CryoWolf_" + UUID.randomUUID();
SessionCallback sessionCallback = new SessionCallback() {
@Override
public Object execute(RedisOperations redisOperations) throws DataAccessException {
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.watch("storage:1");
Integer storage = (Integer) redisTemplate.opsForValue().get("storage:1");
if(storage == null) {
System.out.println("Hasn't been started yet");
return null;
}
if(storage <= 0) {
System.out.println("Empty Storage, Event Ended");
return null;
}
Boolean isMem = redisTemplate.opsForSet().isMember("userkey", uid);
if(isMem) {
System.out.println("Already Purchased");
return null;
}
redisOperations.multi();
redisOperations.opsForValue().decrement("storage:1");
redisOperations.opsForSet().add("userkey", uid);
List exec = redisOperations.exec();
return exec;
}
};
List execute = (List) redisTemplate.execute(sessionCallback);
if(execute == null || execute.size() == 0)
{
System.out.println("The Operation Failed.");
return;
}else
{
System.out.println("Succeed! The User Id is "+uid);
}
}
}
记得加
@ComponentScan("org.chengbing.dao")
CorsConfig:
package org.chengbing.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, GET");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
MybatisPlus Config
package org.chengbing.config;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: fun
* @Description: 分页拦截器
* @Date: 2020/9/10 10:26
* @Version: 1.0.0
*/@Configuration
public class MybatisPlusConfig {
/**
* 注入主键生成器 */ @Bean
public IKeyGenerator keyGenerator() {
return new H2KeyGenerator();
}
/**
* 分页插件 */ @Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
Mybatis Plus Pagination:
Page<Region> pageRegion = new Page<>(page + 1, rowsPerPage);
IPage<Region> regions = service.selectUserPage(pageRegion);
Integer totalPage = Math.toIntExact(regions.getPages());
return new ResultWithInfo<>(regions.getRecords(), 200, totalPage);
Comments | NOTHING