MyBatis-Plus 简单使用

2021/6/11 posted in  MySQL

MyBatis-Plus 是 MyBatis 的一个增强工具,目的是为了简化开发,提高效率。

SpringBoot 集成

添加依赖

<springboot.version>2.3.0.RELEASE</springboot.version>

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.1</version>
</dependency>
<!-- -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

代码生成

mybatis-plus-generator 代码生成器可以生成 controllerentitymapperservicemapper.xml,只要定义好了表结构,使用代码生成器生成代码,即可使用 CRUD

代码生成工具demo ``` public class CreateCode {
public static void main(String[] args) {
	String packageName = "com.hitol.mybatisplusdemo";
	String projectPath = System.getProperty("user.dir") + "/src/main/java";

	// 代码生成器
	AutoGenerator mpg = new AutoGenerator();

	// 全局配置
	GlobalConfig gc = new GlobalConfig();
	// 生成的代码放哪里
	gc.setOutputDir(projectPath);
	gc.setAuthor("hitol");
	gc.setOpen(false);

	gc.setBaseResultMap(true);// XML ResultMap
	gc.setBaseColumnList(true);// XML columList
	//gc.setMapperName("%sDao");
	gc.setServiceName("%sService");
	gc.setServiceImplName("%sServiceImpl");
	mpg.setGlobalConfig(gc);

	// 数据源配置
	DataSourceConfig dsc = new DataSourceConfig();
	dsc.setUrl("jdbc:mysql://localhost:3306/book?useUnicode=true&useSSL=false" +
			"&characterEncoding=utf8");
	dsc.setDriverName("com.mysql.jdbc.Driver");
	dsc.setUsername("root");
	dsc.setPassword("123456");
	mpg.setDataSource(dsc);

	// 包配置
	PackageConfig pc = new PackageConfig();
	pc.setModuleName("");
	// 工程的包名
	pc.setParent(packageName);
	mpg.setPackageInfo(pc);

	//要想输出xml文件,需要额外自定义添加进去
	String templatePath = "/templates/mapper.xml.vm";
	InjectionConfig cfg = new InjectionConfig() {
		@Override
		public void initMap() {
		}
	};
	// 自定义输出配置
	List<FileOutConfig> focList = new ArrayList<FileOutConfig>();

// // 自定义配置会被优先输出,可以生成 xml 文件
// focList.add(new FileOutConfig(templatePath) {
// @Override
// public String outputFile(TableInfo tableInfo) {
// // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
// return System.getProperty("user.dir") + "/src/main/resources/mapper/" + pc.getModuleName()
// + "/" + tableInfo.getEntityName() + "Mapper.xml";
// }
// });

	cfg.setFileOutConfigList(focList);
	mpg.setCfg(cfg);

	// 配置模板
	TemplateConfig templateConfig = new TemplateConfig();
	templateConfig.setXml(null);
	mpg.setTemplate(templateConfig);

	// 策略配置
	StrategyConfig strategy = new StrategyConfig();
	// 这个配置是强制所有字段都有 TableField 注解
	strategy.entityTableFieldAnnotationEnable(true);
	//strategy.setInclude(可选择要生成的表名,多个英文逗号分割);
	strategy.setNaming(NamingStrategy.underline_to_camel);
	strategy.setColumnNaming(NamingStrategy.underline_to_camel);
	strategy.setControllerMappingHyphenStyle(true);

	mpg.setStrategy(strategy);
	mpg.setTemplateEngine(new VelocityTemplateEngine());
	mpg.execute();
	System.out.println("完成");
}

}

</details>


### Test

List list = bookService.list();
System.out.println(JSONObject.toJSONString(list));

Book book = bookService.getById(1);
System.out.println(JSONObject.toJSONString(book));

LambdaQueryWrapper queryWrapper = new QueryWrapper().lambda();
queryWrapper.eq(Book::getBookName,"xxxx1");
Book one = bookService.getOne(queryWrapper);
System.out.println(JSONObject.toJSONString(one));


## 多数据源配置

通过多个 config 来配置多个数据源,每个 config 中通过指定不同的 basePackages、sqlSessionTemplateRef 实现多数据源。

主数据源中的 @Bean 需要加注解 Primary,在 Spring 加载过程中会优先加载 Primary 标注的 bean。

<details>
<MAXmary>第一个数据源</MAXmary>

@Configuration
@MapperScan(basePackages = "com.hitol.mybatisplusdemo.mapper",
sqlSessionTemplateRef="ds1SqlSessionTemplate")
public class MyBatisPlusConfig {

/**
 * mybatis-plus分页插件<br>
 * 文档:https://mp.baomidou.com/guide/page.html <br>
 */
@Bean
public PaginationInterceptor paginationInterceptor() {
	// paginationInterceptor.setLimit(你的最大单页限制数量,默认 500 条,小于 0 如 -1 不受限制);
	return new PaginationInterceptor();
}


/**
 *	主数据源 ds1数据源
 */
@Primary
@Bean("ds1SqlSessionFactory")
public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {
	MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
	sessionFactoryBean.setDataSource(dataSource);
	sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/general/*.xml"));
	return sessionFactoryBean.getObject();

}

@Primary
@Bean(name = "ds1TransactionManager")
public DataSourceTransactionManager ds1TransactionManager(@Qualifier("ds1DataSource") DataSource dataSource) {
	return new DataSourceTransactionManager(dataSource);
}

@Primary
@Bean(name = "ds1SqlSessionTemplate")
public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
	return new SqlSessionTemplate(sqlSessionFactory);
}

//JdbcTemplate主数据源ds1数据源
@Primary
@Bean(name = "ds1JdbcTemplate")
public JdbcTemplate ds1JdbcTemplate(@Qualifier("ds1DataSource") DataSource dataSource) {
	return new JdbcTemplate(dataSource);
}
//主数据源配置 ds1数据源
@Primary
@Bean(name = "ds1DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSourceProperties ds1DataSourceProperties() {
	return new DataSourceProperties();
}

//主数据源 ds1数据源
@Primary
@Bean(name = "ds1DataSource")
public DataSource ds1DataSource(@Qualifier("ds1DataSourceProperties") DataSourceProperties dataSourceProperties) {
	return dataSourceProperties.initializeDataSourceBuilder().build();
}

}

</details>


<details>
<MAXmary>第二个数据源</MAXmary>

@Configuration
@MapperScan(basePackages = "com.hitol.mybatisplusdemo.chinespoetry.mapper",
sqlSessionTemplateRef="ds2SqlSessionTemplate")
public class MyBatisPlusConfig2 {

/**
 * mybatis-plus分页插件<br>
 * 文档:https://mp.baomidou.com/guide/page.html <br>
 */
@Bean("paginationInterceptor2")
public PaginationInterceptor paginationInterceptor() {
	// paginationInterceptor.setLimit(你的最大单页限制数量,默认 500 条,小于 0 如 -1 不受限制);
	return new PaginationInterceptor();
}



/**
 *	主数据源 ds2数据源
 */
@Bean("ds2SqlSessionFactory")
public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("ds2DataSource") DataSource dataSource) throws Exception {
	MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
	sessionFactoryBean.setDataSource(dataSource);
	sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/general/*.xml"));
	return sessionFactoryBean.getObject();

}


@Bean(name = "ds2TransactionManager")
public DataSourceTransactionManager ds2TransactionManager(@Qualifier("ds2DataSource") DataSource dataSource) {
	return new DataSourceTransactionManager(dataSource);
}


@Bean(name = "ds2SqlSessionTemplate")
public SqlSessionTemplate ds2SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
	return new SqlSessionTemplate(sqlSessionFactory);
}

//JdbcTemplate ds2数据源
@Bean(name = "ds2JdbcTemplate")
public JdbcTemplate ds2JdbcTemplate(@Qualifier("ds2DataSource") DataSource dataSource) {
	return new JdbcTemplate(dataSource);
}
//数据源配置 ds2数据源
@Bean(name = "ds2DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSourceProperties ds2DataSourceProperties() {
	return new DataSourceProperties();
}

//数据源 ds2数据源
@Bean(name = "ds2DataSource")
public DataSource ds2DataSource(@Qualifier("ds2DataSourceProperties") DataSourceProperties dataSourceProperties) {
	return dataSourceProperties.initializeDataSourceBuilder().build();
}

}

</details>


## 踩坑-乐观锁

官网上的示例:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}


根据官方文档配置后,一般情况下可以正常使用的,但是如果自己生成了 sqlSessionFactory 需要将乐观锁拦截器添加下

public MyOptimisticLockerInterceptor optimisticLockerInterceptor(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
MyOptimisticLockerInterceptor myOptimisticLockerInterceptor = new MyOptimisticLockerInterceptor();
sqlSessionFactory.getConfiguration().addInterceptor(myOptimisticLockerInterceptor);
return myOptimisticLockerInterceptor;
}


## 踩坑-自动填充功能
官网示例:https://mp.baomidou.com/guide/auto-fill-metainfo.html

如果自己生成了 sqlSessionFactory,需要将自定义的 handler 加到 GlobalConfig 中。

@Primary
@Bean("ds1SqlSessionFactory")
public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/manager/*.xml"));
GlobalConfig gc = new GlobalConfig();
gc.setMetaObjectHandler(metaObjectHandler());
sessionFactoryBean.setGlobalConfig(gc);
return sessionFactoryBean.getObject();

}