MyBatis-Flex 是一个优雅的 MyBatis 增强框架,它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库,其内置的 QueryWrapper帮助我们极大的减少了 SQL 编写的工作的同时,减少出错的可能性。
官方文档连接:https://mybatis-flex.com/
1、轻量:除了 MyBatis,没有任何第三方依赖、没有任何拦截器,其原理是通过 SqlProvider 的方式实现的。同时,在执行的过程中,没有任何的 Sql 解析(Parse)轻运行。 这带来了几个好处:1、极高的性能;2、极易对代码进行跟踪和调试; 3、把控性更高。
2、灵活:支持 Entity 的增删改查、以及分页查询的同时,MyBatis-Flex 提供了 Db + Row 工具,可以无需实体类对数据库进行增删改查以及分页查询。 与此同时,MyBatis-Flex 内置的 QueryWrapper**^灵活** 可以轻易的帮助我们实现 多表查询、链接查询、子查询 等等常见的 SQL 场景。
3、强大:支持任意关系型数据库,还可以通过方言持续扩展,同时支持 多(复合)主键、逻辑删除、乐观锁配置、数据脱敏、数据审计、 数据填充 等等功能。
<dependencies>
<!-- mybatis-fiex代码生成器依赖-->
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-codegen</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<!-- for test only -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
spring:
datasource:
url: // 数据库连接
username: // 数据库账户
password: // 数据库密码
// 如果需要自己编写xml文件则添加该配置
mybatis-flex:
mapper-locations:
- classpath*:/mapper/*.xml
package com.example.mybatisflexdemo.utils;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* @author cyh
* 注意:由于 MyBatis-Flex 的 APT 功能会自动帮我们生成了 Mapper 的 Java 类,
* 如果我们在代码生成器中选择生成 Mapper, 则建议把 APT 的 Mapper 生成功能给关闭掉,
* 否则系统中会存在两份一样功能的 Mapper。
*/
public class CodeGenerationUtil {
public static void main(String[] args) {
//配置数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://47.120.7.89:7878/so-token-db?nullNamePatternMatchesAll=true&autoReconnect=true&useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true");
dataSource.setUsername("root");
dataSource.setPassword("cyh032101");
// 输入信息
// 根包名
//表前缀
//表名
Map<String, Object> map = scannerInfo();
String basePackage = map.get("basePackage").toString();
String preFixTable = map.get("preFixTable").toString();
String tableNames = map.get("tableNames").toString();
//创建配置内容,两种风格都可以。
GlobalConfig globalConfig = createGlobalConfigUseStyle1(basePackage, preFixTable, tableNames);
//通过 datasource 和 globalConfig 创建代码生成器
Generator generator = new Generator(dataSource, globalConfig);
//生成代码
generator.generate();
}
public static GlobalConfig createGlobalConfigUseStyle1(String basePackage, String prefixTable, String tableName) {
//创建配置内容
GlobalConfig globalConfig = new GlobalConfig();
//设置根包
globalConfig.setBasePackage(basePackage);
//设置表前缀和只生成哪些表
if (StrUtil.isNotBlank(prefixTable)) {
globalConfig.setTablePrefix(prefixTable);
}
// 输入表名则生成其中表,否则生成全部
if (StrUtil.isNotBlank(tableName)) {
String[] strings = tableName.split(",");
globalConfig.setGenerateTable(strings);
}
//设置生成 entity 并启用 Lombok
globalConfig.setEntityGenerateEnable(true);
globalConfig.setEntityWithLombok(true);
//设置生成 mapper
globalConfig.setMapperGenerateEnable(true);
// 设置生成controller
globalConfig.setControllerGenerateEnable(true);
// 设置生成Service
globalConfig.setServiceGenerateEnable(true);
globalConfig.setServiceImplGenerateEnable(true);
// //可以单独配置某个列
// ColumnConfig columnConfig = new ColumnConfig();
// columnConfig.setColumnName("tenant_id");
// columnConfig.setLarge(true);
// columnConfig.setVersion(true);
// globalConfig.setColumnConfig("tb_account", columnConfig);
// 生成APT
globalConfig.setTableDefGenerateEnable(true);
return globalConfig;
}
public static Map<String, Object> scannerInfo() {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入根包名称(回车结束):");
String basePackage = scanner.nextLine();
System.out.println("\n");
System.out.println("请输入表前缀(无前缀直接回车结束)");
String preFixTable = scanner.nextLine();
System.out.println("\n");
System.out.println("请输入要生成的表名(多表名以,(英文逗号隔开)输入完成回车结束)");
String tableName = scanner.nextLine();
Map<String, Object> params = new HashMap<>();
params.put("basePackage", basePackage);
params.put("preFixTable", preFixTable);
params.put("tableNames", tableName);
return params;
}
}
@Slf4j
@Configuration
public class MyBatisFlexConfiguration {
public MyBatisFlexConfiguration() {
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
AuditManager.setMessageCollector(auditMessage ->
log.info("{},{}ms", auditMessage.getFullSql()
, auditMessage.getElapsedTime())
);
}
}
public SaTokenInfo login(LoginDto params) {
QueryWrapper wrapper = QueryWrapper.create()
.select(USER_INFO.ID)
.where(USER_INFO.USERNAME.eq(params.getUsername()).and(USER_INFO.PASSWORD.eq(params.getPassword())));
Long uid = userInfoMapper.selectOneByQueryAs(wrapper, Long.class);
if (ObjUtil.isNull(uid)) {
throw new BaseException(500, "账号或者密码错误");
}
StpUtil.login(uid);
return StpUtil.getTokenInfo();
}
// USER_INFO 是通过代码生成器 生成APT
//globalConfig.setTableDefGenerateEnable(true);
// 自动生成的需要手动编码,以下类似
public List<Map<String, Object>> getUserPermissions() {
Long uid = Long.parseLong(StpUtil.getLoginId().toString());
if (ObjUtil.isNull(uid)) {
throw new BaseException(500, "登录信息获取失败,请刷新或重新登录");
}
QueryWrapper wrapper = QueryWrapper.create()
.select(PERMISSIONS_TREE.ALL_COLUMNS)
.select(META.ALL_COLUMNS)
.from(ROLE_USER)
.leftJoin(ROLE_PERMISSIONS)
.on(ROLE_USER.R_ID.eq(ROLE_PERMISSIONS.R_ID))
.leftJoin(PERMISSIONS_TREE)
.on(ROLE_PERMISSIONS.P_ID.eq(PERMISSIONS_TREE.ID))
.leftJoin(META)
.on(PERMISSIONS_TREE.META.eq(META.ID))
.where(ROLE_USER.U_ID.eq(uid));
List<PermissionMeta> metas = roleUserMapper.selectListByQueryAs(wrapper, PermissionMeta.class);
return menuTree.menuList(metas);
}
SQL语句
SELECT pt.id, pt.path, meta.*
FROM tb_role_user as rs
LEFT JOIN tb_role_permissions as rp
ON rs.r_id = rp.r_id
LEFT JOIN tb_permissions_tree as pt
ON rp.p_id = pt.id
LEFT JOIN tb_meta as meta
ON pt.meta = meta.id
WHERE rs.u_id = {uid}