MyBatis-Plus
MyBatis-Plus
内容总览:
简单测试
使用的数据库表:
内容信息:
1、在pom.xml中添加相关配置
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
为了方便测试,因此在pom.xml文件中添加测试所需要的依赖
xxxxxxxxxx
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
2、在application.yml中添加配置
xxxxxxxxxx
# 用于显示执行的sql语句
mybatis-plus
configuration
log-impl org.apache.ibatis.logging.stdout.StdOutImpl
3、创建数据库表对应的entity和mapper文件
User类:在创建该User类使用了lombok组件,可以简化类的编写。
@Data提供了getter和setter
@AllArgsConstructor提供全参构造函数
@NoArgsConstructor提供无参构造函数
x
public class User {
Integer id;
String name;
String password;
String mail;
String image;
}
Mapper类:直接继承BaseMapper
xxxxxxxxxx
public interface UserMapper extends BaseMapper<User> {
}
4、在启动类上添加Mapper文件的检索注解@MapperScan
xxxxxxxxxx
"com.example.mybatisplus.mapper") (
public class MybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisplusApplication.class, args);
}
}
5、测试
在项目文件的test文件夹中创建MapperTests测试类
xxxxxxxxxx
public class MapperTests {
UserMapper userMapper;
public void selectListTest(){
List<User> userList = userMapper.selectList(null);
userList.forEach(System.out::println);
}
}
6、执行结果
代码自动生成器(旧版本)
1、在pom.xml文件中添加相应依赖(同时也要有mybatis-plus-boot-starter依赖)
xxxxxxxxxx
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1.tmp</version>
</dependency>
在使用MyBatis-Plus中的代码自动生成器时,需要模板引擎,它支持Velocity(默认)、Freemaker、Beetl,
xxxxxxxxxx
<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity-engine-core -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ibeetl/beetl -->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
如果选择了非默认引擎,需要在AutoGenerator中配置相关引擎:
xxxxxxxxxx
AutoGenerator generator = new AutoGenerator();
// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());
// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());
// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());
// other config
...
在此我选择使用Velocity默认模板引擎,所以在pom.xml文件中添加如下依赖:
xxxxxxxxxx
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
踩坑:
在添加依赖时,并没有在pom.xml文件中配置org.apache.common:commons-lang3:3.10,但他报错显示没有找到该依赖,我从该网站commons-lang3下载commons-lang3.jar、commons-lang3-resources.jar、commons-lang3-javadoc.jar文件,然后拷贝到本地maven库当中就可以了
2、编辑数据库信息读取类
xxxxxxxxxx
public class SqlDataSourceConfig {
"${spring.datasource.url}") (
private String url;
"${spring.datasource.username}") (
private String userName;
"${spring.datasource.password}") (
private String password;
"${spring.datasource.driver-class-name}") (
private String driver;
}
编写该类是为了方便获取application.yml文件中的数据库连接配置信息
3、编写测试类
在test文件夹下创建AutoGeneratorConfigTests类
xxxxxxxxxx
class AutoGeneratorConfigTests {
//注入数据库配置信息类
private SqlDataSourceConfig sqlDataSourceConfig;
public void autoGeneratorTest(){
//1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
//2、全局配置
GlobalConfig gc = new GlobalConfig();
//获取项目路径
String projectPath = System.getProperty("user.dir");
//设置文件输出路径
gc.setOutputDir(projectPath+"/src/main/java");
//设置作者
gc.setAuthor("life");
//生成后是否打开文件夹
gc.setOpen(false);
//重新生成文件时是否覆盖
gc.setFileOverride(false);
mpg.setGlobalConfig(gc);
//3、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(sqlDataSourceConfig.getUrl());
dsc.setDriverName(sqlDataSourceConfig.getDriver());
dsc.setUsername(sqlDataSourceConfig.getUserName());
dsc.setPassword(sqlDataSourceConfig.getPassword());
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//4、包配置
PackageConfig pc = new PackageConfig();
//设置父包名
pc.setParent("com.example.mybatisplus");
//设置模块名
pc.setModuleName(null);
mpg.setPackageInfo(pc);
//5、策略配置
StrategyConfig strategyConfig = new StrategyConfig();
//设置要建立映射的数据库表,支持同事建立多个表
strategyConfig.setInclude("user","movie");
//数据库表映射到实体的命名策略
//strategyConfig.setNaming(NamingStrategy.underline_to_camel);
//生成实体时去掉表名前缀
//strategyConfig.setTablePrefix(pc.getModuleName()+"_");
//设置数据库表字段映射到实体的命名策略
//strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
//设置实体的Lombok的风格
strategyConfig.setEntityLombokModel(true);
//配置rest风格的Controller(@RestController)
//strategyConfig.setRestControllerStyle(true);
//配置驼峰转连字符
strategyConfig.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategyConfig);
//6、执行
mpg.execute();
}
}
4、执行结果展示
如果添加了模块名参数,则会在父包下的对应文件夹下输出文件。比如将pc.setMoudleName(null)改为pc.setMoudleName("test"),则会在mybatisplus目录下创建一个test文件夹,然后将文件输出到test文件夹下,上图的test文件夹就是按照此种方法产生的。
(ps:当项目启动时自动执行某一方法的一种策略
为了实现当项目启动时会自动执行代码自动生成的函数,我进行了如下操作:
创建一个带有@Component注解的类,其中包含了自定义的代码自动生成函数,并为该函数添加@PostConstruct注解,然后在启动类中设置@ComponentScan,扫描该类所在的包,当扫描到该类时,会自动执行带有@PostConstruct注解的函数。
xxxxxxxxxx
public class AutoGeneratorConfig {
SqlDataSourceConfig sqlDataSourceConfig;
public void AutoGenerator(){
//1、创建代码生成器
AutoGenerator mpg = new AutoGenerator();
//2、全局配置
GlobalConfig gc = new GlobalConfig();
//获取项目路径
String projectPath = System.getProperty("user.dir");
//设置文件输出路径
gc.setOutputDir(projectPath+"/src/main/java");
//设置作者
gc.setAuthor("life");
//生成后是否打开文件夹
gc.setOpen(false);
//重新生成文件时是否覆盖
gc.setFileOverride(false);
mpg.setGlobalConfig(gc);
//3、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(sqlDataSourceConfig.getUrl());
dsc.setDriverName(sqlDataSourceConfig.getDriver());
dsc.setUsername(sqlDataSourceConfig.getUserName());
dsc.setPassword(sqlDataSourceConfig.getPassword());
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//4、包配置
PackageConfig pc = new PackageConfig();
//设置父包名
pc.setParent("com.example.mybatisplus");
//设置模块名
pc.setModuleName(null);
mpg.setPackageInfo(pc);
//5、策略配置
StrategyConfig strategyConfig = new StrategyConfig();
//设置要建立映射的数据库表
strategyConfig.setInclude("user","movie");
//数据库表映射到实体的命名策略
//strategyConfig.setNaming(NamingStrategy.underline_to_camel);
//生成实体时去掉表名前缀
//strategyConfig.setTablePrefix(pc.getModuleName()+"_");
//设置数据库表字段映射到实体的命名策略
//strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
//设置实体的Lombok的风格
strategyConfig.setEntityLombokModel(true);
//配置rest风格的Controller(@RestController)
//strategyConfig.setRestControllerStyle(true);
//配置驼峰转连字符
strategyConfig.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategyConfig);
//6、执行
mpg.execute();
}
public void test(){
System.out.println("---------PostConstruct-----------");
}
}
xxxxxxxxxx
basePackages = {"com.example.mybatisplus.config","com.example.mybatisplus.mapper"}) (
//@MapperScan("com.example.mybatisplus.mapper")
public class MybatisplusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisplusApplication.class, args);
}
}
自定义sql语句
1、设置xml文件路径
在使用自定义sql语句时,首先要在application..yml中配置xml文件所在的位置,为了方便,我将生成的xml文件移动到了resources目录之下
在yml文件中添加配置语句:
xxxxxxxxxx
mybatis-plus
mapper-locations classpath xml/*Mapper.xml
2、在xml文件中添加所需要的查询语句
xxxxxxxxxx
<select id="getByName" resultType="com.example.mybatisplus.entity.User">
select *
from user
where name = #{name}
</select>
3、在mapper文件中添加对应的函数
xxxxxxxxxx
public interface UserMapper extends BaseMapper<User> {
User getByName(String name);
}
4、在Service中添加相关调用
5、运行结果
条件构造器
除了上述的原始自定义sql语句方法,还可以通过条件构造器Wrapper的方法,来实现自定义sql语句。
查询分页
1、创建配置类
创建一个配置类MyBatisPlusConfig,添加@Configuration注解,在其中创建方法PaginationInterceptor paginationInterceptor(),并为其添加@Bean注解交给Spring容器来管理。
xxxxxxxxxx
//@MapperScan("com.example.mybatisplus.mapper")
public class MyBatisPlusConfig {
/**
* 分页实例
* @return PaginationInterceptor
*/
public PaginationInterceptor paginationInterceptor(){
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInterceptor.setLimit(20);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
2、添加XML、Mapper、Service中的内容
xml文件中只需要写正常的查询语句就可以。
xxxxxxxxxx
<select id="selectAllByPage" resultType="com.example.mybatisplus.entity.Movie">
select *
from movie
</select>
<select id="selectByAreaByPage" resultType="com.example.mybatisplus.entity.Movie">
select *
from movie
where area = #{area}
</select>
Mapper文件中的内容如下:
xxxxxxxxxx
public interface MovieMapper extends BaseMapper<Movie> {
/**
* <p>
* 查询 : 根据state状态查询用户列表,分页显示
* </p>
*
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位(你可以继承Page实现自己的分页对象)
* @param state 状态
* @return 分页对象
*/
IPage<Movie> selectAllByPage(Page<?> page, Integer state);
IPage<Movie> selectByAreaByPage(Page<?> page, Integer state, ("area") String area);
}
Service文件中的内容:
xxxxxxxxxx
public class MovieServiceImpl extends ServiceImpl<MovieMapper, Movie> implements IMovieService {
MovieMapper movieMapper;
// 不进行 count sql 优化,解决 MP 无法自动优化 SQL 问题,这时候你需要自己查询 count 部分
// page.setOptimizeCountSql(false);
// 当 total 为小于 0 或者设置 setSearchCount(false) 分页插件不会进行 count 查询
// 要点!!!! 分页返回的对象与传入的对象是同一个
public IPage<Movie> selectAllByPage(Page<?> page, Integer state) {
return movieMapper.selectAllByPage(page,state);
}
public IPage<Movie> selectByAreaByPage(Page<?> page, Integer state, String area) {
return movieMapper.selectByAreaByPage(page, state, area);
}
}
3、测试
xxxxxxxxxx
public void pageTest(){
Page<Movie> page = new Page<>(5,2);
movieService.selectAllByPage(page,null);
System.out.println(page.getCurrent()); // 获取当前页
System.out.println(page.getTotal()); // 获取总记录数
System.out.println(page.getSize()); // 获取每页的条数
System.out.println(page.getRecords()); // 获取每页数据的集合
System.out.println(page.getPages()); // 获取总页数
System.out.println(page.hasNext()); // 是否存在下一页
System.out.println(page.hasPrevious()); // 是否存在上一页
}
xxxxxxxxxx
public void selectByAreaTest(){
Page<Movie> page = new Page<>(2,2);
movieService.selectByAreaByPage(page,null,"美国");
}
如果需要继续查看下一页,可以设置page对象的current属性,然后再调用一次查询函数进行查询。因为调用一次查询之后,page只会存储当前页的信息,并不会存储其他页的信息,所以需要其他页的数据时,需要重新查询。
xxxxxxxxxx
public void nextPageTest(){
Page<Movie> page = new Page<>(1,2);
movieService.selectAllByPage(page,null);
System.out.println(page.getCurrent());
System.out.println(page.getRecords());
page.setCurrent(page.getCurrent()+1);
movieService.selectAllByPage(page,null);
System.out.println(page.getCurrent());
System.out.println(page.getRecords());
}