目录
前言
mybatis-plus和mybatis相当于两兄弟,他简化了mybatis但是却没有影响mybatis
其实就是mapper继承了BaseMapper<实体类名称>然后就可以引用写好的CRUD
官网链接
https://baomidou.com/guide/quick-start.html
有些官网有的我就不写了
注意
不要同时导入mybatis和mybatis_plus,可能会出问题
CRUD
别忘了先引用mapper
@Autowired
UserMapper userMapper;
主键和雪花策略
数据库不要忘记自增 然后实体类id上添加
@TableId(type = IdType.AUTO)
雪花策略为默认id显示的公式,具体可以自己深究
增
@Test
public void InsertTest(){
User user = new User();
user.setName("AA");
user.setAge(11);
user.setEmail("1111@qq.com");
int insert = userMapper.insert(user);
System.out.println(insert);
System.out.println(user);
}
删
多条件删除 map
另外两个跟查一样,可以看看查
//通过map删除
@Test
public void testDelete(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","Tom");
userMapper.deleteByMap(map);
}
逻辑删除又叫软删除(其实就是把删除变成了更新)
1.数据库添加一个int类型默认值为0的字段deleted
2.实体类上加注解@TableLogic
3.在配置类上配置逻辑删除(以下以application为例)
# 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
mybatis-plus.global-config.db-config.logic-delete-field=flag
# 逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0
4.找个删除代码操作就完事了
@Test
public void testDelete(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","Jack");
userMapper.deleteByMap(map);
}
注意当添加了逻辑删除之后查询结果不会有什么变化,但是其实sql改变了
改
@Test
public void UpdateTest(){
User user = new User();
//通过条件自动拼接sql
user.setId(6L);
user.setName("BB");
user.setAge(22);
user.setEmail("1BB@qq.com");
//表面上是ById但其实是传整个参数
int update = userMapper.updateById(user);
System.out.println(update);
}
查
查询全部
@Test
void contextLoads() {
//queryWrapper
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
关键字查询
@Test
public void testSelectById(){
User user = userMapper.selectById(2L);
System.out.println(user);
}
批量查询
@Test
public void testSelectByBatchId(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1,2,3));
System.out.println("//");
System.out.println(users);
System.out.println("------------------");
users.forEach(System.out::println);
}
多条件查询 map
@Test
public void testSelectByBatchIds(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","AA");
map.put("age",11);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
分页查询
1.导入分页代码
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
2.直接使用
//分页查询
@Test
public void testPage(){
//第一个是页数,第二个是条数
Page<User> page = new Page<>(1,10);
userMapper.selectPage(page,null);
//便利输出
page.getRecords().forEach(System.out::println);
//输出总条数
System.out.println(page.getTotal());
}
条件构造器Wrapper
wrapper可以代替一些功能复杂的sql
查询name不为空且age大于等于22的人
@Test
//查询name不为空且age大于等于22的人
void contextLoads() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
.ge("age",22);
userMapper.selectList(wrapper).forEach(System.out::println);
}
通过一个条件查
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("","");
Mapper.SelectOne(Wrapper)
查询age在20到30间的人数
@Test
void contextLoads2() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",20,30);
Long aLong = userMapper.selectCount(wrapper);
System.out.println(aLong);
}
模糊查询,查询名字中带a的
@Test
void contextLoads3() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name","a");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}
嵌套子查询
这是打印的sql后半句是这样的
WHERE(id IN (select id from user where id<4))
@Test
void contextLoads4() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id","select id from user where id<4");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}
通过id升序查询
@Test
void contextLoads5() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("id");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
插件及扩展
自动填充处理
1.在数据库添加datetime类型的两个字段 create_time和update_time
2.在实体类上添加注解
//字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
3.创建一个自定义handler实现MetaObjectHandler
@Slf4j
//一定不要忘记把处理器加到IOC容器中
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
//插入时填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill...");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//更新时填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill...");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
4.再次运行增或改,会发现这两个字段自动更新了
乐观锁配置
乐观锁即非常乐观,认为所有事务都是没改变的,所以不会加锁,而是使用version来控制事务是否可以改变
1.在数据库添加version字段,默认为1
2.在实体类添加注解@Version
3.编写一个config来注册乐观锁插件
这时候可以把application里的扫描文件夹放进去
//扫描mapper文件夹
@MapperScan("com.hxz.mapper")
@EnableTransactionManagement
//配置类
@Configuration
public class MybatisPlusConfig {
//注册乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
4.最后在测试类中测试代码
//测试成功乐观锁
@Test
public void testMybatisPlusInterceptor1(){
User user = userMapper.selectById(1L);
user.setName("SBB");
user.setAge(88);
userMapper.updateById(user);
}
//测试失败乐观锁
@Test
public void testMybatisPlusInterceptor2(){
User user1 = userMapper.selectById(1L);
user1.setName("BBS");
user1.setAge(66);
User user2 = userMapper.selectById(1L);
user2.setName("SBB");
user2.setAge(88);
userMapper.updateById(user2);
userMapper.updateById(user1);
}
Mybatis-Plus自动生成策略
其实很简单
1.创建数据库
2.创建项目并配置application.properties
3.创建一个测试类,编写代码生成器即可
// 代码自动生成器
public class ZiDongCode {
public static void main(String[] args) {
// 需要构建一个 代码自动生成器 对象
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("HXZ");
gc.setOpen(false);
gc.setFileOverride(false); // 是否覆盖
gc.setServiceName("%sService"); // 去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("1052600676");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("blog");
pc.setParent("com.hxz");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("jd_depositrate1"); // 设置要映射的表名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); // 自动lombok;
strategy.setLogicDeleteFieldName("deleted");
// 自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified",
FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
//localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); //执行
}
}