MybatisPlus介绍
官网:https://baomidou.com/
MyBatis-Plus (简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生(详细介绍见官网)
Mybatis自动驼峰映射
实现步骤:
-
数据库遵循数据库命名规则,单词之间下划线隔开,Java中遵循驼峰命名法
-
mybatis配置文件中开启配置,注意settings标签在配置文件中的位置顺序
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
-
例:
// javabean public class Staff{ private int staffId; private String staffName; private String staffHobby; }
-- 数据口中表的字段 int staff_id varchar(20) staff_name varchar(20) staff_hobby
此时,查询结果就不需要做结果集映射
junit单元测试
实现步骤:
-
pom.xml导入坐标(依赖)
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
-
注释:
- @Before:执行@Test之前运行
- @Test:类似main方法
- @After:执行@Test之后运行
-
例子
InputStream stream = null; SqlSession sqlSession = null; StaffMapper sMapper = null; @Before public void beforeMethod(){ try { stream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory build = new SqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); sMapper = sqlSession.getMapper(StaffMapper.class); } catch (IOException e) { e.printStackTrace(); } } @Test public void show1(){ int i = sMapper.insertOne(new Staff("王二狗", "抽烟")); } @After public void AfterMethod(){ try { sqlSession.close(); stream.close(); } catch (IOException e) { e.printStackTrace(); } }
lombok
含义:自动生成实体类的get set 无参 有参
实现步骤:
-
idea工具安装插件(有其只做一次)侵入式设计(若将代码拉到没有lombok的IDEA中,就会报错)
-
pom.xml导入坐标(依赖)
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> </dependency>
-
注释
-
@NoArgsConstructor:无参构造方法
-
@AllArgsConstructor:全参构造方法
-
@Data:get,set,toString方法
-
-
例:
// 添加注释后就不需要写get,set,toString,无参,有参构造方法,如果需要非全参构造方法可以另写 @NoArgsConstructor @AllArgsConstructor @Data public class Staff{ private int staffId; private String staffName; private String staffHobby; }
MybatisPlus的使用
实现步骤:
-
pom.xml导入坐标
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.1.1</version> </dependency>
注意:MP坐标添加后,mybatis坐标移除
-
编写注解配置实体类与关系表映射关系(truncate清空表以及主键)
@TableName(value = “关联表名称”)=》修饰在类
@TableField(value = “关联字段名称”)》修饰在属性
exist = “忽略字段”
@TableId(type=“指定主键生成策略,默认雪花算法”)===========》修饰在属性
AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4);@NoArgsConstructor @AllArgsConstructor @Data @TableName(value = "staff") public class Staff { @TableId(value = "staff_id",type = IdType.AUTO) private int staffId; @TableField(value = "staff_name") private String staffName; @TableField(value = "staff_hobby") private String staffHobby; }
-
使用:
BaseMapper===========》公共的数据访问层
IService/ServiceImp==》公共的业务层public interface StaffMapper extends BaseMapper<Staff> { }
-
测试代码使用MyBatisSqlSessionFactoryBuilder
@Before public void BeforeMethod(){ try { stream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory build = new MybatisSqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); sMapper = sqlSession.getMapper(StaffMapper.class); } catch (IOException e) { e.printStackTrace(); } }
注意:在new 的时候需要使用MyBatisSqlSessionFactoryBuilder
-
BaseMapper中的增删改查
public class Test02 { InputStream stream =null; SqlSession sqlSession =null; StaffMapper sMapper = null; @Before public void BeforeMethod(){ try { stream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory build = new MybatisSqlSessionFactoryBuilder().build(stream); sqlSession = build.openSession(true); sMapper = sqlSession.getMapper(StaffMapper.class); } catch (IOException e) { e.printStackTrace(); } } @After public void AfterMethod(){ try { sqlSession.close(); stream.close(); } catch (IOException e) { e.printStackTrace(); } } // 新增 @Test public void show1(){ Staff staff = new Staff("张三", "看美女"); int i = sMapper.insert(staff); System.out.println("主键回填"+staff.getStaffId()); System.out.println("添加行数"+i); } // 通过ID修改 @Test public void show2(){ Staff staff = new Staff(); staff.setStaffHobby("吃吃喝喝"); staff.setStaffId(5); int i = sMapper.updateById(staff); System.out.println("影响行数:"+i); } // 条件修改 @Test public void show3(){ // 修改数据 Staff staff = new Staff(); staff.setStaffHobby("抽烟喝酒烫头"); QueryWrapper<Staff> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("staff_name","张三"); int row = sMapper.update(staff, queryWrapper); System.out.println("影响行数:"+row); } // ID查询 @Test public void show4(){ Staff staff = sMapper.selectById(5); System.out.println(staff); } // 相当于条件查找的in @Test public void show5(){ List<Staff> sList = sMapper.selectBatchIds(Arrays.asList(1, 3, 5)); sList.forEach(System.out::println); } // count函数 @Test public void show6(){ Integer count = sMapper.selectCount(null); System.out.println("数据总数"+count); } // 条件查找or @Test public void show7(){ QueryWrapper<Staff> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("staff_name","惠晨怡").or().eq("staff_hobby","看美女"); // 下面的条件相当于and // queryWrapper.eq("staff_name","惠晨怡"); // queryWrapper.eq("staff_hobby","抽烟喝酒烫头"); List<Staff> slist = sMapper.selectList(queryWrapper); slist.forEach(System.out::println); } // 分页 @Test public void show8(){ //1.定义分页规则 Page<Staff> staffPage = new Page<>(); staffPage.setSize(3); //每页记录数 staffPage.setCurrent(2); //当前页码 IPage<Staff> iPage = sMapper.selectPage(staffPage, null); List<Staff> slist = iPage.getRecords(); slist.forEach(System.out::println); System.out.println("总记录数"+iPage.getTotal()); System.out.println("总页数"+iPage.getPages()); } // 删除 @Test public void show9(){ int row = sMapper.deleteById(6); System.out.println("删除行数"+row); } }
注意:
-
MP自动主键回填,新增后通过对象调用方法可以得到主键
-
条件QueryWrapper
QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
QueryWrapper中有许多的方法,如lt,gt,eq,in等等
-
MP分页的使用:
使用前需要在mybtais配置文件中进行配置
<!--插件--> <plugins> <!--mp分页插件--> <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"></plugin> </plugins>
- page.setCurrent(2);当前页码从1开始
- 分页需要配置插件
- MP坐标版本3.1.1不能使用过高版本
-
MP条件查询
@Test
public void show1(){
//条件查询
LambdaQueryWrapper<Staff> la = new LambdaQueryWrapper<>();
la.gt(Staff::getStaffAge,10);
List<Staff> slist = sMapper.selectList(la);
slist.forEach(System.out::println);
}
LambdaQueryWrapper也是拼接条件的对象,和QueryWrapper区别参数的形式
MP模糊动态查询
// 模糊动态查询
@Test
public void show2(){
// 前端发送了的数据
Integer num1 = null;
Integer num2 = 30;
// 查询条件
LambdaQueryWrapper<Staff> la = new LambdaQueryWrapper<>();
if(num1 != null){
la.gt(Staff::getStaffAge,num1);
}
if(num2 !=null){
la.lt(Staff::getStaffAge,num2);
}
List<Staff> slist = sMapper.selectList(la);
slist.forEach(System.out::println);
}
// 写法二:
@Test
public void show3(){
Integer num1 = null;
Integer num2 = 30;
LambdaQueryWrapper<Staff> la = new LambdaQueryWrapper<>();
la.gt(num1!=null,Staff::getStaffAge,num1);
la.lt(num2 !=null, Staff::getStaffAge,num2);
List<Staff> slist = sMapper.selectList(la);
slist.forEach(System.out::println);
}
LambdaQueryWrapper拼接条件方法重载,写法二中LambdaQueryWrapper传了三个参数,第一个参数为条件,如果为真则后面执行
MP字段查询
@Test
public void show4(){
LambdaQueryWrapper<Staff> la = new LambdaQueryWrapper<Staff>();
la.select(Staff::getStaffName, Staff::getStaffHobby);
List<Staff> slist = sMapper.selectList(la);
slist.forEach(System.out::println);
}
LambdaQueryWrapper的select方法,将想要查找的字段写入,写入的字段有数据,剩下属性为null或为0
MP特殊查询
@Test
public void show5(){
QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
queryWrapper.select("count(*) as num1 , max(staff_age) as num2 ,min(staff_age) as num3");
List<Map<String, Object>> slist = sMapper.selectMaps(queryWrapper);
slist.forEach(System.out::println);
}
LambdaQueryWrapper的select方法
- count(*),统计数据数量
- max(staff_age),统计年龄最大值
- min(staff_age),统计年龄最小值
查询结果存放在Map集合里,键值对的形式,key为"as"后面所起的别名,value为查询的结果,上述查询结果如下:
{num1=4, num3=10, num2=30}
MP分组查询
@Test
public void show6(){
QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
queryWrapper.select("count(*) as num,staff_age");
queryWrapper.groupBy("staff_age");
List<Map<String, Object>> slist = sMapper.selectMaps(queryWrapper);
System.out.println(slist);
}
LambdaQueryWrapper的groupBy方法,先通过select方法写条件,在通过groupBy方法确定分组条件,结果如下
[
{num=1, staff_age=10},
{num=2, staff_age=20},
{num=1, staff_age=30}
]
-
num为count(*)的结果,staff_age是分组的字段,num和staff_age是两个键值对,存放在Map中
-
一共有三组,即三个Map,三个Map存放在List中,所以Map外面又包了一层List
MP逻辑删除
物理删除:业务数据从数据库中丢弃,执行的是delete操作
逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中,执行的是update操作
实现步骤:
-
修改数据库表添加
deleted
列,比如0
代表正常,1
代表删除,可以在添加列的同时设置其默认值为0
正常。 -
实体类添加属性以及注解
@TableLogic(value="0",delval="1") private Integer deleted; //value为正常数据的值,delval为删除数据的值
逻辑删除
@Test public void show7() { mapper.deleteById(6); }
注意:
- 逻辑删除的数据在MP中全查不显示,但在Mybatis中全查会看到这样的数据,Mybtatis中实现逻辑删除全查需要添加条件where deleted = 0,才不会显示逻辑删除的数据