Mybatis Plus
官网:MyBatis-Plus (baomidou.com)
在持久层框架中mybatis应用比较多,而且比重在逐渐的上升。通常项目的组合是SSM。mybatis 之所以火,是因为他的灵活,使用方便,优化比较容易。
mybatis的直接执行sql语句,sql语句是写在xml文件中,使用mybatis 需要多个xml配置文件,在一定程度上比较繁琐。一般数据库的操作都要涉及到CURD。
mybatis-plus是在mybatis 上的增强,减少了xml的配置,几乎不用编写xml就可以做到单表的CURD,很是方便,极大提供了开发的效率。我们写程序目的就是让生活更加简单。
快速启动
快速开始 | MyBatis-Plus (baomidou.com)
-
新建数据表并插入数据
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VN5MpL1R-1619833743488)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210428150631476.png)]](https://i-blog.csdnimg.cn/blog_migrate/297a2e31ae901f6146332a6aa9dc3a63.png)
-
导入依赖(mysql、mybatis-plus)
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> -
配置数据库连接信息
spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8 username: root password: root -
编写实体类
@Data @AllArgsConstructor @NoArgsConstructor public class User { /*指定主键的方式 value:主键字段的名称,如果是id,可以不用写。 type:指定主键的类型,主键的值如何生成。idType.AUTO表示自动增长。| * */ @TableId(value = "id",type = IdType.AUTO) private Integer id; private String name; private String email; private Integer age; } -
编写Dao接口
/* 自定义Mapper,就是Dao接口。 1.要实现BaseMapper 2.指定实体类 BaseMapper是MP框架中的对象,定义17个操作方法(CRUD) */ public interface UserMapper extends BaseMapper<User> { } -
在启动类注解上,加上mapperscan注解.
帮助我们找到相关的类和注解
//@MapperScan:扫描器,指定mapper类所在的包 @SpringBootApplication @MapperScan(value = "com.nanda.mapper") public class SpringbootMybatisplusApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisplusApplication.class, args); } } -
在测试类中测试
@SpringBootTest class SpringbootMybatisplusApplicationTests { //使用自动注入,注入mapper对象(dao) @Autowired private UserMapper userDao; //定义测试方法 //测试添加操作,insert @Test public void testInsert(){ //创建User对象 User user=new User(); user.setName("zs"); user.setAge(20); user.setEmail("10455@qq.com"); //调用usermapper的方法,也就是父接口basemapper中提供的方法 int rows=userDao.insert(user); System.out.println("insert 的结果"+rows); } }
使用MP的步骤:
-
新建springboot工程
-
指定maven的mp、mysql依赖
-
在配置文件中配好数据库连接
-
创建实体类 (1)定义属性 (2)指定主键的类型
-
创建Dao接口 ,需要继承BaseMapper< 实体.class>
-
在springboot的启动类上,加入@MapperScan(value=“指定Dao接口的包名”)
-
测试使用:
在测试类或service注入Dao接口,框架实现动态代理创建Dao的实现类对象
调用BaseMapper中的方法,完成CRUD
日志配置
在yaml文件中,加入如下
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
CRUD
insert
@SpringBootTest
class SpringbootMybatisplusApplicationTests {
//使用自动注入,注入mapper对象(dao)
@Autowired
private UserMapper userDao;
//定义测试方法
//测试添加操作,insert
@Test
public void testInsert(){
//创建User对象
User user=new User();
user.setName("zs");
user.setAge(20);
user.setEmail("10455@qq.com");
//调用usermapper的方法,也就是父接口basemapper中提供的方法
int rows=userDao.insert(user);
System.out.println("insert 的结果"+rows);
//获取主键id,刚添加数据库中的数据的id
int id=user.getId();
System.out.println("主键id:"+ id);
}
}
注: insert()返回值int,数据插入成功的行数,成功的记录数。getld()获取主键值,
update
更新所有非主键字段
//更新操作update @Test public void testUpdate(){ User user=new User(); user.setName("aaa"); user.setAge(99); user.setEmail("22222@qq.com"); user.setId(9); /*执行更新,根据主键值更新 UPDATE user SET name=?, email=?, age=? WHERE id=? 更新了所有非null属性值,条件where id =主键值*/ int rows = userDao.updateById(user); System.out.println("update rows:"+rows); }
控制更新的属性
//控制更新的属性 @Test public void testUpdate2(){ User user=new User(); user.setName("bbb"); user.setId(9); //更新数据 //UPDATE user SET name=? WHERE id=? int rows = userDao.updateById(user); System.out.println("update rows:"+rows); }
注意:如果实体类属性是基本类型,那么默认值为0而不是null。那么update的时候认为是有值的,不为null,就会把0放进去。
delete
按主键删除一条数据
/* * 按主键删除一条数据 * 方法是deleteById() * 参数:主键值 * 返回值:删除成功的记录数 * */ @Test public void testDeleteById(){ //DELETE FROM user WHERE id=? int rows=userDao.deleteById(9); System.out.println("deleteById:"+rows); }
按条件删除
/* * 按条件删除数据,条件是封装到map对象中 * 方法:deleteByMap(map对象) * 返回值:删除成功的记录数 * */ @Test public void testDeleteByMap(){ //创建map对象,保存条件值 Map<String, Object> map=new HashMap<>(); //put(“表的字段名”,条件值),可以封装多个条件 map.put("name","zs"); map.put("age",21); //调用删除方法 //DELETE FROM user WHERE name = ? AND age = ? int row = userDao.deleteByMap(map); System.out.println("deleteByMap:"+row); }
批量删除
/* * 批处理方式:使用多个主键值,删除数据 * 方法:deleteBatchIds() * 参数:Collection<? extends Serializable> var1 * 返回值:删除的记录数 * */ @Test public void deleteBatch(){/* List<Integer> ids=new ArrayList<>(); ids.add(1); ids.add(2); ids.add(3); ids.add(4); ids.add(5);*/ //使用lambda创建List集合 List<Integer> ids = Stream.of(6, 7, 8).collect(Collectors.toList()); //删除操作 //DELETE FROM user WHERE id IN ( ? , ? , ? , ? , ? ) int rows = userDao.deleteBatchIds(ids); System.out.println("deleteBatchIds:"+ids); }
select
根据主键id查询
/* * 实现查询selectById,根据主键值查询 * 参数:主键值 * 返回值:对象实体(唯一一个对象) * */ @Test public void testSelectById(){ //SELECT id,name,email,age FROM user WHERE id=? //如果根据主键没有查找到数据,得到的返回值是null User user = userDao.selectById(11); System.out.println("selectById:"+user); //再使用对象之前,需要判断对象是否为null if(user!=null){ //业务方法的调用 } }
注:没有查询结果,不会报错
批量查询记录
正常形式
/* * 根据id批量查询 * 方法:selectBatchIds * 参数:id的集合 * 返回值:List<T> * */ @Test public void selectBatchId(){ List<Integer> ids=new ArrayList<>(); ids.add(6); ids.add(10); ids.add(11); ids.add(21); //查询数据 //SELECT id,name,email,age FROM user WHERE id IN ( ? , ? , ? , ? ) List<User> users = userDao.selectBatchIds(ids); System.out.println("size:"+users.size()); for (User user : users) { System.out.println(user); } }
lambda表达式形式
/* * 使用lambda查询数据 * */ @Test public void selectBatchId2(){ List<Integer> ids = Stream.of(6, 10, 11, 22).collect(Collectors.toList()); //SELECT id,name,email,age FROM user WHERE id IN ( ? , ? , ? , ? ) List<User> users = userDao.selectBatchIds(ids); users.forEach(user -> { System.out.println("查询的user对象:"+ user); }); }
注:根据id查询记录,把需要查询的多个id存入到 List,调用selectBatchlds(),传入List,返回值也是 List。查询条件是from user where in id (1,2)
使用map的条件查询
/* * 使用Map做多条件查询 * 方法:selectByMap() * 参数:Map<String,Object> 返回值:List<T> * */ @Test public void testSelectByMap(){ //创建Map,封装查询条件 Map<String, Object> map=new HashMap<>(); //key是字段名,value是字段值,多个key,是and连接 map.put("name","zs0"); map.put("age",20); //根据map查询 //SELECT id,name,email,age FROM user WHERE name = ? AND age = ? List<User> users = userDao.selectByMap(map); users.forEach(user -> { System.out.println("selectByMap:"+user); }); }
更多的查询方式,在后面章节作为专题讲解。包括条件对象Wrapper,lambda表达式,分页查询等等。
ActiveRecord(AR)
ActiveRecord是什么:
- 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的Field;
- ActiveRecord负责把自己持久化.在ActiveRecord 中封装了对数据库的访问,通过对象自己实现CRUD,实现优雅的数据库操作。
- ActiveRecord 也封装了部分业务逻辑。可以作为业务对象使用。
初步搭建
-
新建实体类继承Model接口
必须继承Model,Model定义了表的 CRUD方法,Dept 属性名和列名是一样的。
/** 使用AR,要求实体类需要继承MP中的Model* Model中提供了对数据库的CRUD操作* */ @Data @AllArgsConstructor @NoArgsConstructorpublic class Dept extends Model { //定义属性,属性名和表的列名一样 @TableId(value = "id",type = IdType.AUTO) private Integer id; private String name; private String mobile; private Integer manager;} -
新建Dao接口继承BaseMapper
不使用mapper,也需要定义这个类,MP通过mapper获取到表的结构;不定义时,MP报错无法获取到表信息
/* * DeptMapper是不需要使用的,MP需要使用DeptMapper获取到数据库的表的信息。* 如果不定义DeptMapper,MP会报错,找不到表的定义信息* */public interface DeptMapper extends BaseMapper<Dept> {}
CRUD
insert
@Test public void testInsert(){ //定义dept的实体 Dept dept=new Dept(); dept.setName("销售部"); dept.setMobile("010-12345678"); dept.setManager(1); //调用实体对象自己的方法,完成对象自身到数据库的添加操作 //INSERT INTO dept ( name, mobile, manager ) VALUES ( ?, ?, ? ) boolean insert = dept.insert(); System.out.println("ar insert result:"+insert); }
update
创建实体对象,对要更新的属性赋值,null的属性不更新,根据主键更新记录。
返回值是boolean,true更新成功。没有更新记录是false。
@Test public void testUpdate(){ //定义dept的实体 Dept dept=new Dept(); dept.setId(1);// dept.setName("销售部"); dept.setMobile("010-1234567899");// dept.setManager(1); //null的属性值不做更新处理,再update中没有null的字段 //UPDATE dept SET mobile=? WHERE id=? boolean result = dept.updateById(); System.out.println("ar updateById result:"+result); }
delete
/* * deleteById()删除操作 * */ @Test public void testDeleteById(){ Dept dept=new Dept(); //DELETE FROM dept WHERE id=? boolean result = dept.deleteById(2); System.out.println("ar deleteById result:"+result); }
select
/* * selectById() * 1.按实体的主键能查找出数据,返回对象 * 2.按实体的主键不能查找出数据,返回null,不报错 * */ @Test public void testSelectById(){ Dept dept=new Dept(); dept.setId(1); //调用查询方法 如果不想强行转换,就给实体类的model加上泛型 //SELECT id,name,mobile,manager FROM dept WHERE id=? Dept model = (Dept) dept.selectById(); System.out.println(model); }
/* * selectAll():查询所有的 * */ @Test public void testSelectAll(){ Dept dept=new Dept(); List list = dept.selectAll(); System.out.println(list); }
表和列
主键、TableName、TableFileld
主键类型
ldType枚举类,主键定义如下:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfJJt4mS-1619833743491)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210429101526148.png)]](https://i-blog.csdnimg.cn/blog_migrate/4fe87a256908c398bbaadd9ac7f4ea9d.png)
- none没有主键
- auto自动增长(mysql,sql server)
- input手工输入
- id_worker:实体类用Long id ,表的列用bigint , int类型大小不够
- id_worker_str实体类使用String id,表的列使用varchar 50
- uuid 实体类使用String id,列使用varchar 50
- assign_id:类似于id_worker+id_worker_str。无论是Long还是String都行
- assign_uuid:类似于uuid
id_worker: Twitter雪花算法-分布式ID
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xS0WfUD2-1619833743494)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210429102206953.png)]](https://i-blog.csdnimg.cn/blog_migrate/d767f5c91a6cd8bf5451ce51109a50c4.png)
指定表名
定义实体类,默认的表名和实体类同名;如果不一致,在实体类定义上面使用TableName 说明表名称。
例如:@TableName(value=“数据库表名”)
使用位置:类上面
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P0cCGHn7-1619833743496)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210429102426121.png)]](https://i-blog.csdnimg.cn/blog_migrate/13106d6f5c868a63037643bc6ba0f968.png)
指定列名
例如:@TableField(value=“数据库字段名称”)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-acaFBklp-1619833743499)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210429102619402.png)]](https://i-blog.csdnimg.cn/blog_migrate/160f7cae6dfc2d86f3ef75a8ffe94d52.png)
驼峰命名
数据库列名使用下划线,实体类属性名是驼峰命名方式。MyBatis 默认支持这种规则。
例如:
数据库:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVFlZJXV-1619833743500)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210429102742167.png)]](https://i-blog.csdnimg.cn/blog_migrate/a8527a6879a9fc3669bc63ea0d718253.png)
实体类:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nDd975GB-1619833743501)(C:\Users\yyyzl\AppData\Roaming\Typora\typora-user-images\image-20210429102753024.png)]](https://i-blog.csdnimg.cn/blog_migrate/5c85772ca0327c798242201c9b8d7d83.png)
自定义sql
-
创建Mapper
public interface StudentMapper extends BaseMapper<Student> { Student selectByName(String name);} -
新建sql映射文件
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.nanda.mapper.StudentMapper"> <select id="selectByName" resultType="com.nanda.pojo.Student"> select * from student where name = #{name} </select></mapper> -
配置文件中配置位置
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath*:mapper/*Mapper.xml -
测试
@SpringBootTestpublic class TestStudent { @Autowired private StudentMapper studentDao; @Test public void selectStudent(){ Student student = studentDao.selectByName("22"); System.out.println(student); }}
查询和分页
查询构造器:Wrapper
QueryWrapper(LambdaQueryWrapper)和updateWrapper(LambdaUpdateWrapper)的父类用于生成sql的where条件, entity属性也用于生成sql的where 条件.MP3.x开始支持lambda表达式, LambdaQueryWrapper, LambdaUpdateWrapper
支持lambda表达式的构造查询条件。
查询
allEq
以Map为参数条件
(1)查询条件没null
@Test public void testAllEq(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //组装条件 Map<String,Object> param=new HashMap<>(); //Map<key,value> key列名,value查询的值 param.put("name","张三"); param.put("age",22); qw.allEq(param); //调用MP自己的查询方法 //SELECT id,name,age,email,status FROM student WHERE (name = ? AND age = ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
(2)查询条件有null
/* * (1)Map对象中有key的value是null * 使用的是qw.allEq(param,true); * 结果是:WHERE (name = ? AND age IS NULL) * * (2)Map对象中有key的value是null * 使用的是qw.allEq(param,false); * 结果是:WHERE (name = ?) * * 结论:allEq(map,boolean) * true:处理null值,where条件加入字段is null * false:忽略null,不作为where条件 * */ @Test public void testAllEq2(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //组装条件 Map<String,Object> param=new HashMap<>(); //Map<key,value> key列名,value查询的值 param.put("name","张三"); //age是null param.put("age",null); //第二个参数为true,或者false qw.allEq(param,true); //调用MP自己的查询方法 //为true时:SELECT id,name,age,email,status FROM student WHERE (name = ? AND age IS NULL) //为false时:SELECT id,name,age,email,status FROM student WHERE (name = ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
eq
等于=
/* * eq使用 * eq(“列名”,值) * */ @Test public void testEq(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.eq("name","张三"); //SELECT id,name,age,email,status FROM student WHERE (name = ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
ne
ne不等于
/* * ne使用 * ne表示不等于<> * ne(“列名”,值) * */ @Test public void testNe(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //组成条件 qw.ne("name","张三"); //SELECT id,name,age,email,status FROM student WHERE (name <> ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
gt
gt大于
/* * gt 大于(>) * */ @Test public void testGt(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.gt("age",28); //age>28 //SELECT id,name,age,email,status FROM student WHERE (age > ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
ge
ge大于等于
/* * ge 大于等于(>=) * */ @Test public void testGt(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.ge("age",28); //age>=28 //SELECT id,name,age,email,status FROM student WHERE (age >= ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
lt
lt小于
/* * lt 小于(<) * */ @Test public void testGt(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.lt("age",28); //age<28 //SELECT id,name,age,email,status FROM student WHERE (age < ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
le
le小于等于
/* * le 小于等于(<=) * */ @Test public void testGt(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.ge("age",28); //age<=28 //SELECT id,name,age,email,status FROM student WHERE (age <= ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
between
between 在两个值范围之间
/* * between (? and ?) * */ @Test public void testBetween(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //between(“列名”,开始值,结束值) qw.between("age",22,28); //SELECT id,name,age,email,status FROM student WHERE (age BETWEEN ? AND ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
notBetween
notBetween 不在两个值范围之间
/* * notBetween (不在范围区间内) * */ @Test public void testNotBetween(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //between(“列名”,开始值,结束值) qw.notBetween("age",22,28); //SELECT id,name,age,email,status FROM student WHERE (age NOT BETWEEN ? AND ?) //where age < 22 or age > 28 List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
like
like 匹配某个值
/* * like 匹配某个值 * */ @Test public void testLike(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.like("name","张"); //SELECT id,name,age,email,status FROM student WHERE (name LIKE ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
notLike
notLike 不匹配某个值
/* * notLike 不匹配某个值 * */ @Test public void testNotLike(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.notLike("name","张"); //SELECT id,name,age,email,status FROM student WHERE (name NOT LIKE ?) List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
likeLeft、likeRight
likeLeft “%值”
likeRight “值%”
/* * likeLeft "%值" * */ @Test public void testLikeLeft(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.likeLeft("name","张"); //SELECT id,name,age,email,status FROM student WHERE (name LIKE ?) %张 List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
isNull、isNotNull
isNull判断字段值为null
isNotNull字段值不为null
/* * isNull ,判断字段是null * */ @Test public void testIsNull(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //判断email is null //WHERE (email IS NULL) qw.isNull("email"); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
in、notIn
in后面值列表,在列表中都是符合条件的。
notin不在列表中的
/** in 值列表* */@Testpublic void testIn(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //in (列名,多个值的列表) //WHERE (name IN (?,?,?)) qw.in("name","张三","李四","李雷"); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}//或者/* * in 值列表 * */ @Test public void testIn2(){ QueryWrapper<Student> qw=new QueryWrapper<>(); List<Object> list=new ArrayList<>(); list.add("张三"); list.add("李四"); //in (列名,多个值的列表) //WHERE (name IN (?,?)) qw.in("name",list); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student)); }
inSql、notInSql
inSql常用来做子查询类似in()
notlnSql类似notln()
/** insql():使用子查询* */@Testpublic void testInSQL(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //WHERE (age IN (select age from student where id=1)) qw.inSql("age","select age from student where id=1"); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
groupBy
groupBy 基于多个字段分组
/** groupBy:分组* */@Testpublic void testGroupBy(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.select("name,count(*) personNumbers"); // select name,count(*) personNumbers qw.groupBy("name"); //SELECT name,count(*) personNumbers FROM student GROUP BY name List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
orderByAsc、orderByDesc、orderBy
orderByAsc按字段升序
orderByDesc按字段降序
orderBy 每个字段指定排序方向
/** orderByAsc:按字段升序* */@Testpublic void testOrderByAsc(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.orderByAsc("name","age"); //SELECT id,name,age,email,status FROM student ORDER BY name ASC,age ASC List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}//或者/** orderByDesc:按字段降序* */@Testpublic void testOrderByAsc(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.orderByDesc("name","age"); //SELECT id,name,age,email,status FROM student ORDER BY name Desc,age Desc List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
/** order:指定字段和排序方向** boolean condition:条件内容是否加入到sql语句的后面* true:条件加入到sql语句* FROM student ORDER BY name ASC** false:条件不加入到sql语句* FROM student* */@Testpublic void testOrder(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.orderBy(true,true,"name"). orderBy(true,false,"age"). orderBy(true,false,"email"); //SELECT id,name,age,email,status FROM student ORDER BY name ASC,age DESC,email DESC List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
or、and
or连接条件用or,默认是and
and 连接条件用and
/** and or 方法* */@Testpublic void testOr(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //SELECT id,name,age,email,status FROM student WHERE (name = ? OR age = ?) qw.eq("name","张三").or().eq("age",22); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
last
last拼接sql语句
/** last : 拼接sql语句到MP的sql语句的最后* */@Testpublic void testLast(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //SELECT id,name,age,email,status FROM student WHERE (name = ? OR age = ?) limit 1 qw.eq("name","张三").or().eq("age",22).last("limit 1"); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
exisit、notExists
exists拼接EXISTS ( sql语句)
notExists 是exists的相反操作
/** exists:判断条件* */@Testpublic void testExists(){ QueryWrapper<Student> qw=new QueryWrapper<>(); //SELECT id,name,age,email,status FROM student // WHERE (EXISTS (select id from student where age>20)) qw.exists("select id from student where age>20"); List<Student> students = studentDao.selectList(qw); students.forEach(student -> System.out.println(student));}
分页
前提:配置分页插件,实现物理分页。默认是内存分页
@Configurationpublic class Config { //分页插件 @Bean public PaginationInnerInterceptor paginationInnerInterceptor(){ return new PaginationInnerInterceptor(); }}
分页查询:
/** 分页:* 1.统计记录数,使用count(1)** 2.实现分页,在sql语句的末尾加入limit 0,3*SELECT id,name,age,email,status FROM student WHERE (age > ?)* */@Testpublic void testPage(){ QueryWrapper<Student> qw=new QueryWrapper<>(); qw.gt("age",22); IPage<Student> page=new Page<>(); //设置分页的数据 page.setCurrent(1);//第一页 page.setSize(3);//每页的记录数 IPage<Student> result = studentDao.selectPage(page, qw); //获取分页后的记录 List<Student> students = result.getRecords(); System.out.println("students.size()="+students.size()); //分页的信息 System.out.println("页数"+result.getPages()); System.out.println("总记录数"+result.getTotal()); System.out.println("当前页码"+result.getCurrent()); System.out.println("每页的记录数"+result.getSize());}
MP生成器
MyBatis plus实战视频教程-带你快速掌握MyBatis-plus_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
946

被折叠的 条评论
为什么被折叠?



