mybatisplus代码生成器
版本匹配是个比较麻烦的问题,这是我的配置:
<dependency>
<groupid>com.baomidou</groupid>
<artifactid>mybatis-plus-boot-starter</artifactid>
<version>3.5.2</version>
</dependency>
<dependency>
<groupid>com.baomidou</groupid>
<artifactid>mybatis-plus-generator</artifactid>
<version>3.5.2</version>
</dependency>
<dependency>
<groupid>org.freemarker</groupid>
<artifactid>freemarker</artifactid>
<version>2.3.31</version> <!-- 推荐版本 -->
</dependency>codegenerator:
package com.neuedu.hisweb.utils;
import com.baomidou.mybatisplus.core.exceptions.mybatisplusexception;
import com.baomidou.mybatisplus.generator.fastautogenerator;
import com.baomidou.mybatisplus.generator.config.outputfile;
import com.baomidou.mybatisplus.generator.config.rules.datetype;
import com.baomidou.mybatisplus.generator.config.rules.namingstrategy;
import com.baomidou.mybatisplus.generator.engine.freemarkertemplateengine;
import com.baomidou.mybatisplus.generator.fill.column;
import com.baomidou.mybatisplus.annotation.fieldfill; // 引入正确的枚举类
import org.apache.commons.lang3.stringutils;
import java.util.collections;
import java.util.scanner;
public class codegenerator {
private static final string url = "jdbc:mysql://localhost:3306/his02?useunicode=true&characterencoding=utf-8&usessl=false&allowmultiqueries=true";
private static final string username = "root";
private static final string password = "1";
private static final string author = "xj";
private static final string parent_package = "com.neuedu.hisweb";
private static final string output_dir = system.getproperty("user.dir") + "/src/main/java";
public static string scanner(string tip) {
scanner scanner = new scanner(system.in);
system.out.println("请输入" + tip + ":");
if (scanner.hasnext()) {
string ipt = scanner.next();
if (stringutils.isnotblank(ipt)) {
return ipt;
}
}
throw new mybatisplusexception("请输入正确的" + tip + "!");
}
public static void main(string[] args) {
// 获取需要生成的表名
string tables = scanner("表名,多个英文逗号分割");
fastautogenerator.create(url, username, password)
.globalconfig(builder -> {
builder.author(author)
.outputdir(output_dir)
.fileoverride()
.disableopendir()
.datetype(datetype.only_date)
.commentdate("yyyy-mm-dd");
})
.packageconfig(builder -> {
builder.parent(parent_package)
.entity("entity")
.service("service")
.serviceimpl("service.impl")
.mapper("mapper")
.controller("controller")
.pathinfo(collections.singletonmap(
outputfile.xml,
system.getproperty("user.dir") + "/src/main/resources/mapper"
));
})
.strategyconfig(builder -> {
builder.addinclude(tables.split(","))
.entitybuilder()
.enablelombok()
.naming(namingstrategy.underline_to_camel)
.columnnaming(namingstrategy.underline_to_camel)
.logicdeletecolumnname("deleted")
.versioncolumnname("version")
.addtablefills(
new column("create_time", fieldfill.insert), // 修改为正确的枚举值
new column("update_time", fieldfill.insert_update) // 修改为正确的枚举值
)
.controllerbuilder()
.enablereststyle()
.formatfilename("%scontroller")
.servicebuilder()
.formatservicefilename("%sservice")
.formatserviceimplfilename("%sserviceimpl")
.mapperbuilder()
.formatmapperfilename("%smapper")
.formatxmlfilename("%smapper");
})
.templateengine(new freemarkertemplateengine())
.execute();
}
}mybatis-plus混合使用xml和注解配置
配置原则
1.优先级:
- xml 配置会覆盖注解配置。
2.最佳实践:
- 简单的 crud 操作可以使用注解(如
@select、@insert等)。 - 复杂的 sql 查询(如多表关联、动态 sql)建议使用 xml 配置。
3.xml 文件位置:
- 默认放在
resources/mapper目录下,文件名与 mapper 接口名对应。
具体配置方法
1.基础配置
确保 application.yml 或 application.properties 中正确配置 mybatis-plus:
# application.yml
mybatis-plus:
# mapper xml 文件路径
mapper-locations: classpath:mapper/*.xml
# 实体扫描,多个package用逗号或者分号分隔
type-aliases-package: com.neuedu.hisweb.entity
configuration:
# 开启驼峰命名
map-underscore-to-camel-case: true2.混合使用示例
mapper 接口:
package com.neuedu.hisweb.mapper;
import com.baomidou.mybatisplus.core.mapper.basemapper;
import com.neuedu.hisweb.entity.user;
import org.apache.ibatis.annotations.*;
import java.util.list;
public interface usermapper extends basemapper<user> {
// 1. 使用注解实现简单查询
@select("select * from user where age > #{age}")
list<user> selectbyage(int age);
// 2. 使用注解实现带参数的插入
@insert("insert into user(name, age) values(#{name}, #{age})")
@options(usegeneratedkeys = true, keyproperty = "id")
int insertuser(user user);
// 3. 使用 xml 实现复杂查询(xml 文件中定义该方法)
list<user> selectuserwithdepartment();
}对应的 xml 文件(resources/mapper/usermapper.xml):
<?xml version="1.0" encoding="utf-8" ?>
<!doctype mapper public "-//mybatis.org//dtd mapper 3.0//en"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.neuedu.hisweb.mapper.usermapper">
<!-- 实现 usermapper 接口中定义的 selectuserwithdepartment 方法 -->
<select id="selectuserwithdepartment" resulttype="com.neuedu.hisweb.entity.user">
select u.*, d.name as dept_name
from user u
left join department d on u.dept_id = d.id
where u.deleted = 0
</select>
<!-- 可以添加更多复杂 sql -->
</mapper>注意事项
1.方法名匹配:xml 文件中的 id 必须与 mapper 接口中的方法名一致。
2.参数处理:
- 注解方式:使用
@param注解为参数命名。 - xml 方式:可以直接使用参数名或索引。
3.冲突处理:
- 如果同一方法在 xml 和注解中都有定义,xml 配置会覆盖注解配置。
4.xml 文件路径:
- 确保
mapper-locations配置正确指向 xml 文件。 - 推荐使用
classpath:mapper/*.xml或classpath*:mapper/**/*.xml。
动态 sql 示例
对于复杂的动态 sql,xml 方式更加灵活:
<select id="selectuserbycondition" resulttype="com.neuedu.hisweb.entity.user">
select * from user
<where>
<if test="name != null and name != ''">
and name like concat('%', #{name}, '%')
</if>
<if test="age != null">
and age >= #{age}
</if>
<if test="deptid != null">
and dept_id = #{deptid}
</if>
</where>
order by create_time desc
</select>常见问题
xml 文件未被加载:
- 检查
mapper-locations配置是否正确。 - 确保 xml 文件在
resources目录下的正确位置。
方法找不到:
- 检查 xml 中的
namespace是否与 mapper 接口的全限定名一致。 - 检查方法名(
id)是否匹配。
依赖问题:
- 确保项目中包含 mybatis-plus 和 mybatis 的依赖:
<dependency>
<groupid>com.baomidou</groupid>
<artifactid>mybatis-plus-boot-starter</artifactid>
<version>3.5.2</version>
</dependency>@mapperscan与mapper-locations的功能的兼容性
@mapperscan负责让 spring 容器识别 mapper 接口。mapper-locations负责让 mybatis-plus 加载 xml 中的 sql 定义。只要两者的路径配置与实际文件位置一致,即可同时使用,不会产生冲突。
两者的核心功能区别
@mapperscan("com.neuedu.hisweb.mapper") 的作用
- 扫描 mapper 接口:告诉 spring 容器去哪里查找 mybatis-plus 的 mapper 接口(如
patientcostsmapper),并将这些接口注册为 spring bean。 - 必须配置:如果没有该注解或未通过其他方式扫描 mapper 接口,spring 将无法识别这些接口,导致依赖注入失败(如
@autowired usermapper会报错)。
mapper-locations: classpath:mapper/*.xml 的作用
- 指定 xml 映射文件路径:告诉 mybatis-plus 去哪里查找 xml 格式的 sql 映射文件(如
patientcostsmapper.xml)。 - 可选配置:如果 mapper 接口中所有方法都使用注解(如
@select)定义 sql,则无需配置;若存在 xml 定义的 sql,则必须配置正确路径。
为什么需要同时使用?
场景示例:
- mapper 接口
patientcostsmapper继承自basemapper<patientcosts>,自动获得 crud 方法(无需 xml)。 - 若该接口中定义了自定义方法(如
selectbycondition),且该方法的 sql 在patientcostsmapper.xml中实现,则必须通过mapper-locations配置 xml 路径,否则 mybatis-plus 无法找到对应的 sql 语句。
@mapperscan 解决的是 mapper 接口的注册问题,mapper-locations 解决的是 xml 映射文件的加载问题,两者功能独立,可同时使用。
目录结构建议
为避免混淆,建议按以下规范组织文件:
mapper 接口位置:
src/main/java/com/neuedu/hisweb/mapper/patientcostsmapper.java
(与 @mapperscan("com.neuedu.hisweb.mapper") 扫描路径一致)
xml 映射文件位置:
src/main/resources/mapper/patientcostsmapper.xml
(与 mapper-locations: classpath:mapper/*.xml 配置路径一致)
可能的冲突场景与解决方案
1.xml 与注解的 sql 定义冲突
- 问题:若 mapper 接口的某个方法同时通过注解(如
@select)和 xml 定义 sql,则 xml 配置优先级更高,会覆盖注解中的 sql。 - 解决方案:同一方法的 sql 定义只能选择一种方式(注解或 xml),避免重复定义。
2.mapper 接口未被扫描
- 问题:若
@mapperscan扫描路径错误(如写成@mapperscan("com.neuedu.hisweb.dao")),则 spring 无法找到patientcostsmapper,导致启动时报错。 - 解决方案:确保
@mapperscan的包路径与 mapper 接口实际路径一致。
验证配置是否生效
启动应用:
- 若控制台无
nosuchbeandefinitionexception或invalid bound statement错误,说明配置正确。
查看日志:
- 若配置了
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.stdoutimpl,执行 sql 时会打印 xml 或注解中的 sql 语句,可验证是否正确加载。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论