文章目录
前言
Mybatis:
MyBatis是一个基于SQL映射机制的持久化层框架,它内部封装了加载驱动、创建连接、创建statement等繁琐冗余的JDBC操作步骤过程,开发时只需要关注SQL语句的编写与映射配置,不用考虑如何执行以及执行结果的封装,并且可以控制SQL语句的编写与优化,有利于执行性能,灵活度高;
MybatisPlus:
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
Mybatis-Plus是一款国人研发的开源框架,官网全中文,可以自行浏览:MybatisPlus官网
一、环境配置
- 依赖坐标:因为MyBatis-Plus是第三方技术,所以再导入启动器坐标是要添加版本号
<!--mybatis+mp-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
- YML文件配置:在YMl文件中注意代码缩进!
#数据源
spring:
datasource:
url: jdbc:mysql://localhost:3306/2204db?serverTimezone=GMT
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
map-underscore-to-camel-case: true #自动驼峰映射,默认为true,可不写
#导入日志实现类,开启数据库访问日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
二、项目搭建
1.用注解表示实体类与表的双向关联关系
代码如下(示例):
//lombok的类注解,提供get、set、有参构造、无参构造;
@Data
@NoArgsConstructor
@AllArgsConstructor
//声明类与表的关联关系
@TableName(value = "student")
public class Student implements Serializable {
//声明表中主键字段与实体类属性的关联关系
@TableId(value="stu_id",type = IdType.AUTO)
private int stuId;
//声明表中其他字段与实体类属性的关联关系
@TableField("stu_name")
private String stuName;
@TableField("stu_nick")
private String stuNick;
@TableField("stu_hobby")
private String stuHobby;
@TableField("stu_age")
private int stuAge;
@TableField(value = "deleted")
//开启逻辑删除,0表示未删除,1表示以及删除
@TableLogic(value="0",delval="1")
private int deleted;
public Student(String stuName, String stuNick, String stuHobby) {
this.stuName = stuName;
this.stuNick = stuNick;
this.stuHobby = stuHobby;
}
}
2.MyMybatis-Plus中的Mapper接口
@Mapper//逐个注入
public interface StudentMapper extends BaseMapper<Student>{
}
在MyMybatis-Plus中Mapper接口只需要继承BaseMapper接口,BaseMapper接口为我们封装了大量的关于单表操作的方法,我们只需要调用即可。
3.MyMybatis-Plus中的Service接口
接口:MyMybatis-Plus也为我们准备了实现单表操作业务层接口:IService:
public interface StudentService extends IService<Student> {
}
因为Service实现类实现了Service接口,也就等于实现了IService接口,那么就要写一大堆实现IService的实现方法,如何解决这个问题,MyMybatis-plus也为我们做了准备:
实现类:ServiceImpl为我们重写了IService接口中的所有方法;
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper,Studentr> implements StudentService {
@Autowired(required = false)
OrderMapper mapper;
//业务层逻辑方法+数据访问层mapper调用方法即可
....
}
三、BeseMapper方法演示:
由于是方法快速演示,就不再service层测试,直接用test单元测试演示
在测试类中装配StudentMapper:
@Autowired(required = false)
private StudentMapper mapper;
1.新增
@Test
public void test01(){
Student student = new Student("","","");
int row = mapper.insert(student);
System.out.println("主键回填id:"+student.getStuId());
System.out.println("影响行数:"+row);
}
2.根据ID修改
未传入的数据会改为默认值
@Test
public void test02()throws Exception{
Student stu = new Student();
stu.setStuId(2);
stu.setStuHobby("网抑云");
int row = mapper.updateById(stu);
System.out.println("影响行数:"+row);
}
3.根据姓名修改
QueryWrapper查询条件构造器:相当于SQL语句中的where
@Test
public void test03()throws Exception{
//1.修改数据
Student stu = new Student();
stu.setStuHobby("");
//2.创建条件
QueryWrapper<Student> wrapper = new QueryWrapper<Student>();
wrapper.eq("stu_name","");
mapper.update(stu,wrapper);
}
4.根据ID查询
返回结果自动匹配数据类型,不用做类型转换
@Test
public void test04()throws Exception{
Student stu = mapper.selectById(6);
System.out.println(stu);
}
5.批量查询
selectBatchIds()方法传参必须是单列集合;
@Test
public void test05()throws Exception{
List<Student> list = mapper.selectBatchIds(Arrays.asList(5,1,3));
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
}
6.统计查询
selectCount(null)代表全查;
@Test
public void test06()throws Exception{
int count = mapper.selectCount(null);
System.out.println(count);
}
7.查询多个结果集
QueryWrapper查询条件构造器支持使用链式编程,将多个条件用or()或者and()拼接;
@Test
public void test07()throws Exception{
QueryWrapper<Student> queryWrapper = new QueryWrapper();
//方式1:
queryWrapper.eq("stu_sex","男").or().eq("stu_hobby","纯爷们");
//方式2:
//queryWrapper.eq("stu_sex","男");
// queryWrapper.eq("stu_hobby","纯爷们");
List<Student> list = mapper.selectList(queryWrapper);
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
}
9.lambda表达式条件查询方式
@Test
public void test08(){
//1.查询条件
LambdaQueryWrapper<Student> lambdaQueryWrapper = new LambdaQueryWrapper<Student>();
lambdaQueryWrapper.gt(Student::getStuAge,18);
//2.查询
List<Student> list = mapper.selectList(lambdaQueryWrapper);
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
}
9.lambda表达式按照条件动态查询方式1
@Test
public void test09(){
//1.前端发送来的数据
Integer num1 = null;
Integer num2 = 30;
//1.查询条件
LambdaQueryWrapper<Student> lambdaQueryWrapper = new LambdaQueryWrapper<Student>();
//2.判断
if(null != num2){
lambdaQueryWrapper.lt(Student::getStuAge,num2);
}
if(null != num1){
lambdaQueryWrapper.gt(Student::getStuAge,num1);
}
//3.查询
List<Student> list = mapper.selectList(lambdaQueryWrapper);
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
}
10.lambda表达式按照条件动态查询方式2
@Test
public void test10(){
//1.前端发送来的数据
Integer num1 = null;
Integer num2 = 30;
//1.查询条件
LambdaQueryWrapper<Student> lambdaQueryWrapper = new LambdaQueryWrapper<Student>();
//2.判断
lambdaQueryWrapper.lt(null != num2,Student::getStuAge,num2);
lambdaQueryWrapper.gt(null != num1,Student::getStuAge,num1);
//3.查询
List<Student> list = mapper.selectList(lambdaQueryWrapper);
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
11.lambda表达式查询指定字段
@Test
public void test11() {
//1.条件
LambdaQueryWrapper<Student> lambdaQueryWrapper = new LambdaQueryWrapper<Student>();
lambdaQueryWrapper.select(Student::getStuName,Student::getStuHobby);
//2.查询
List<Student> list = mapper.selectList(lambdaQueryWrapper);
//4.遍历
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
}
12.聚合查询
@Test
public void test12() {
//1.查询条件
QueryWrapper queryWrapper = new QueryWrapper<Student>();
//2.判断
queryWrapper.select("count(*) as num1,sum(stu_age) as num2,max(stu_age) as num3");
//3.查询
List<Map<String,Object>> list = mapper.selectMaps(queryWrapper);
//4.遍历
System.out.println(list);
}
13.分组查询
//分组查询
@Test
public void test13() {
//1.查询条件
QueryWrapper queryWrapper = new QueryWrapper<Student>();
//2.判断
queryWrapper.select("count(*) as num1,stu_sex");
queryWrapper.groupBy("stu_sex");
//3.查询
List<Map<String,Object>> list = mapper.selectMaps(queryWrapper);
//4.遍历
System.out.println(list);
}
14.分页查询
@Test
public void test14()throws Exception{
//1.定义分页规则
IPage<Student> page = new Page<Student>();
page.setSize(2);//每页记录数
page.setCurrent(2);//当前页码
//2.查询条件(可选)
IPage<Student> iPage = mapper.selectPage(page,null);
List<Student> list = iPage.getRecords();//分页结果
System.out.println("总记录数:"+iPage.getTotal());
System.out.println("总记页数:"+iPage.getPages());
for (int i = 0; i < list.size(); i++) {
Student student = list.get(i);
System.out.println(student);
}
}
15.逻辑删除
物理删除:业务数据从数据库中丢弃,执行的是delete操作
逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中,执行的是update操作;
需搭配 @TableLogic(value=“0”,delval=“1”):value为正常数据的值,delval为删除数据的值;
@Test
public void test15() {
mapper.deleteById(6);
}
总结
Mybatis-Plus在Mybatis的基础上提供额外的功能和工具来增强与数据库的交互的生产力和简便性,尤其是通过少量配置即可实现单表大部分CRUD操作!