MybatisPlus学习笔记(一)
概述
MybatisPlus是一款Mybatis增强工具,用于简化开发,提高效率。 它在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
基本配置
Maven依赖
- mybatis-plus
- mysql驱动
数据源配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mp_db?characterEncoding=utf-8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
创建Mapper接口
第一步,创建Mapper接口继承BaseMapper接口。
BaseMapper提供了很多常用方法,我们不需要去自己编写Sql语句。(狂喜)
第二步,扫描包,也可以直接加上 @Mapper
注解。
@MapperScan("cn.cagurzhan.mapper")
常用配置
表映射规则
- 默认情况下:泛型指定的实体类类名就是表名。如果不一致需要自己配置。
- 单独配置:entity实体类上加注解
@TableName("tb_user")
- 全局表名前缀:
mybatis-plus:
global-config:
db-config:
table-prefix: tb_
主键生成策略
- 默认情况:基于雪花算法的自增id。
雪花算法(Snowflake)是一种生成分布式全局唯一ID的算法,生成的ID称为Snowflake IDs或snowflakes。 这种算法由Twitter创建,并用于推文的ID。
-
实体类的属性(对应表的字段):加上注解
@TableId(type=IdType.AUTO)
- IdType的取值如下:
- AUTO:数据库ID自增。依赖于数据库。
- NONE:根据主键全局策略自动生成。
- INPUT:手动设置主键。 不设置,插入的时候主键是null
- ASSIGN_ID:当实体类主键属性为空,才会填充。使用雪花算法。
- ASSIGN_UUID:当实体类主键属性为空,才会填充,使用UUID。
-
全局设置:
mybatis-plus:
global-config:
db-config:
# id生成策略 auto为数据库自增
id-type: auto
字段映射
- 默认:根据实体类属性名映射表中的字段名。
- 如果不一致:字段上加上注解
@TableField(value="")
字段和列名驼峰映射
- **默认开启!**形式:Java中userName -- Sql中 user_name
- 关闭:
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
核心方法
基本使用
- 插入:
mapper.insert(实体类)
- 删除:
mapper.deleteXXX()
- 可以是BatchIds,传入id的集合。
- 可以是单个Id
- 可以是Map
- 更新:
mapper.updateXXX(实体类)
- 可以是Id
- 可以是实体类
条件构造器
条件构造器Wrapper可以帮助我们方便的构造条件。
UML图
- AbstractWrapper提供了用来构造 where的方法。
- QueryWrapper子类提供针对 select的语法。
- UpdateWrapper子类提供针对 set的语法。
- 方法文档:方法文档
- 包括eq、lte、gt、gte、like、between、notLike等等。
演示AbstractWrapper方法
默认用AND连接。
//and
QueryWrapper wrapper = new QueryWrapper();
wrapper.gt("age",18);
wrapper.eq("address","四川成都");
wrapper.in("id",1,2,3);
wrapper.between("like",10,29);
wrapper.like("name","Zhan"); //%Zhan%
wrapper.orderByDesc("age"); //降序
List<User> users = userMapper.selectList(wrapper);
演示QueryWrapper方法
select(要查询的列们)
select(实体类.class, Predicate)
select(Predicate)
//第一种
wrapper.select("id","user_name");
List<User>users = mapper.selectList(wrapper);
//第二种
wrapper.select(User.class,new Predicate<TableFieldInfo>(){
public boolean test(TableFieldInfo info){
return "user_name".equals(info.getColumn());
}
});
mapper.selectList(wrapper);
//第三种
queryWrapper.select(new Predicate<TableFieldInfo>() {
@Override
public boolean test(TableFieldInfo tableFieldInfo) {
return !"address".equals(tableFieldInfo.getColumn());
}
});
演示UpdateMapper方法
前面的update需要传入一个实体类,如果修改的列比较少,创建这样一个对象显得有点麻烦和复杂。
好消息,好消息,UpdateWrapper提供了set方法来设置要更新的列及其值。
//把id大于1的用户年龄改为99
uwrapper.gt("id",1);
uwrapper.set("age",99);
mapper.update(null,uwrapper);
Lambda条件构造器
前面的条件构造器都是用字符串来确定列名,这种方式有一个弊端: 无法在编译期确定列名的合法性。
Lambda条件构造器:直接以实体类的方法引用的形式来指定列名。
方法引用语法见jdk8函数式编程新特性。
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge,18);
wrapper.eq(User::getAddress,"成都");
mapper.selectList(wrapper);
自定义SQL
复杂的SQL需要我们自己来定义方法,写对应的SQL。
Mybatis方式
- 第一步,Mapper接口中定义方法。
- 比如:
User findUser(Long id)
- 比如:
- 第二步,创建XML。
- resources/mapper
- 先配置XML文件存放目录。
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
- 第三步,XML文件中映射文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.cagurzhan.mpdemo3.mapper.UserMapper">
<select id="findMyUser" resultType="cn.cagurzhan.mpdemo3.domain.User">
select * from tb_user where id=#{id}
</select>
</mapper>
mybatis方式集合wrapper
-
第一步,添加Wrapper类型参数的方法。
- 注解是为了在xml中获取名字,
Constants.WRAPPER
就是:ew。 User findUserByWrapper(@param(Constants.WRAPPER) Wrapper<User> wrapper)
- 注解是为了在xml中获取名字,
-
XML
<select id="findMyUserByWrapper" resultType="cn.cagurzhan.mpdemo3.domain.User">
select * from tb_user ${ew.customSqlSegment}
</select>
分页查询
基本分页查询
配置分页查询拦截器
- 创建
cn.cagurzhan.mpdemo.config.MybatisPlusConfig
@Configuration
public class PageConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
分页查询
IPage<User> page = new Page<>();
//每页条数
page.setSize(2);
//查询第几页
page.setCurrent(1);
mapper.selectPage(page,null);
//可以使用方法获得页数的数据
page.getRecord();//获取当前页数据
page.getTotal();//获取总记录数
page.getCurrent();//获得当前页数
多表分页查询
多表分页查询需要在mapper中自定义方法,方法参数是Page。其它的交给mybatis吧!
- 第一步,定义接口中的方法
IPage<Orders> findAllOrders(Page<Orders> page);
- 第二步,XML中写SQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sangeng.mapper.OrdersMapper">
<select id="findAllOrders" resultType="cn.cagurzhan.mpdemo3.domain.Orders">
SELECT
o.*,u.user_name
FROM
tb_user u
JOIN
tb_orders o
ON
u.id = o.user_id
</select>
</mapper>
Service层接口
Mp提供了Service层的实现,只需要编写接口继承IService,再创建一个接口实现类继承ServiceImpl,即可享用。
Service层支持了更多的批量操作方法。
- 之前:需要自己在service中注入mapper。
- 改造后:
//服务类接口
public interface UserService extends IService<User>{
}
//实现类
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService{
}
//测试,直接调用service的方法
service.list();
自定义方法
其它的mapper需要自己注入再使用。
代码生成器
配置
- 依赖
mybatis-plus-generator
freemaker
- 生成器配置
public class GeneratorTest {
@Test
public void generate() {
AutoGenerator generator = new AutoGenerator();
// 全局配置
GlobalConfig config = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
// 设置输出到的目录
config.setOutputDir(projectPath + "/src/main/java");
config.setAuthor("cagur");
// 生成结束后是否打开文件夹
config.setOpen(false);
// 全局配置添加到 generator 上
generator.setGlobalConfig(config);
// 数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mp_db?characterEncoding=utf-8&serverTimezone=UTC");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("root");
// 数据源配置添加到 generator
generator.setDataSource(dataSourceConfig);
// 包配置, 生成的代码放在哪个包下
PackageConfig packageConfig = new PackageConfig();
packageConfig.setParent("cn.cagurzhan.mp.generator");
// 包配置添加到 generator
generator.setPackageInfo(packageConfig);
// 策略配置
StrategyConfig strategyConfig = new StrategyConfig();
// 下划线驼峰命名转换
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
// 开启lombok
strategyConfig.setEntityLombokModel(true);
// 开启RestController
strategyConfig.setRestControllerStyle(true);
generator.setStrategy(strategyConfig);
generator.setTemplateEngine(new FreemarkerTemplateEngine());
// 开始生成
generator.execute();
}
}
- 感谢你赐予我前进的力量