# 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的类增加一个接口,这个类实现这个接口,其它需要调用的地方注入接口而不是类本身。笨方法,它有效啊!**