# mybatis-plus-jpa-dicode
**Repository Path**: mybatis-plus-jpa/mybatis-plus-jpa-dicode
## Basic Information
- **Project Name**: mybatis-plus-jpa-dicode
- **Description**: mybatis-plus-jpa-dicode打破了传统意义上的低代码理念,实现了真正意义上的建表自动化和接口自动化,除定制场景外全程不需要写代码。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-07-16
- **Last Updated**: 2025-10-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 介绍
mybatis-plus-jpa-dicode打破了传统意义上的低代码理念,实现了真正意义上的建表自动化和接口自动化,除定制场景外全程不需要写代码。
## Maven引用[点击此处查看最新版本号](https://central.sonatype.com/artifact/com.xiaoyudeguang/mybatis-plus-jpa-dicode)
```xml
com.xiaoyudeguang
mybatis-plus-jpa-dicode
${最新版本}
```
也可访问[mybatis-plus-jpa-dicode-demo](https://gitee.com/mybatis-plus-jpa/mybatis-plus-jpa-dicode-demo)下载示例项目
## 添加配置
```
server:
port: 8080
spring:
main:
allow-bean-definition-overriding: true
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
username: ${MYSQL_USER:root}
password: ${MYSQL_PWD:123456}
url: jdbc:mysql://mysql-server:3306/${MYSQL_DB:demo}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
enable_lazy_load_no_trans: true
schema_update:
unique_constraint_strategy: RECREATE_QUIETLY
data:
redis:
database: 1
host: 127.0.0.1
port: 6379
password: 123456
timeout: 10s
lettuce:
pool:
max-active: 200
max-wait: -1ms
max-idle: 10
min-idle: 0
springdoc:
api-docs:
enabled: true
info:
title: ${pom.name}
description: ${pom.description}
version: ${pom.version}
contact:
name: 赵光
email: 1316851612@qq.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
groups:
enabled: true
group-configs:
- group: all
paths-to-match: /**/**
display-name: "全部接口"
paths-to-exclude: /internal/**
oauth2:
client-id: oauth-client-id
client-secret: oauth-client-secret
cache:
disabled: false
writer-with-default-pretty-printer: true
writer-with-order-by-keys: true
mybatis-plus:
type-handlers-package: com.xiaoyudeguang.handler
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
```
# 使用教程
## 自动建表
启动项目后,把下面的curl复制到postman或者直接在命令行执行,然后数据库里就有了一张名称为"sys_dept"的表。
```
curl --location --request GET 'http://127.0.0.1:8080/sysDept/getById/1'
```
"sys_dept"表的结构( **所有的数据都会存储在json字段中,所以等同于表字段是可以随意扩展的** ):

打开地址 [http://localhost:8080/doc.html],可以看到框架提供的公共接口下的11个接口,都是可以直接调用的(使用教程点击[更多](https://gitee.com/mybatis-plus-jpa/mybatis-plus-jpa-dicode/wikis/公共接口使用说明)查看):

## 定制场景
### 1. 假设已经按照上面的教程通过自动建表的方式创建了用户表(sys_user)和角色表(sys_role)和用户角色表(sys_user_role)三张表,我们要新写一个接口查询编码为"zhangsan"的用户有哪些角色,curl如下:
```
curl --location 'http://127.0.0.1:8080/user/roleList' \
--data '{
"userNo": "zhangsan"
}'
```
### 2. 代码实现:
#### 2.1 创建实体类
实体类模板
```
import com.baomidou.mybatisplus.annotation.TableName;
import com.xiaoyudeguang.annotation.JsonField;
import com.xiaoyudeguang.model.BaseModel;
import lombok.*;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("{表名}")
public class {实体类名} extends BaseModel<{实体类名}>{
}
```
#### 2.2 创建mapper接口
mybatisplus的[ActiveRecord模式](https://baomidou.com/guides/data-interface/#activerecord)要求必须创建实体类对应的mapper接口,如果不想手动创建,可以引入[mybatis-plus-apt-support](https://gitee.com/mybatis-plus-support/mybatis-plus-apt-support)来自动创建mapper接口
```
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.model.{实体类名};
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface {实体类名}Mapper extends BaseMapper<{实体类名}> {
}
```
#### 2.3 编写ServiceImpl(因为数据都会存在json字段中,所以此处用到了[mybatis-plus-json-support](https://gitee.com/mybatis-plus-support/mybatis-plus-json-support))
```
package com.example.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.xiaoyudeguang.dicode.service.impl.DiCodeServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class SysUserServiceImpl extends DiCodeServiceImpl {
public List roleList(String tableName, JsonNode request) throws Exception {
JsonLambdaQueryWrapper sysUserJsonWrapper = new JsonLambdaQueryWrapper<>();
sysUserJsonWrapper.json(SysUser::getJson).eq("userNo", request.findValue("userNo").asText());
SysUser sysUser = new SysUser().selectOne(sysUserJsonWrapper);
if (sysUser == null) {
throw new BusinessException("用户不存在");
}
JsonLambdaQueryWrapper sysUserRoleJsonWrapper = new JsonLambdaQueryWrapper<>();
sysUserRoleJsonWrapper.json(SysUserRole::getJson).in("roleNo", request.findValue("userNo").asText());
List sysUserRoleList = new SysUserRole().selectList(sysUserRoleJsonWrapper);
Set roleNoList = sysUserRoleList.stream().map(SysUserRole::getRoleNo).collect(Collectors.toSet());
if (sysUser == null) {
throw new BusinessException("用户没有关联角色");
}
JsonLambdaQueryWrapper sysRoleJsonWrapper = new JsonLambdaQueryWrapper<>();
sysRoleJsonWrapper.json(SysRole::getJson).in("roleNo", roleNoList);
new SysRole().selectList(sysRoleJsonWrapper);
return null;
}
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user")
public class SysUser extends BaseModel {
private static final long serialVersionUID = 1L;
@JsonField
private String roleNo;
@JsonField
private String userNo;
@JsonField
private String userNo;
@JsonField
private String userName;
@JsonField(exist = false)
private List roleList;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_role")
public class SysRole extends BaseModel {
private static final long serialVersionUID = 1L;
@JsonField
private String roleNo;
@JsonField
private String roleName;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_user_role")
public class SysUserRole extends BaseModel {
private static final long serialVersionUID = 1L;
@JsonField
private String roleNo;
@JsonField
private String userNo;
}
```
# 适配其他数据库(框架本身已支持下面3种)
## mysql
```java
@Bean
public TableSQLProvider tableSQLProvider() {
return new TableSQLProvider() {
@Override
public String getSql(String dataSourceType, String tableName) {
return """
CREATE TABLE `%s` (
`id` bigint NOT NULL PRIMARY KEY COMMENT '主键id',
`app_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '应用id',
`tenant_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '租户id',
`created` datetime DEFAULT NULL COMMENT '创建时间',
`creator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '创建人',
`modified` datetime DEFAULT NULL COMMENT '修改时间',
`modifier` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '修改人',
`status` bigint DEFAULT 0 COMMENT '状态',
`is_default` bigint DEFAULT 1 COMMENT '是否默认',
`json` json NOT NULL COMMENT '扩展字段',
`sort` int DEFAULT 100000 COMMENT '排序'
) ENGINE=InnoDB AUTO_INCREMENT=1
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_bin
COMMENT='%s'
ROW_FORMAT=DYNAMIC;
""".formatted(tableName, tableName);
}
};
}
```
## gaaus(高斯)
```
@Bean
public TableSQLProvider tableSQLProvider() {
return new TableSQLProvider() {
@Override
public String getSql(String dataSourceType, String tableName) {
return """
CREATE TABLE "%s" (
"id" BIGSERIAL PRIMARY KEY,
"app_id" VARCHAR(50) DEFAULT NULL,
"tenant_id" VARCHAR(50) DEFAULT NULL,
"created" TIMESTAMP DEFAULT NULL,
"creator" VARCHAR(50) DEFAULT NULL,
"modified" TIMESTAMP DEFAULT NULL,
"modifier" VARCHAR(50) DEFAULT NULL,
"status" BIGINT DEFAULT 0,
"is_default" BIGINT DEFAULT 1,
"json" JSONB NOT NULL,
"sort" INTEGER DEFAULT 100000
)
WITH (orientation=column, compression=middle);
COMMENT ON COLUMN "%s"."id" IS '主键id';
COMMENT ON COLUMN "%s"."app_id" IS '应用id';
COMMENT ON COLUMN "%s"."tenant_id" IS '租户id';
COMMENT ON COLUMN "%s"."created" IS '创建时间';
COMMENT ON COLUMN "%s"."creator" IS '创建人';
COMMENT ON COLUMN "%s"."modified" IS '修改时间';
COMMENT ON COLUMN "%s"."modifier" IS '修改人';
COMMENT ON COLUMN "%s"."status" IS '状态';
COMMENT ON COLUMN "%s"."is_default" IS '是否默认';
COMMENT ON COLUMN "%s"."json" IS '扩展字段';
COMMENT ON COLUMN "%s"."sort" IS '排序';
COMMENT ON TABLE "%s" IS '%s';
""".formatted(
tableName, tableName, tableName, tableName, tableName,
tableName, tableName, tableName, tableName, tableName,
tableName, tableName, tableName, tableName
);
}
};
}
```
## dm(达梦)
```
@Bean
public TableSQLProvider tableSQLProvider() {
return new TableSQLProvider() {
@Override
public String getSql(String dataSourceType, String tableName) {
return """
CREATE TABLE "%s" (
"ID" BIGINT NOT NULL IDENTITY(1,1) PRIMARY KEY,
"APP_ID" VARCHAR(50) DEFAULT NULL,
"TENANT_ID" VARCHAR(50) DEFAULT NULL,
"CREATED" DATETIME DEFAULT NULL,
"CREATOR" VARCHAR(50) DEFAULT NULL,
"MODIFIED" DATETIME DEFAULT NULL,
"MODIFIER" VARCHAR(50) DEFAULT NULL,
"STATUS" BIGINT DEFAULT 0,
"IS_DEFAULT" BIGINT DEFAULT 1,
"JSON" CLOB NOT NULL,
"SORT" INT DEFAULT 100000
);
COMMENT ON COLUMN "%s"."ID" IS '主键id';
COMMENT ON COLUMN "%s"."APP_ID" IS '应用id';
COMMENT ON COLUMN "%s"."TENANT_ID" IS '租户id';
COMMENT ON COLUMN "%s"."CREATED" IS '创建时间';
COMMENT ON COLUMN "%s"."CREATOR" IS '创建人';
COMMENT ON COLUMN "%s"."MODIFIED" IS '修改时间';
COMMENT ON COLUMN "%s"."MODIFIER" IS '修改人';
COMMENT ON COLUMN "%s"."STATUS" IS '状态';
COMMENT ON COLUMN "%s"."IS_DEFAULT" IS '是否默认';
COMMENT ON COLUMN "%s"."JSON" IS '扩展字段';
COMMENT ON COLUMN "%s"."SORT" IS '排序';
COMMENT ON TABLE "%s" IS '%s';
""".formatted(
tableName, tableName, tableName, tableName, tableName,
tableName, tableName, tableName, tableName, tableName,
tableName, tableName, tableName, tableName
);
}
};
}
```