欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

MyBatisPlus自动生成代码springboot+mybatis+mysql 以及动态sql生成方法(测试可用版)

发布时间:2025/3/15 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 MyBatisPlus自动生成代码springboot+mybatis+mysql 以及动态sql生成方法(测试可用版) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

用了一段时间的springboot,想着百度一下自动生成代码的方式,包括后面如何生成动态sql方法的方式。
摸索了几天,整理一下:
**

1 自动生成代码方式:com.baomidou.mybatisplus

**

mvn配置:

<!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.6</version></dependency>

创建包路径:com.cbe.generator

在com.cbe.generator下创建CodeGenerator类:
一言不合就上代码

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import java.util.ArrayList; import java.util.List; import java.util.Scanner;// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中 public class CodeGenerator {/*** <p>* 读取控制台内容* </p>*/public static String scanner(String tip) {Scanner scanner = new Scanner(System.in);StringBuilder help = new StringBuilder();help.append("请输入" + tip + ":");System.out.println(help.toString());if (scanner.hasNext()) {String ipt = scanner.next();if (StringUtils.isNotEmpty(ipt)) {return ipt;}}throw new MybatisPlusException("请输入正确的" + tip + "!");}public static void main(String[] args) {// 代码生成器AutoGenerator mpg = new AutoGenerator();// 全局配置GlobalConfig gc = new GlobalConfig();//当前工程路径String projectPath = System.getProperty("user.dir"); // System.out.println(projectPath);gc.setOutputDir(projectPath + "/src/main/java");//生成文件的输出目录【默认 D 盘根目录】gc.setAuthor("liuyuzhu");//开发人员gc.setOpen(false);//是否打开输出目录gc.setFileOverride(true);// 是否覆盖已有同名文件,默认是falsegc.setActiveRecord(true);// 开启 ActiveRecord 模式,默认是falsegc.setEnableCache(false);// 是否在xml中添加二级缓存配置,默认是falsegc.setBaseResultMap(true);// 开启 BaseResultMap,默认是falsegc.setBaseColumnList(true);// 开启 baseColumnList,默认是false/** 各层文件名称方式,例如: %sAction 生成 UserAction* %s 为占位符,注意 %s 会自动填充表实体属性!*///gc.setMapperName("%sDao");//默认UserMapper.xml//gc.setXmlName("%sDao");//默认UserMapper.xml//gc.setServiceName("MP%sService");//默认IUserService.java//gc.setServiceImplName("%sServiceDiy");//默认UserServiceImpl.java//gc.setControllerName("%sAction");//默认UserController.javampg.setGlobalConfig(gc);// 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://x.x.x.x:3306/xxxx?useUnicode=true&useSSL=false&characterEncoding=utf8");//dsc.setSchemaName("public");//PostgreSQL schemaNamedsc.setDriverName("com.mysql.jdbc.Driver");dsc.setUsername("xxxxxx");dsc.setPassword("xxxxx");mpg.setDataSource(dsc);// 包配置PackageConfig pc = new PackageConfig();pc.setModuleName(scanner("模块名"));//父包模块名,默认null//父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名pc.setParent("com.cbe");//默认com.baomidou//pc.setController("liuxzhController");//默认controller//pc.setService("liuxzhService");//默认service//pc.setServiceImpl("liuxzhService.impl");//默认service.impl//pc.setEntity("liuxzhEntity");//默认entity//pc.setMapper("liuxzhMapper");//默认mapper//pc.setXml("liuxzhMapper.xml");//默认mapper.xmlmpg.setPackageInfo(pc);// 自定义配置InjectionConfig cfg = new InjectionConfig() {@Overridepublic void initMap() {// to do nothing}};// 如果模板引擎是 freemarkerString templatePath = "/templates/mapper.xml.ftl";// 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm";// 自定义输出配置List<FileOutConfig> focList = new ArrayList<>();// 自定义配置会被优先输出focList.add(new FileOutConfig(templatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;}});cfg.setFileOutConfigList(focList);mpg.setCfg(cfg);// 配置模板TemplateConfig templateConfig = new TemplateConfig();// 配置自定义输出模板// templateConfig.setEntity();// templateConfig.setService();// templateConfig.setController();templateConfig.setXml(null);mpg.setTemplate(templateConfig);// 策略配置StrategyConfig strategy = new StrategyConfig();//数据库表映射到实体的命名策略,默认:不做任何改变,原样输出strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略,未指定按照 naming 执行strategy.setColumnNaming(NamingStrategy.underline_to_camel);//【实体】是否为lombok模型(默认 false)//strategy.setEntityLombokModel(true);//生成@RestController 控制器strategy.setRestControllerStyle(true);//自定义继承的Controller类全称,带包名//strategy.setSuperControllerClass("com.mybatisplus.demo.common.BaseController");//strategy.setSuperServiceClass();//strategy.setSuperServiceImplClass();//strategy.setSuperMapperClass("com.mybatisplus.demo.common.BaseMapper");//strategy.setSuperEntityClass("com.mybatisplus.demo.common.BaseEntity");//自定义继承的Entity类全称,带包名strategy.setInclude(scanner("表名"));//表明String数组strategy.setSuperEntityColumns("id");// 驼峰转连字符:// @RequestMapping("/managerUserActionHistory")-->@RequestMapping("/manager-user-action-history")strategy.setControllerMappingHyphenStyle(true);strategy.setTablePrefix(pc.getModuleName() + "_");//表前缀mpg.setStrategy(strategy);//数据库表配置mpg.setTemplateEngine(new FreemarkerTemplateEngine());// 选择 freemarker 引擎,默认 Veloctiy//生成代码mpg.execute();}}

执行方法如下:执行main方法
输入模块包名test,回车;在输入表名test_case;之后回车就直接生成了代码了。前提需要建好表。

到这里并没有结束:
生成类似的结构如下:


其中mapper包中需要给相关Mapper类添加注解@Mapper,给service和impl类添加注解 @Service。这样便可以不报错了。

2,关于注入动态代码模块:
注明一下:本人不喜欢配置xml,能注解的都注解。个人喜好而已。
首先,完成上述工作后通用的一些增删改查都是有的。此处生成的是有额外需要的sql;
下面为在mapper接口层注入动态sql,有些sql可以直接写完注入,有些则需要配置Provider单独生成。SelectProvider,UpdateProvider等。

@Mapper public interface TestWorksheetMapper extends BaseMapper<TestWorksheet> {@SelectProvider(method = "selectByTaskNoAppName",type = WorksheetProvider.class)int selectByTaskNoAppName(@Param("taskNo") String taskNo,@Param("appName") String appName);@UpdateProvider(method = "updateByTaskNoAndAppName", type = WorksheetProvider.class)Boolean updateByTaskNoAndAppName( TestWorksheet sheet,String taskNo,String appName);@Select("SELECT addAppTime, taskNo,taskName,appName, STATUS,genbranchUser, testersStr,bugsNum, producerStr FROM TEST_WORKSHEET WHERE status not in ('合并主干完成','作废') ORDER BY addAppTime DESC ;")List<TestWorksheet> queryWorkSheetUnDone();@Select("SELECT addAppTime, taskNo,taskName,appName, STATUS,genbranchUser, testersStr,bugsNum, producerStr FROM TEST_WORKSHEET WHERE status ='合并主干完成' and status !='作废' ORDER BY addAppTime DESC limit 20;")List<TestWorksheet> queryWorkSheetDone();}

method = “updateByTaskNoAndAppName”, type = WorksheetProvider.class
method 的值 对应WorksheetProvider 类中的方法名。
接下来我们看WorksheetProvider类;
以最复杂的update为例:

import org.apache.ibatis.jdbc.SQL;import com.cbe.worksheet.entity.TestWorksheet;public class WorksheetProvider {public String selectByTaskNoAppName(String taskNo, String appName) {String sql = "select count(*) from test_worksheet where taskNo='" + taskNo + "'" + " and appName='" + appName+ "' and status!='作废';";return sql;}// 根据工单号应用名更新数据public String updateByTaskNoAndAppName(TestWorksheet sheet, String taskNo, String appName) { // System.out.println(sheet.toString());String sql = new SQL() {{UPDATE("test_worksheet");if(sheet.getAddAppTime() != null){SET("addAppTime='"+sheet.getAddAppTime()+"'"); }if(sheet.getPtype() != null){SET("ptype='"+sheet.getPtype()+"'"); }if(sheet.getTeamDesc() != null){SET("teamDesc='"+sheet.getTeamDesc()+"'"); }if(sheet.getCasesNum() != null){SET("casesNum='"+sheet.getCasesNum()+"'"); }if(sheet.getExpectedOnlineTime() != null){SET("expectedOnlineTime='"+sheet.getExpectedOnlineTime()+"'"); }if(sheet.getMaoyanNum() != null){SET("maoyanNum='"+sheet.getMaoyanNum()+"'"); }if(sheet.getTaskNo() != null){SET("taskNo='"+sheet.getTaskNo()+"'"); }if(sheet.getActualOnlineTime() != null){SET("actualOnlineTime='"+sheet.getActualOnlineTime()+"'"); }if(sheet.getExpectedTestDoneTime() != null){SET("expectedTestDoneTime='"+sheet.getExpectedTestDoneTime()+"'"); }if(sheet.getMergeTime() != null){SET("mergeTime='"+sheet.getMergeTime()+"'"); }if(sheet.getTestNum() != null){SET("testNum='"+sheet.getTestNum()+"'"); }if(sheet.getExpectedPutTestTime() != null){SET("expectedPutTestTime='"+sheet.getExpectedPutTestTime()+"'"); }if(sheet.getPname() != null){SET("pname='"+sheet.getPname()+"'"); }if(sheet.getAppName() != null){SET("appName='"+sheet.getAppName()+"'"); }if(sheet.getGenbranchTime() != null){SET("genbranchTime='"+sheet.getGenbranchTime()+"'"); }if(sheet.getGenbranchUser() != null){SET("genbranchUser='"+sheet.getGenbranchUser()+"'"); }if(sheet.getPutMergeTime() != null){SET("putMergeTime='"+sheet.getPutMergeTime()+"'"); }if(sheet.getTestingTime() != null){SET("testingTime='"+sheet.getTestingTime()+"'"); }if(sheet.getRqtId() != null){SET("rqtId='"+sheet.getRqtId()+"'"); }if(sheet.getTestersStr() != null){SET("testersStr='"+sheet.getTestersStr()+"'"); }if(sheet.getBugsNum() != null){SET("bugsNum='"+sheet.getBugsNum()+"'"); }if(sheet.getTestWorkLoad() != null){SET("testWorkLoad='"+sheet.getTestWorkLoad()+"'"); }if(sheet.getProducerStr() != null){SET("producerStr='"+sheet.getProducerStr()+"'"); }if(sheet.getInTime() != null){SET("inTime='"+sheet.getInTime()+"'"); }if(sheet.getDevelopersStr() != null){SET("developersStr='"+sheet.getDevelopersStr()+"'"); }if(sheet.getActualPutTestTime() != null){SET("actualPutTestTime='"+sheet.getActualPutTestTime()+"'"); }if(sheet.getActualTestDoneTime() != null){SET("actualTestDoneTime='"+sheet.getActualTestDoneTime()+"'"); }if(sheet.getMergedTime() != null){SET("mergedTime='"+sheet.getMergedTime()+"'"); }if(sheet.getRqter() != null){SET("rqter='"+sheet.getRqter()+"'"); }if(sheet.getTaskName() != null){SET("taskName='"+sheet.getTaskName()+"'"); }if(sheet.getFixNum() != null){SET("fixNum='"+sheet.getFixNum()+"'"); }if(sheet.getStatus() != null){SET("status='"+sheet.getStatus()+"'"); }WHERE("taskNo='" + taskNo + "' and appName='" + appName+"'" );}}.toString(); // System.out.println(sql);return sql;}}

其中update部分 是自动打印生成的,只是复制过来使用。避免手工编写。

if(sheet.getAddAppTime() != null){SET("addAppTime='"+sheet.getAddAppTime()+"'"); }

使用到的工具类如下:

public class SqlProvider {public static String upperCase(String str) {return str.substring(0, 1).toUpperCase() + str.substring(1); }static void update(String tabname){CreUpSql sql = new CreUpSql();String[][] string= sql.getFieldsNames(tabname);for (int i = 0; i < string.length; i++) {String parm = string[i][0]; // System.out.println(string[i][0]+" " +string[i][1]);System.out.println( " if(sheet.get"+upperCase(parm)+"() != null){SET(\""+parm+"='\"+sheet.get"+upperCase(parm)+"()+\"'\"); }");}} public static void main(String[] args) {update("test_case"); }

里面用到CreUpSql;

public class CreUpSql {/*** 获取表的所有字段名称* * @param tabname* @return*/public String[][] getFieldsNames(String tabname) {Connection conn = null;try {conn = ConnUtil.getConn();} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}Statement stat = null;ResultSet rs = null;ResultSetMetaData data = null; // 定义ResultSetMetaData对象String[][] resultStrs = null;int coloumCount = 0;try {stat = conn.createStatement();String sql = "select * from " + tabname;rs = stat.executeQuery(sql);// 查询数据data = rs.getMetaData();coloumCount = data.getColumnCount();resultStrs = new String[coloumCount][2];for (int i = 0; i < coloumCount; i++) {resultStrs[i][0] = data.getColumnName(i + 1);resultStrs[i][1] = data.getColumnTypeName(i + 1);}// 关闭数据库资源if (rs != null) {rs.close();}if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}return resultStrs;}}

这里用到了ConnUtil ;

public class ConnUtil {private final static String DRIVER="com.mysql.jdbc.Driver";private final static String URL="jdbc:mysql://x.x.x.x:3306/xxxx?useUnicode=true&characterEncoding=utf-8";private final static String USERNAME="xxxx";//数据库登录用户名private final static String PASSWORD="xxxxxx";//数据登录密码private static Connection conn;public static Connection getConn() throws Exception {try {Class.forName(DRIVER);conn=DriverManager.getConnection(URL,USERNAME ,PASSWORD);//连接数据库} catch (Exception e) {throw new Exception("数据库连接异常!");}return conn;//返回连接对象}//关闭数据库连接public void CloseConnection() {if(null!=conn) {try {conn.close();//关闭连接} catch (SQLException e) {e.printStackTrace();}}}}

按着步骤就可以执行。亲测可用。有问题可以随时联系我;欢迎指教。

总结

以上是生活随笔为你收集整理的MyBatisPlus自动生成代码springboot+mybatis+mysql 以及动态sql生成方法(测试可用版)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。