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("完成");
	}

}

Test

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

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

LambdaQueryWrapper<Book> queryWrapper = new QueryWrapper<Book>().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。

第一个数据源
@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();
	}

}

第二个数据源
@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();
	}

}

踩坑-乐观锁

官网上的示例:

@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();

}