1、什么是 MyBatis-Plus
Mybatis-Plus:为简化开发而生
MyBatis-Plus(简称 MP)是一个基于 MyBatis 的增强工具,它对 Mybatis 的基础功能进行了增强,但未做任何改变。使得我们可以可以在 Mybatis 开发的项目上直接进行升级为 Mybatis-plus,正如它对自己的定位,它能够帮助我们进一步简化开发过程,提高开发效率。
Mybatis-Plus 其实可以看作是对 Mybatis 的再一次封装,升级之后,对于单 表的 CRUD 操作,调用 Mybatis-Plus 所提供的 API 就能够轻松实现,此外还提供了各种查询方式、分页等行为。最最重要的,开发人员还不用去编写 XML,这就大大降低了开发难度
2、快速使用
1、导入依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.4</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.5.1</version>
</dependency>
2、 配置数据库参数
spring.datasource.password=*******
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.url=jdbc:mysql://localhost:3306/library?serverTimezone=UTC
#mybatis的日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
3、建一个数据库表
4、文件目录
5、实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
@TableId
int bookId;
String bookName;
int bookCounts;
String detail;
@TableField(fill= FieldFill.INSERT)
private Date createTime;
@TableField(fill=FieldFill.INSERT_UPDATE)
private Date updateTime;
@Version
@TableField(fill= FieldFill.INSERT)
private Integer version;
}
6、做表映射
@Repository
public interface BookMapper extends BaseMapper<Book> {
}
7、 可以开始测试
3、一般用法
(1).查找和更新操作
/**
* 插入用户表一条数据
*/
@Test
public void testInsert(){
Book b1=new Book();
b1.setBookName("《xxxxxx》");
b1.setBookCounts(299);
b1.setDetail("学会使用常用的linux指令");
int result=bookMapper.insert(b1);
System.out.println(result);
}
/**
* 根据多个id查询
*/
@Test
public void testSelectBatchIds(){
List<Book> books=bookMapper.selectBatchIds(Arrays.asList(1,2,3));
books.forEach(System.out::println);
}
/**
* 简单的条件查询,通过map封装查询条件
*/
@Test
public void testSelectMap(){
HashMap<String,Object> map=new HashMap<>();
map.put("book_name","《爱迪生的伟大发明》");
// map.put("detail","睡前小故事");
List<Book> books=bookMapper.selectByMap(map);
books.forEach(System.out::println);
}
/**
* 通过id修改用户信息
*/
@Test
public void testUpdateById(){
Book b=new Book();
b.setBookId(15);
b.setBookName("《Linux私房菜》");
b.setDetail("好好学习指令 这是3.0版本");
b.setBookCounts(100);
int res=bookMapper.updateById(b);
System.out.println(res);
}
(2) . 乐观锁使用
1. 编写配置类,加入官方给的拦截器功能 ,分页也是这个 一同加上了,表中的version字段要记得写上。
/**
* 乐观锁插件
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//配置乐观锁
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//配置分页
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
/**
* 测试乐观锁插入
*/
@Test
public void testOptimisticLocker(){
Book b1=new Book();
b1.setBookName("《深技大入场券》");
b1.setBookCounts(33);
b1.setDetail("我来了,神技大");
int result=bookMapper.insert(b1);
System.out.println(result);
}
/**
* 测试乐观锁更新
*/
@Test
public void testUpdateByIdOptimisticLocker(){
//必须查询才能更新
Book b=bookMapper.selectById(16);
b.setBookId(16);
b.setBookName("《深技大入场券》");
b.setDetail("我来了,神技大 一定要上");
b.setBookCounts(999);
int res=bookMapper.updateById(b);
System.out.println(res);
}
(3). 删除操作
/**
* 根据id删除
*/
@Test
public void testDeleteById(){
int id=bookMapper.deleteById(17);
System.out.println(id);
}
/**
* 批量删除数据
*/
@Test
public void testDeleteBatchByIds(){
int result=bookMapper.deleteBatchIds(Arrays.asList(18,19));
System.out.println(result);
}
/**
* 条件删除
*/
@Test
public void testDeleteByMap(){
//DELETE FROM book WHERE book_counts = ?
HashMap<String,Object> map=new HashMap<>();
map.put("book_counts",299);
int result=bookMapper.deleteByMap(map);
}
(4)分页查询
/**
* 分页查询
*/
@Test
public void testSelectPage(){
//current 目前的
Page<Book> page=new Page<>(1,5);
bookMapper.selectPage(page, Wrappers.<Book>lambdaQuery().ge(Book::getBookId,2));
List<Book> record=page.getRecords();
record.forEach(System.out::println);
//常用方法
// boolean hasNext=page.hasNext();
// boolean hasPrevious=page.hasPrevious();
// System.out.println(hasNext+" "+hasPrevious);
}
4. 复杂查询
Mybatis-Plus提供了两个常用类处理复杂查询操作,QueryWrapper和UpdateWrapper
/**
* 复杂查询的
* ge gt le lt isNull isNotNull的用法
*/
@Test
public void testQueryWrapper1(){
QueryWrapper<Book> query=new QueryWrapper<>();
//SELECT COUNT(*) AS total FROM book WHERE (book_counts >= ? AND book_name IS NOT NULL)
query.ge("book_counts",60).isNotNull("book_name");
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// WHERE (book_counts >= ? AND book_name IS NOT NULL) LIMIT ?
Page<Book> page=new Page<>(1,5);
bookMapper.selectPage(page,query);
page.getRecords().forEach(System.out::println);
}
/**
*
* 复杂查询的
* eq ne的用法
*/
@Test
public void testQueryWrapper2(){
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("book_id",13);
Book book=bookMapper.selectOne(queryWrapper);
System.out.println(book);
}
/**
*
* 复杂查询的
* between notBetween的用法
*/
@Test
public void testQueryWrapper3(){
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// WHERE (book_counts BETWEEN ? AND ?)
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
queryWrapper.between("book_counts",20,60);
List<Book> book=bookMapper.selectList(queryWrapper);
book.forEach(System.out::println);
}
/**
*
* 复杂查询的
* allEq的用法
*/
@Test
public void testQueryWrapper4(){
HashMap<String,Object> map=new HashMap();
map.put("book_name","《1003夜》");
map.put("detail","睡前小故事");
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// WHERE (detail = ? AND book_name = ?)
queryWrapper.allEq(map);
List<Book> l=bookMapper.selectList(queryWrapper);
l.forEach(System.out::println);
}
/**
*
* 复杂查询的
* like notLike likeLeft likeRight
*/
@Test
public void testQueryWrapper5(){
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
queryWrapper.like("book_name","ql")
.notLike("book_name","no");
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// WHERE (book_name LIKE ? AND book_name NOT LIKE ?)
List<Map<String,Object>> list=bookMapper.selectMaps(queryWrapper);
System.out.println(list);
}
/**
*
* 复杂查询的
* in notIn inSql notInSql exist notExists
*/
@Test
public void testQueryWrapper6(){
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
queryWrapper.inSql("book_id","select book_id from Book where book_id<10");
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// WHERE (book_id IN (select book_id from Book where book_id<10))
List<Object> bookIds=bookMapper.selectObjs(queryWrapper);
System.out.println(bookIds);
}
/**
*
* 复杂查询的
* or and
*/
@Test
public void testQueryWrapper7(){
UpdateWrapper<Book> updateWrapper=new UpdateWrapper<>();
Book book=new Book();
book.setBookId(15);
book.setBookName("《Linux私房菜》");
book.setBookCounts(81);
// UPDATE book SET book_name=?, book_counts=?, update_time=?
// WHERE (book_name LIKE ? OR book_counts LIKE ?)
updateWrapper.like("book_name","《Linux私房菜》").or().like("book_counts",15);
int result=bookMapper.update(book,updateWrapper);
System.out.println(result);
}
/**
*
* 复杂查询的
* 嵌套or 嵌套and
*/
@Test
public void testQueryWrapper8(){
UpdateWrapper<Book> updateWrapper=new UpdateWrapper<>();
Book book=new Book();
book.setBookId(13);
book.setBookName("《Mysql高级进阶》");
book.setBookCounts(88);
//UPDATE book SET book_name=?, book_counts=?, update_time=?
// WHERE (book_name LIKE ? OR (detail = ? AND book_counts <> ?))
//使用了lambda表达式,or中的表达式后面的条件会加上括号
updateWrapper.like("book_name","xxx")
.or(i->i.eq("detail","xxxxxx").ne("book_counts",999));
// UPDATE book SET book_name=?, book_counts=?, update_time=?
// WHERE (book_name LIKE ? OR detail = ? AND book_counts <> ?)
// updateWrapper.like("book_name","xxx")
// .or().eq("detail","xxxxxx").ne("book_counts",999);
int result=bookMapper.update(book,updateWrapper);
System.out.println(result);
}
/**
*
* 复杂查询的
* 9.orderBy orderByDesc orderByAsc
*/
@Test
public void testQueryWrapper9(){
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// ORDER BY book_id ASC
// orderBy(执行条件,'是否正序',排序的列)
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
queryWrapper.orderBy(true,true,"book_id");
List<Book> books=bookMapper.selectList(queryWrapper);
System.out.println(books);
}
/**
*
* 复杂查询的
* 10.last
* 只能调用一次,多次调用以最后一次为准 有sql注入的风险
*/
@Test
public void testQueryWrapper10(){
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
//SELECT book_id,book_name,book_counts,detail,create_time,update_time,version FROM book
// limit 1
queryWrapper.last("limit 1");
Book book=bookMapper.selectOne(queryWrapper);
System.out.println(book);
}
/**
*
* 复杂查询的
* 11. 指点呀查询的列
*/
@Test
public void testQueryWrapper11(){
QueryWrapper<Book> queryWrapper=new QueryWrapper<>();
//SELECT book_id,book_name FROM book
queryWrapper.select("book_id","book_name");
List<Book> list=bookMapper.selectList(queryWrapper);
list.forEach(System.out::println);
}
/**
*
* 复杂查询的
* 12. set setSql
*/
@Test
public void testQueryWrapper12(){
UpdateWrapper<Book> updateWrapper=new UpdateWrapper<>();
Book book=new Book();
book.setDetail("xxxx");
//UPDATE book SET book_counts=?, detail=?, update_time=?, book_name=?,book_counts=?
// WHERE (book_name LIKE ? OR book_id BETWEEN ? AND ?)
updateWrapper.like("book_name","《xxxxxxxxx》")
.or()
.between("book_id",1,20)
.set("book_name","《Redis入门学习》")
// .setSql("detail='学好努力做缓存'")
.set("book_counts",50);
int result=bookMapper.update(book,updateWrapper);
System.out.println(result);
System.out.println(book);
}