mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
重构 TableInfo.buildResultMap
This commit is contained in:
parent
b67bd62a0e
commit
4cc7fdb4e7
@ -36,15 +36,16 @@ import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
|
||||
import org.apache.ibatis.executor.parameter.ParameterHandler;
|
||||
import org.apache.ibatis.executor.resultset.ResultSetHandler;
|
||||
import org.apache.ibatis.executor.statement.StatementHandler;
|
||||
import org.apache.ibatis.mapping.*;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.Environment;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.ResultMap;
|
||||
import org.apache.ibatis.session.*;
|
||||
import org.apache.ibatis.transaction.Transaction;
|
||||
import org.apache.ibatis.util.MapUtil;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -189,37 +190,11 @@ public class FlexConfiguration extends Configuration {
|
||||
|
||||
String resultMapId = tableInfo.getEntityClass().getName();
|
||||
|
||||
/*ResultMap resultMap;
|
||||
ResultMap resultMap;
|
||||
if (hasResultMap(resultMapId)) {
|
||||
resultMap = getResultMap(resultMapId);
|
||||
} else {
|
||||
resultMap = tableInfo.buildResultMap(this);
|
||||
this.addResultMap(resultMap);
|
||||
}*/
|
||||
|
||||
// 变量名与属性名区分开
|
||||
List<ResultMap> resultMapList;
|
||||
if (hasResultMap(resultMapId)) {
|
||||
resultMapList = new ArrayList<>();
|
||||
fillResultMapList(resultMapId, resultMapList);
|
||||
} else {
|
||||
resultMapList = tableInfo.buildResultMapList(this);
|
||||
for (ResultMap resultMap : resultMapList) {
|
||||
if (!hasResultMap(resultMap.getId())) {
|
||||
addResultMap(resultMap);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 这里解释一下为什么要反转这个集合:
|
||||
*
|
||||
* MyBatis 在解析 ResultMaps 的时候,是按照顺序一个一个进行解析的,对于有嵌套
|
||||
* 的 ResultMap 对象,也就是 nestResultMap 需要放在靠前的位置,首先解析。
|
||||
*
|
||||
* 而我们进行递归 buildResultMapList 是非嵌套 ResultMap 在集合最开始的位置,
|
||||
* 所以要反转一下集合,将 hasNestedResultMaps 的 ResultMap 对象放到集合的最
|
||||
* 前面。
|
||||
*/
|
||||
Collections.reverse(resultMapList);
|
||||
}
|
||||
|
||||
return new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), ms.getSqlSource(), ms.getSqlCommandType())
|
||||
@ -234,8 +209,7 @@ public class FlexConfiguration extends Configuration {
|
||||
.lang(ms.getLang())
|
||||
.resultOrdered(ms.isResultOrdered())
|
||||
.resultSets(ms.getResultSets() == null ? null : String.join(",", ms.getResultSets()))
|
||||
//.resultMaps(CollectionUtil.newArrayList(resultMap)) // 替换resultMap
|
||||
.resultMaps(resultMapList)
|
||||
.resultMaps(Collections.singletonList(resultMap))
|
||||
.resultSetType(ms.getResultSetType())
|
||||
.flushCacheRequired(ms.isFlushCacheRequired())
|
||||
.useCache(ms.isUseCache())
|
||||
@ -243,19 +217,6 @@ public class FlexConfiguration extends Configuration {
|
||||
.build();
|
||||
}
|
||||
|
||||
private void fillResultMapList(String resultMapId, List<ResultMap> resultMapList) {
|
||||
ResultMap resultMap = this.getResultMap(resultMapId);
|
||||
resultMapList.add(resultMap);
|
||||
if (resultMap.hasNestedResultMaps()) {
|
||||
for (ResultMapping resultMapping : resultMap.getResultMappings()) {
|
||||
String nestedResultMapId = resultMapping.getNestedResultMapId();
|
||||
if (nestedResultMapId != null) {
|
||||
fillResultMapList(nestedResultMapId, resultMapList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成新的、已替换主键生成器的 MappedStatement
|
||||
*
|
||||
|
||||
@ -706,80 +706,12 @@ public class TableInfo {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 该功能有更好的方式实现,此方法可能会被移除。
|
||||
*/
|
||||
@Deprecated
|
||||
|
||||
public ResultMap buildResultMap(Configuration configuration) {
|
||||
String resultMapId = entityClass.getName();
|
||||
List<ResultMapping> resultMappings = new ArrayList<>();
|
||||
|
||||
for (ColumnInfo columnInfo : columnInfoList) {
|
||||
ResultMapping mapping = new ResultMapping.Builder(configuration, columnInfo.property,
|
||||
columnInfo.column, columnInfo.propertyType)
|
||||
.jdbcType(columnInfo.getJdbcType())
|
||||
.typeHandler(columnInfo.buildTypeHandler())
|
||||
.build();
|
||||
resultMappings.add(mapping);
|
||||
|
||||
//add property mapper for sql: select xxx as property ...
|
||||
if (!Objects.equals(columnInfo.getColumn(), columnInfo.getProperty())) {
|
||||
ResultMapping propertyMapping = new ResultMapping.Builder(configuration, columnInfo.property,
|
||||
columnInfo.property, columnInfo.propertyType)
|
||||
.jdbcType(columnInfo.getJdbcType())
|
||||
.typeHandler(columnInfo.buildTypeHandler())
|
||||
.build();
|
||||
resultMappings.add(propertyMapping);
|
||||
if (configuration.hasResultMap(resultMapId)) {
|
||||
return configuration.getResultMap(resultMapId);
|
||||
}
|
||||
}
|
||||
|
||||
for (IdInfo idInfo : primaryKeyList) {
|
||||
ResultMapping mapping = new ResultMapping.Builder(configuration, idInfo.property,
|
||||
idInfo.column, idInfo.propertyType)
|
||||
.flags(CollectionUtil.newArrayList(ResultFlag.ID))
|
||||
.jdbcType(idInfo.getJdbcType())
|
||||
.typeHandler(idInfo.buildTypeHandler())
|
||||
.build();
|
||||
resultMappings.add(mapping);
|
||||
}
|
||||
|
||||
if (joinTypes != null && !joinTypes.isEmpty()) {
|
||||
joinTypes.forEach((fieldName, fieldType) -> {
|
||||
|
||||
TableInfo joinTableInfo = TableInfoFactory.ofEntityClass(fieldType);
|
||||
List<ColumnInfo> joinTableInfoColumnInfoList = joinTableInfo.getColumnInfoList();
|
||||
|
||||
for (ColumnInfo joinColumnInfo : joinTableInfoColumnInfoList) {
|
||||
if (!existColumn(resultMappings, joinColumnInfo.column)) {
|
||||
ResultMapping mapping = new ResultMapping.Builder(configuration, fieldName + "." + joinColumnInfo.property,
|
||||
joinColumnInfo.column, joinColumnInfo.propertyType)
|
||||
.jdbcType(joinColumnInfo.jdbcType)
|
||||
.typeHandler(joinColumnInfo.buildTypeHandler())
|
||||
.build();
|
||||
resultMappings.add(mapping);
|
||||
}
|
||||
|
||||
//add property mapper for sql: select xxx as property ...
|
||||
if (!existColumn(resultMappings, joinColumnInfo.property)) {
|
||||
if (!Objects.equals(joinColumnInfo.column, joinColumnInfo.property)) {
|
||||
ResultMapping propertyMapping = new ResultMapping.Builder(configuration, fieldName + "." + joinColumnInfo.property,
|
||||
joinColumnInfo.property, joinColumnInfo.propertyType)
|
||||
.jdbcType(joinColumnInfo.jdbcType)
|
||||
.typeHandler(joinColumnInfo.buildTypeHandler())
|
||||
.build();
|
||||
resultMappings.add(propertyMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return new ResultMap.Builder(configuration, resultMapId, entityClass, resultMappings).build();
|
||||
}
|
||||
|
||||
public List<ResultMap> buildResultMapList(Configuration configuration) {
|
||||
String resultMapId = entityClass.getName();
|
||||
List<ResultMap> resultMaps = new ArrayList<>();
|
||||
List<ResultMapping> resultMappings = new ArrayList<>();
|
||||
|
||||
// <resultMap> 标签下的 <result> 标签映射
|
||||
@ -819,19 +751,11 @@ public class TableInfo {
|
||||
// 获取嵌套类型的信息,也就是 javaType 属性
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(fieldType);
|
||||
// 构建嵌套类型的 ResultMap 对象,也就是 <association> 标签下的内容
|
||||
// 这里是递归调用,直到嵌套类型里面没有其他嵌套类型或者集合类型为止
|
||||
List<ResultMap> resultMapList = tableInfo.buildResultMapList(configuration);
|
||||
// 寻找是否有嵌套 ResultMap 引用
|
||||
Optional<ResultMap> nestedResultMap = resultMapList.stream()
|
||||
.filter(e -> fieldType.getName().equals(e.getId()))
|
||||
.findFirst();
|
||||
// 处理嵌套类型 ResultMapping 引用
|
||||
nestedResultMap.ifPresent(resultMap -> resultMappings.add(new ResultMapping.Builder(configuration, fieldName)
|
||||
ResultMap nestedResultMap = tableInfo.buildResultMap(configuration);
|
||||
resultMappings.add(new ResultMapping.Builder(configuration, fieldName)
|
||||
.javaType(fieldType)
|
||||
.nestedResultMapId(resultMap.getId())
|
||||
.build()));
|
||||
// 全部添加到 ResultMap 集合当中
|
||||
resultMaps.addAll(resultMapList);
|
||||
.nestedResultMapId(nestedResultMap.getId())
|
||||
.build());
|
||||
});
|
||||
}
|
||||
|
||||
@ -841,34 +765,17 @@ public class TableInfo {
|
||||
// 获取集合泛型类型的信息,也就是 ofType 属性
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(genericClass);
|
||||
// 构建嵌套类型的 ResultMap 对象,也就是 <collection> 标签下的内容
|
||||
// 这里是递归调用,直到集合类型里面没有其他嵌套类型或者集合类型为止
|
||||
List<ResultMap> resultMapList = tableInfo.buildResultMapList(configuration);
|
||||
// 寻找是否有嵌套 ResultMap 引用
|
||||
Optional<ResultMap> nestedResultMap = resultMapList.stream()
|
||||
.filter(e -> genericClass.getName().equals(e.getId()))
|
||||
.findFirst();
|
||||
// 处理嵌套类型 ResultMapping 引用
|
||||
nestedResultMap.ifPresent(resultMap -> resultMappings.add(new ResultMapping.Builder(configuration, field.getName())
|
||||
ResultMap nestedResultMap = tableInfo.buildResultMap(configuration);
|
||||
resultMappings.add(new ResultMapping.Builder(configuration, field.getName())
|
||||
.javaType(field.getType())
|
||||
.nestedResultMapId(resultMap.getId())
|
||||
.build()));
|
||||
// 全部添加到 ResultMap 集合当中
|
||||
resultMaps.addAll(resultMapList);
|
||||
.nestedResultMapId(nestedResultMap.getId())
|
||||
.build());
|
||||
});
|
||||
}
|
||||
|
||||
resultMaps.add(new ResultMap.Builder(configuration, resultMapId, entityClass, resultMappings).build());
|
||||
|
||||
return resultMaps;
|
||||
}
|
||||
|
||||
private static boolean existColumn(List<ResultMapping> resultMappings, String name) {
|
||||
for (ResultMapping resultMapping : resultMappings) {
|
||||
if (resultMapping.getColumn().equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
ResultMap resultMap = new ResultMap.Builder(configuration, resultMapId, entityClass, resultMappings).build();
|
||||
configuration.addResultMap(resultMap);
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.ColumnMask;
|
||||
import com.mybatisflex.core.handler.Fastjson2TypeHandler;
|
||||
import com.mybatisflex.core.mask.Masks;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountDTO {
|
||||
|
||||
|
||||
private Long id;
|
||||
|
||||
@ColumnMask(Masks.CHINESE_NAME)
|
||||
private String userName;
|
||||
|
||||
private int age;
|
||||
|
||||
@NotBlank
|
||||
private Date birthday;
|
||||
|
||||
@Column(typeHandler = Fastjson2TypeHandler.class, isLarge = true)
|
||||
private Map<String, Object> options;
|
||||
|
||||
@Column(isLogicDelete = true)
|
||||
private Boolean isDelete;
|
||||
|
||||
private List<Article> articles;
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
|
||||
public Date getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public void setBirthday(Date birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
|
||||
public Map<String, Object> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(Map<String, Object> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public void addOption(String key, Object value) {
|
||||
if (options == null) {
|
||||
options = new HashMap<>();
|
||||
}
|
||||
options.put(key, value);
|
||||
}
|
||||
|
||||
public Boolean getDelete() {
|
||||
return isDelete;
|
||||
}
|
||||
|
||||
public void setDelete(Boolean delete) {
|
||||
isDelete = delete;
|
||||
}
|
||||
|
||||
public List<Article> getArticles() {
|
||||
return articles;
|
||||
}
|
||||
|
||||
public void setArticles(List<Article> articles) {
|
||||
this.articles = articles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AccountDTO{" +
|
||||
"id=" + id +
|
||||
", userName='" + userName + '\'' +
|
||||
", age=" + age +
|
||||
", birthday=" + birthday +
|
||||
", options=" + options +
|
||||
", isDelete=" + isDelete +
|
||||
", articles=" + articles +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.audit.MessageCollector;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
|
||||
public class JoinTestStarter {
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataSource dataSource = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("schema.sql")
|
||||
.addScript("data.sql")
|
||||
.build();
|
||||
|
||||
MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance()
|
||||
.setDataSource(dataSource)
|
||||
.addMapper(AccountMapper.class)
|
||||
.addMapper(MyAccountMapper.class)
|
||||
.start();
|
||||
|
||||
//开启审计功能
|
||||
AuditManager.setAuditEnable(true);
|
||||
|
||||
//设置 SQL 审计收集器
|
||||
MessageCollector collector = new ConsoleMessageCollector();
|
||||
AuditManager.setMessageCollector(collector);
|
||||
|
||||
|
||||
AccountMapper accountMapper = bootstrap.getMapper(AccountMapper.class);
|
||||
|
||||
|
||||
// List<Account> accounts = accountMapper.selectListByQuery(QueryWrapper.create());
|
||||
// System.out.println(accounts);
|
||||
|
||||
List<AccountDTO> accountDTOS = accountMapper.selectListByQueryAs(QueryWrapper.create(),AccountDTO.class);
|
||||
System.out.println(accountDTOS);
|
||||
|
||||
//
|
||||
// List<ArticleDTO> articleDTOS = accountMapper.selectListByQueryAs(QueryWrapper.create(), ArticleDTO.class);
|
||||
// System.out.println(articleDTOS);
|
||||
//
|
||||
//
|
||||
// Page<ArticleDTO01> paginate = accountMapper.paginateAs(Page.of(1, 10), QueryWrapper.create(), ArticleDTO01.class);
|
||||
// System.out.println(paginate);
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,9 @@ spring:
|
||||
# enabled: true
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/mp_test
|
||||
url: jdbc:mysql://localhost:3306/flex_test
|
||||
username: root
|
||||
password: 12345678
|
||||
password: 123456
|
||||
# sql:
|
||||
# init:
|
||||
# schema-locations: classpath:schema.sql
|
||||
|
||||
@ -1,19 +1,3 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : MySQL3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80024
|
||||
Source Host : localhost:3306
|
||||
Source Schema : mp_test
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80024
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 08/06/2023 19:48:10
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
@ -24,12 +8,11 @@ DROP TABLE IF EXISTS `tb_good`;
|
||||
CREATE TABLE `tb_good`
|
||||
(
|
||||
`good_id` int NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
`name` varchar(255) CHARACTER SET utf8mb4 NULL DEFAULT NULL,
|
||||
`price` decimal(10, 2) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`good_id`) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -67,7 +50,6 @@ CREATE TABLE `tb_order`
|
||||
PRIMARY KEY (`order_id`) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -96,7 +78,6 @@ CREATE TABLE `tb_order_good`
|
||||
`good_id` int NOT NULL
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -136,12 +117,11 @@ DROP TABLE IF EXISTS `tb_role`;
|
||||
CREATE TABLE `tb_role`
|
||||
(
|
||||
`role_id` int NOT NULL AUTO_INCREMENT,
|
||||
`role_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
`role_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
`role_key` varchar(255) CHARACTER SET utf8mb4 NULL DEFAULT NULL,
|
||||
`role_name` varchar(255) CHARACTER SET utf8mb4 NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`role_id`) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -163,12 +143,11 @@ DROP TABLE IF EXISTS `tb_user`;
|
||||
CREATE TABLE `tb_user`
|
||||
(
|
||||
`user_id` int NOT NULL AUTO_INCREMENT,
|
||||
`user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
|
||||
`user_name` varchar(255) CHARACTER SET utf8mb4 NULL DEFAULT NULL,
|
||||
`password` varchar(255) CHARACTER SET utf8mb4 NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`user_id`) USING BTREE
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -193,7 +172,6 @@ CREATE TABLE `tb_user_order`
|
||||
`order_id` int NOT NULL
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
@ -222,7 +200,6 @@ CREATE TABLE `tb_user_role`
|
||||
`role_id` int NOT NULL
|
||||
) ENGINE = InnoDB
|
||||
CHARACTER SET = utf8mb4
|
||||
COLLATE = utf8mb4_0900_ai_ci
|
||||
ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
Loading…
x
Reference in New Issue
Block a user