MyBatis-Plus教程
1、简介
Mybatis和Hibernate是项目中最常用的两个持久层框架,Hibernate封装的比较完整,可移植性高,而Mybatis仅仅是一个半自动的ORM框架,但是Myabtis更轻量化,灵活性更好,效率更高,可个性化定制,SQL优化相对简单,这也是很多公司为什么选择使用Mybatis,而不是Hibernate的原因,Hibernate已经逐渐被JPA替代,隐退至底层,而不是直接被使用。
使用Mybatis小伙伴的在嘲笑Hibernate臃肿的同时又羡慕人家面向对象操作的便捷,于是,基于Mybatis二次封装的框架应运而生,如TkMybatis、MyBatis-Plus,本文将主要介绍MyBatis-Plus的使用,MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生,提供了很多面向对象的操作方法。至于其特性和框架结构这里就不赘述了,可以详看官网(官网地址)。
2、与SpringBoot整合使用
划重点:
a.由于MyBatis-Plus更新频率比较快,而且部分版本变化较大,本文会根据官方的更新及时调整文章内容,确保内容的正确性。
b.引入 MyBatis-Plus 之后就不要再次引入 MyBatis 以及 MyBatis-Spring相关包,以避免因版本差异导致问题。
2.1 依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
lombok依赖是为简化实体引入,非必须。
版本说明:使用SpringBoot 2.1.5.RELEAS、JDK1.8、MySQL数据库8.0.16
2.2 建表
先建一张表,这里建一张物流公司表
-- ---------------------------- -- Table structure for logistics -- ---------------------------- DROP TABLE IF EXISTS `logistics`; CREATE TABLE `logistics` ( `id` mediumint(6) NOT NULL AUTO_INCREMENT, `ecode` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '物流公司编码', `ename` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '物流公司名称', `short_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '物流公司简称', `logistics_type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '电子面单物流类型', `mailno_regular` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '运单号正则表达式', `account_no` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '帐号', `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码', `pay_type` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '付款方式', `express_type` int(11) NULL DEFAULT NULL COMMENT '快件产品类型', `monthly_card_no` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '月结卡号', `weight_type` int(11) NULL DEFAULT NULL COMMENT '称重方式', `send_city_code` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '发货城市编号', `url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '直连电子面单URL', `cainiao_url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜鸟模板URL', `ad_org_id` bigint(20) NULL DEFAULT NULL COMMENT '所属组织', `isactive` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'Y' COMMENT '是否可用', `ad_client_id` bigint(20) NULL DEFAULT NULL COMMENT '所属公司', `ownerid` bigint(20) NULL DEFAULT NULL COMMENT '创建人id', `ownerename` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人姓名', `ownername` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人用户名', `creationdate` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', `modifierid` bigint(20) NULL DEFAULT NULL COMMENT '修改人id', `modifierename` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人姓名', `modifiername` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人用户名', `modifieddate` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, INDEX `id`(`id`) USING BTREE COMMENT 'id' ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '物流公司档案' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
2.3 application.properties
server.port=9006 ###########数据库连接信息############### spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456
2.4 实体类
既然是映射框架,肯定需要将表与实体类、表字段与实体属性一一对应。
@TableName(value = "logistics") @Data public class Logistics { @TableField(fill = FieldFill.INSERT) @TableId(value = "id", type = IdType.INPUT) private Long id; @TableField(value = "ecode") private String ecode; private String ename; private String shortName; private String logisticsType; private String mailnoRegular; private String accountNo; private String password; private String payType; private Integer expressType; private String monthlyCardNo; private Integer weightType; private String sendCityCode; private String url; private String cainiaoUrl; private Long adOrgId; private String isactive; private Long adClientId; private Long ownerid; private String ownerename; private String ownername; private Date creationdate; private Long modifierid; private String modifierename; private String modifiername; private Date modifieddate; }
实体类注解说明:
(1)@TableName 表名注解,用来确立表和实体的关系
(2)@TableId 主键注解,这个不用多说,肯定是置于ID属性上了。
(3)@TableField 字段注解(非主键),确立实体属性与表字段的关系。
如果和数据库表字段一致或者表字段使用了下划线,实体属性将下划线替换为大写,也就是驼峰,如is_delete对应isDelete,就可以省略该注解。因为我建的表字段都满足,因此全部省略。
属性可以比字段少,如果属性没有对应的表字段,应该使用注解的exist属性标识(是否为数据库表字段)。
字段为null的更不更新跟字段的策略有关,默认不更新。改变策略strategy=FieldStrategy.IGNORED,就会忽略null值的判断,null就会进行更新。
字段策略源码:
/** * 字段策略枚举类 * * @author hubin * @since 2016-09-09 */ public enum FieldStrategy { /** * 忽略判断 */ IGNORED, /** * 非NULL判断 */ NOT_NULL, /** * 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断) */ NOT_EMPTY, /** * 默认的,一般只用于注解里 * <p>1. 在全局里代表 NOT_NULL</p> * <p>2. 在注解里代表 跟随全局</p> */ DEFAULT }
(4)@Version 乐观锁注解、标记 @Verison 在字段上
(5)@EnumValue 通用枚举类注解(注解在枚举字段上),这个会在后面详解。
(6)@TableLogic 表字段逻辑处理注解(逻辑删除)
(7)@SqlParser 租户注解
(8)@KeySequence 序列主键策略 oracle
2.5 使用1--------Mapper CRUD 接口
映射关系已经确立好了,只需要创建XXMapper 接口, 并继承 BaseMapper 接口。
@Mapper public interface LogisticsMapper extends BaseMapper<Logistics> { }
至此,我们就可以使用MyBatis-Plus封装的各种方法了。
注意:如果觉得在每个mapper接口上加一个@Mapper比较麻烦,可以选择去掉所有接口的注解,而在启动类上加上@MapperScan(“com.mybatisPlus.mapper”)进行统一扫描,value是mapper接口所在路径。
2.5.1 新增
@RunWith(SpringRunner.class) @SpringBootTest public class MybatisPlusApplicationTests { @Autowired private LogisticsMapper LogisticsMapper; @Test public void test025() { Logistics logistics = new Logistics(); logistics.setEcode("123"); logistics.setEname("顺丰快递"); logistics.setShortName("SF"); int insert = LogisticsMapper.insert(logistics); } }
MybatisPlus会自动把当前插入对象在数据库中的id写回到该实体中,通过get方法得到id。
注入mapper接口,这里IDEA可能会报无法注入,这个不用管,属于误报。
2.5.2 修改
根据id修改
Logistics logistics = new Logistics(); logistics.setId(10L); logistics.setEcode("123"); logistics.setEname("天天快递"); logistics.setShortName("TT"); int i = LogisticsMapper.updateById(logistics);
根据条件修改
将ename是“天天快递”的全部更新
int update = LogisticsMapper.update(logistics, new UpdateWrapper<Logistics>().eq("ename", "天天快递"));
构造器说明:
xxxWrapper是条件构造器,可以构造不同的组合条件,下面是构造器的继承图,可以根据不同的场景选择不同的构造器:
构造器条件 | 说明 |
---|---|
eq | 等于 = |
ne | 不等于 <> |
gt | 大于 > |
ge | 大于等于 >= |
lt | 小于 < |
le | 小于等于 <= |
between | BETWEEN 值1 AND 值2 |
notBetween | NOT BETWEEN 值1 AND 值2 |
like | LIKE ‘%值%’ |
notLike | NOT LIKE ‘%值%’ |
likeLeft | LIKE ‘%值’ |
likeRight | LIKE ‘值%’ |
isNull | 字段 IS NULL |
isNotNull | 字段 IS NOT NULL |
in / inSql | 字段 IN (value.get(0), value.get(1), …),例: in(“age”,{1,2,3})—>age in (1,2,3) |
notIn / notInSql | 字段NOT IN (value.get(0), value.get(1), …) |
groupBy | 分组:GROUP BY 字段, … |
orderBy / orderByAsc | 排序:ORDER BY 字段, … ASC |
orderByDesc | 排序:ORDER BY 字段, … DESC |
having | HAVING ( sql语句 ) |
or | 注意事项:主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接) |
and | AND 嵌套 |
last | 无视优化规则直接拼接到 sql 的最后 |
exists | 拼接 EXISTS ( sql语句 ) |
notExists | 拼接 NOT EXISTS ( sql语句 ) |
nested | 正常嵌套 不带 AND 或者 OR 例: nested(i -> i.eq(“code”, “123”).ne(“status”, “1”))—>(code= ‘123’ and status <> ‘1’) |
2.5.3 删除
根据id删除
int delete = LogisticsMapper.deleteById(10);
根据id集合批量删除
List<Long> list = new ArrayList<>(); list.add(1L); list.add(2L); int i = LogisticsMapper.deleteBatchIds(list);
根据条件删除—map构造条件
Map<String, Object> map = new HashMap<>(); map.put("ecode", 123); map.put("ename", "顺丰"); int delete = LogisticsMapper.deleteByMap(map);
注意:map构造的条件之间是and的关系,并且key是表中的字段名,而不是属性名。
根据条件删除—Wrapper构造器(不常用)
int delete = LogisticsMapper.delete(new Wrapper<Logistics>() { @Override public Logistics getEntity() { Logistics logistics = new Logistics(); logistics.setEcode("123"); logistics.setEname("中通"); return logistics; } @Override public MergeSegments getExpression() { //合并 SQL 片段 return null; } @Override public String getCustomSqlSegment() { return null; } @Override public String getSqlSegment() { return null; } });
2.5.4 查询
根据id查询,返回一个实体;
T selectById(Serializable id)
根据id集批量查询,返回实体集;
List<T> selectBatchIds(idList)
根据map构造条件查询,注意是and关系;
List<T> selectByMap(columnMap);
根据Wrapper条件构造器查询,返回实体,要确保结果唯一,否则会抛出异常;
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
根据Wrapper条件构造器查询记录数;
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
根据Wrapper条件构造器查询,返回实体集;
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
根据Wrapper条件构造器查询,返回字段映射对象 Map 集合
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
根据Wrapper条件构造器查询,返回第一个字段的值集合,如表第一个字段是id,那就返回id集合;
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
根据Wrapper条件构造器分页查询,返回分好页的全部记录,返回实体分页对象;
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
根据Wrapper条件构造器分页查询,返回分好页的全部记录,返回字段映射对象 Map 分页对象;
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
上面查询都是将所有字段返回,有时候业务上并不需要这么多的字段,而且查询所有字段比较耗时,MP也提供了查询指定字段的方法,如下:
List<Logistics> ocBOrders1 = LogisticsMapper.selectList(new LambdaQueryWrapper<Logistics>().select(Logistics::getId, Logistics::getEcode).eq(Logistics::getId, 1)); List<Logistics> ocBOrders2 = LogisticsMapper.selectList(Wrappers.<Logistics>query().select("id", "ecode").eq("id", 1)); List<Logistics> ocBOrders3 = LogisticsMapper.selectList(new QueryWrapper<Logistics>().select("id", "ecode").eq("id", 1));
三种方式都可以,select里指定需要查询的字段,返回的依然是实体集,但是因为没有查询其他字段,其他属性都是null。
注意:条件构造器可以为null,代表没有条件,查询所有,但是按照id集批量查询或者修改的时候传参是不能为空的。
另外:分页查询需要配合分页插件。如果不配置,其默认采用的分页为RowBounds的分页即逻辑分页,也就是先把数据记录全部查询出来,然在再根据offset和limit截断记录返回(性能差,甚至会把服务器搞崩),而通过分页插件的配置即可达到物理分页效果。
@SpringBootApplication public class MybatisPlusApplication { public static void main(String[] args) { SpringApplication.run(MybatisPlusApplication.class); } /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
2.6 使用2--------Service CRUD 接口
使用mapper能满足大部分人的需求,但是MP还提供了Service CRUD 接口,
只需要让你的service类继承MP提供的ServiceImpl<LogisticsMapper, Logistics>,然后调用父类的方法就可以了,如果有扩展需求还可以进行重写。Service CRUD接口需要依赖mapper接口,虽然可能不用mapper,但是要留着。
@Service public class LogisticsService extends ServiceImpl<LogisticsMapper, Logistics> { public void queryById(){ Logistics logistics = this.getById(1); //或者super.getById(1); } }
为了和Mapper CRUD 接口提供的方法区分开来,加了方法前缀,getxxx查询、removexxx 删除、listxxx 查询集合、pagexxx 分页、savexxx新增(提供了批量新增)。这里就不一一演示了,大家可以试试。
如果mapper和service提供的方法还是无法满足你,或者你还是喜欢用SQL,so easy,因为MP是包含Mybatis的,你可以直接将他当作Mybatis使用,在mapper中写SQL。
@Mapper public interface LogisticsMapper extends BaseMapper<Logistics> { @Select("SELECT ECODE FROM LOGISTICS WHERE ID=#{id}") String getEcodeById(Long id); }
2.7 使用3--------ActiveRecord CRUD
ActiveRecord(以下简称AR)模式在新版本中的官文没有提及,但是并没有移除,因为不需要注入XXMapper,AR操作是通过对象本身调用相关方法,new的对象之后直接调用方法操作即可。
1、实体类
实体类需要继承Model,重写方法,return当前类的主键
@Override protected Serializable pkVal() { return id; }
2、mapper接口
@Mapper public interface LogisticsMapper extends BaseMapper<Logistics> { }
虽然AR模式用不到mapper接口,但是一定要定义,否则使用AR时会报空指针异常。
3、使用
CRUD都不止一个方法,这里只演示一个。
(1)、新增
logistics.insert();
(2)、更新
logistics.updateById();
(3)、查询
logistics.selectById();
(4)、删除
boolean b = logistics.deleteById();
返回的是布尔,true删除成功,false删除失败,删除数据库中不存在的数据返回false
(5)、AR分页操作:
IPage selectPage = logistics.selectPage(new Page<>(1, 4), new QueryWrapper<Logistics>().like("ecode", "123")); List<Logistics> list = selectPage.getRecords();
注意:如果需要看方法的底层sql,需要在配置文件中配置一下:
#控制台打印底层sql mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
2.8 通用枚举
很多业务下,前端显示的是逻辑值,但是数据库存的却是数值,如男在数据库对应1,女对应2,这里就需要进行字段的转换,不管是后端做还是前端做,都是一件很麻烦的事情,如果一两个还好,但是这种字段多的话代码繁琐不优雅,MP提供了解决方法,就是通用枚举。
(1)首先,将该类字段直接定义为枚举;
转化字段需要JSON序列化处理,只要是json传输,就需要进行JSON序列化处理,因为我们传给前端的就是json字符串。
@JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString) private SexEnum sex;
这里使用的是Fastjson,如果是Jackson,则是在需要响应描述字段的get方法上添加@JsonValue注解即可。
(2)枚举类
定义对应枚举类
public enum SexEnum { MALE(1, "男"), FEMALE(2, "女"); @EnumValue//用于标记数据库存的是那个字段的值 private final int code; private final String descp; SexEnum(int code, String descp) { this.code = code; this.descp = descp; } public int getCode() { return code; } //重写toString方法,返回逻辑值 @Override public String toString() { return descp; } }
(3)application.propertis文件增加配置
#mybatis-Plus配置,枚举类所在包路径 mybatis-plus.typeEnumsPackage=com.mybatisPlus.model.enums
这样就搞定了。
3、代码生成器
MP的强大不止于此,它提供了很多附属功能,如分布式事务、多数据源切换、SQL性能监控(p6spy实现)、代码生成器等等。因为表字段和实体属性是一一对应的,如果表中字段几十上百,写一个实体类简直就是折麽人,MP提供的代码生成器不仅可以生成实体类,还可以生成mapper、xml、service、controller,有了这个神器再也不担心实体类生成了,如果字段名称改的比较多,直接重新生成就好了,不用再一个个找出来修改,大大的提高了效率。
3.1 依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.1.1</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency>
MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖
3.2 代码生成类
官文中的示例好久没更新了,所以需要稍作调整,copy下面代码,修改相关信息,直接主类运行即可。
public class CodeGenerator { public static void main(String[] args) { //代码生成器 AutoGenerator mpg = new AutoGenerator(); mpg.setGlobalConfig(globalConfig()); mpg.setDataSource(dataSourceConfig()); mpg.setStrategy(strategyConfig()); mpg.setPackageInfo(packageConfig()); mpg.execute(); } /** * 全局配置 */ private static GlobalConfig globalConfig() { GlobalConfig config = new GlobalConfig(); config.setActiveRecord(false) // 是否开启AR模式 .setAuthor("sunies") //生成的文件头@author .setOutputDir("C:/Users/sunies/Desktop") //生成路径 .setFileOverride(true) //文件是否覆盖 .setIdType(IdType.AUTO) // 主键策略 .setServiceName("%sService") //文件名称方式,例如: %sAction 生成 UserAction, %s 为占位符默认情况下生成的Service接口的名字首字母都带有I .setBaseResultMap(true) // 是否生成基本的sql中的ResultMap .setBaseColumnList(true) // 是否生成基本的sql列 .setSwagger2(true)//实体属性 Swagger2 注解 .setOpen(false);//生成后是否自动打开文件夹 return config; } /** * 数据库连接信息 * * @return */ private static DataSourceConfig dataSourceConfig() { DataSourceConfig dsc = new DataSourceConfig(); dsc.setDbType(DbType.MYSQL); dsc.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=utf-8"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); return dsc; } /** * 策略配置 */ private static StrategyConfig strategyConfig() { StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setCapitalMode(true); // 是否大写命名 // 表前缀 //strategyConfig.setTablePrefix(""); strategyConfig.setNaming(NamingStrategy.underline_to_camel); // 从数据库表到文件的命名策略 //需要包含的表名,允许正则表达式(与exclude二选一配置) strategyConfig.setInclude("logistics"); // 数据库表名,需要存在 //数据库表字段映射到实体的命名策略,原样输出no_change,下划线转驼峰命underline_to_camel; strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel); //自定义继承的Entity类全称,带包名 //strategyConfig.setSuperEntityClass("com.baomidou.ant.common.BaseEntity"); //是否为lombok模型(默认 false) strategyConfig.setEntityLombokModel(true); //生成控制器 strategyConfig.setRestControllerStyle(true); //实体是否生成 serialVersionUID strategyConfig.setEntitySerialVersionUID(true); // 自定义继承的Controller类全称,带包名 //strategyConfig.setSuperControllerClass("com.baomidou.ant.common.BaseController"); //自定义基础的Entity类,公共字段 //strategyConfig.setSuperEntityColumns("id"); //驼峰转连字符 //strategyConfig.setControllerMappingHyphenStyle(true); //表前缀 //strategyConfig.setTablePrefix(); return strategyConfig; } /** * 包名策略配置 */ private static PackageConfig packageConfig() { PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.demo"); // 总包名 packageConfig.setEntity("model"); // 实体生成后所在包名 packageConfig.setController("controller"); packageConfig.setService("service"); packageConfig.setMapper("mapper"); packageConfig.setXml("mapper"); return packageConfig; } /** * 自定义配置 * * @return */ private static InjectionConfig injectionConfig() { InjectionConfig injectionConfig = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! return "C:/Users/sunies/Desktop" + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); /* cfg.setFileCreate(new IFileCreate() { @Override public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) { // 判断自定义文件夹是否需要创建 checkDir("调用默认方法创建的目录"); return false; } }); */ injectionConfig.setFileOutConfigList(focList); return injectionConfig; } /** * 配置模板 * * @return */ private static TemplateConfig templateConfig() { TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板 //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 // templateConfig.setEntity("templates/entity2.java"); // templateConfig.setService(); // templateConfig.setController(); templateConfig.setXml(null); return templateConfig; } }
- [置顶] SSM框架——详细整合教程(Spring+SpringMVC+MyBatisPlus+Maven)
- MyBatis Plus工具快速入门使用教程
- Mybatis Plus的相关使用教程与扩展
- SpringBoot整合MybatisPlus的简单教程实现(简单整合)
- MyBatis实战教程之四增删改查操作
- (整理)MyBatis入门教程
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- mybatis简明教程
- 大型SpringMVC,Mybatis,Redis,Solr,Nginx,SSM分布式电商项目视频教程下载
- MyBatis,Spring整合简易教程
- MyBatis实用教程
- MyBatis使用教程(入门级)
- mybatis多对多关联实战教程(推荐)
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)
- SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)
- mybatis实战教程(mybatis in action)之二:以接口的方式编程
- Spring+SpringMVC+MyBatis详细整合教程
- MyBatis入门学习教程