# mybatis-plus3-demo
**Repository Path**: bj_renyong/mybatis-plus3-demo
## Basic Information
- **Project Name**: mybatis-plus3-demo
- **Description**: mybatis-plus3的demo练习
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2018-07-17
- **Last Updated**: 2023-03-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# mybatis-plus3-demo
## 1. 项目介绍
mybatis-plus3的demo练习
项目围绕didu库的idea_menu,idea_role,idea_role_menu三个表,进行代码生成的测试
## 2. 操作步骤
### 2.1 pom.xml
需要加入以下依赖:
```
com.baomidou
mybatis-plus
3.4.1
pom
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
com.baomidou
mybatis-plus-generator
3.4.1
test
commons-io
commons-io
2.11.0
test
junit
junit
4.13.2
test
org.apache.velocity
velocity
1.7
test
org.springframework.boot
spring-boot-starter-test
test
```
### 2.2 运行时配置文件
将这几个文件移植到项目
- generator_web_db.xml
- mybatis-config.xml
- 表名和字段表都要求使用小写+下划线的格式。因为:1.数据库如果装在windows下是不区分大小写;2.统一标准,便于代码生成
### 2.3 代码生成配置文件
移植文件:mp_generator.properties,并修改配置信息
### 2.4 代码生成的程序类
移植类文件:
```
MpGenerator: 代码生成主程序
MyMsqlTypeConvert:自定义的Mysql->Java类型转换器
MyVelocityTemplateEngine:自定义实现的velocity模版引擎
```
### 2.5 模板文件
如果使用mybatis-plus-generator提供的模板文件进行代码生成,生成的代码存在格式问题,虽不影响使用,但输出效果不理想。
将test/resources/templates下的模板文件移植到实际项目的相应目录下,即可以解决代码生成后的格式问题。
### 2.6 代码生成
执行demo.generator.MyGenerator,如果配置正确,代码可以生成。
### 2.7 测试配置文件
移植test/resources下的配置文件,并进行配置调整
```
application.yml (必须)
application-mysql.yml (必须)
logback.xml (推荐)
```
### 2.8 测试依赖的主程序
移植类或创建类文件:Application,并进行代码调整
修改完成后,编译,启动,确保能正确执行
## 3. 使用说明
### 3.1 update问题
update需要面对的一个问题是全字段update还是指定字段的update
全字段update适合单条记录的操作,指定字段update相对灵活一些,既可以单调记录操作也可以操作满足条件的多条记录。但指定字段update的一个问题是如果不给某个字段赋值(非NULL),这个字段的值就不会被修改,这意味着无法把某个字段的值由非NULL修改为NULL。鱼与熊掌不可得兼!
方案一:采用指定字段update(推荐)
这时如果有需求将某个字段赋值为null,示例代码如下
```java
IdeaRole record = new IdeaRole().setRemark("haha");
Wrapper wrapper = new UpdateWrapper()
// 变通方法,通过set方法,强行增加set create_time字段
.set(IdeaRole.CREATE_TIME, null)
.eq(IdeaRole.ROLE_ID, 1);
roleService.update(record, wrapper);
// 以上代码的输出SQL:
// UPDATE idea_role SET remark=?, create_time=? WHERE (role_id = ?)
```
方案二:采用全字段update
全字段update是指entity中的所有字段都要出现在update的set语句中,这可以实现数据库中将某个值修改为NULL的情况,但无法解决根据条件批量修改数据的情况。解决方法就是手写mybatis代码,补充相应的实现。
要想实现全字段update,需要将entity类中的所有属性(主键属性除外)都加上注解:**fill = FieldFill.UPDATE**,例如:
```java
/**
* 父菜单ID,一级菜单为0
*/
@TableField(fill = FieldFill.UPDATE)
private Integer parentId;
```
**类 demo.generator.MyAutoGenerator实现了在生成的entity类的每个属性上追加这一注解。**
### 3.2 字段名不规范导致代码错误
比如 字符名定义为abstract,这是java的关键字,正常生成后会因这个关键字而编译错误。
解决方案:
```java
// 设置生成字段的注解,这一步一般不需要,但如果生成的字段有与java冲突的关键字导致代码编译错误时,需要设置为true
strategy.entityTableFieldAnnotationEnable(true);
```
1. MpGenerator打开如上代码,此时代码生成后会在entity的属性中会加入字段注解
2. 覆盖类AutoGenerator,加入自己特殊需求的代码
### 3.3 表名不规范导致Entity类名与表名自动转换失效
比如表cms_archives_2,这个表的_2因为不是以字母开头,类名与表名的自动转换失效。
解决方案:需要借助@TableName来指定Entity对应的表名。代码生成时如何做到?
```
gc.setEntityName("%sEntity");
// 这个也行,就是为了打开注解 gc.setEntityName("%s");
```
只要gc的entityName为非空,代码生成时就会产生@TableName
### 3.4 字段类型为unsigned int时,默认转换为java Integer,会出现数值溢出的问题
java int的取值范围为: -2 147 483 648 ~ 2 147 483 647
mysql unsigned int的取值范围为:0 ~ 4 294 967 295,这时候如果再转换为java Integer,就有数值越界风险
解决方案:
* 自定义mysql类型转换器
* 注入自定义的mysql类型转换器
```
// 注入自定义的mysql类型转换器
dsc.setTypeConvert(new MyMsqlTypeConvert());
```
### 3.5 有个项目,在某个方法加上了事务注解后,在openjdk:8 环境下就总是启动报错,各种尝试都无法解决
这个问题非常蹊跷!
问题原因很简单,就是这个类没有接口,这个类的方法上使用注解@Transactional,在本机(sun jdk)没有问题,放到服务器(OpenJdk)就怎么都不行!
比较靠谱的解释:
```
原因就是这个bean被多次代理的时候,jdk代理是基于接口的,所以最后这个bean的类型变成了代理接口proxy的类型。
```
就是说项目里面这个bean被多次代理了,原因不好找啊,可能跟shiro的使用有关系,那怎么办呢???
**实在不行,就把使用了@Transactional的类增加一个接口,这个类实现这个接口,其它需要调用的地方注入接口而不是类本身。笨方法,它有效啊!**