mybatis-plus简单使用
MyBatis是Java的持久层框架,实际工作中就是来简化和规范传统的数据库CURD操作。
MyBatis-Plus(MP)是MyBatis的增强工具,所谓增强,实际上是对MyBatis进行了进一步的封装,简化了Dao或Mapper以及Service层的重复无技术性的代码,可以提高我们的开发效率。
MP的官网https://mybatis.plus/是一个非常好的学习途径,在代码实践中看源码对理解MP的插件、特性也非常有帮助。
特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
MP提供的实例很多,由于自己不是在项目中用到的,还不清楚在项目中的实际应用更偏向于哪一部分,而且刚接触,对于我这个初入职场的小菜鸡来说学习效率比较低,只简单尝试了Mapper的CURD操作,其他部分等到项目中运用的时候再深究。
1. 首先新建一个SpringBoot Maven项目,在pom.xml中引入数据库、Tomcat相关包,再引入MP的包。
2. 接着,在application.yml中配置数据库,并给SpringBoot启动类加上扫描Mapper的注解。
3. 下一步就可以在数据库新建一个简单的表,并创建一个有映射关系的pojo实体类。这里部分属性有注解是因为数据库字段的命名和实体类属性不一致,可以加上@TableField来手动映射。@Data是lombok简化get/set/toString等方法的注解。
4. 在Mapper包下新建一个Mapper类,继承BaseMapper<Pojo>。
5. 最后在测试类下写测试方法。代码如下:
1 package com.zxin.mybatisplus; 2 3 import com.baomidou.mybatisplus.core.conditions.Wrapper; 4 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; 6 import com.zxin.mybatisplus.mapper.EquipmentMapper; 7 import com.zxin.mybatisplus.pojo.CompanyEquipment; 8 import org.junit.Test; 9 import org.junit.runner.RunWith; 10 import org.springframework.boot.test.context.SpringBootTest; 11 import org.springframework.test.context.junit4.SpringRunner; 12 13 import javax.annotation.Resource; 14 import javax.sound.midi.Soundbank; 15 import java.util.*; 16 17 @RunWith(SpringRunner.class) 18 @SpringBootTest 19 /** 20 * MyBatisPlus测试CRUD 21 */ 22 public class MybatisPlusApplicationTests { 23 @Resource 24 private EquipmentMapper equipmentMapper; 25 26 27 @Test 28 /** 29 * 查询selectList and selectById 30 */ 31 public void query1() { 32 List<CompanyEquipment> companyEquipments = equipmentMapper.selectList(null); 33 CompanyEquipment companyEquipment = equipmentMapper.selectById(19); 34 System.out.println(companyEquipment.toString()); 35 } 36 37 @Test 38 /** 39 * selectByMap 40 */ 41 public void query2(){ 45 Map<String, Object> map = new HashMap<>(); 46 map.put("CompanyId", 24); 47 List<CompanyEquipment> companyEquipments = equipmentMapper.selectByMap(map); 48 companyEquipments.forEach(System.out::println); 49 } 50 51 @Test 52 public void query3(){ 53 /** 54 * 条件构造器查询:使用queryWrapper.点各种条件 55 */ 56 QueryWrapper<CompanyEquipment> queryWrapper = new QueryWrapper<>(); 57 58 //条件设置为("CompanyId",24)--->CompanyId = 24,等同于allEq方法中Map参数只put一个键值对。(键需要是数据库的列) 59 //eq为等于,同样的,ne表示不等于,gt是大于,ge是大于等于,lt是小于,le是小于等于,参数都是两个值,也就是一个键值对 60 queryWrapper.eq("CompanyId",24); 61 62 //写多条queryWrapper.eq("CompanyId",24),会用and连接,等同于先创建一个Map,再push多个键值对,使用allEq。 63 //怎样写多条eq但是用or连接? 答:eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王' 64 queryWrapper.eq("CompanyId", 24); 65 queryWrapper.eq("IsPass", 0); 66 67 //Map如果只put一对键值,相当于eq方法,put多对键值,相当于多条queryWrapper.eq。 68 Map<String, Object> map = new HashMap<>(); 69 map.put("CompanyId", 24); 70 //如果map中的键对应的值不为空,allEq的第二个参数true/false就没有意义 71 map.put("Reason", null); 72 //约束为空的对象,是否条件为空,例如map中的Reason设置了null,查询时true/false决定是否在条件中加入值为null的列。 73 queryWrapper.allEq(map, true); 74 75 //需要传3个值,第一个是哪一列,第二个是大于的值,第三个是小于的值。 76 //同样的,notBetween也是传3个值,表示不在这个范围内的。 77 //该方法等同于两条ge,le方法。 78 queryWrapper.between("ExpiredDate","2020-08-01","2020-08-31"); 79 80 //like就是sql的like,该语句表示Name中包含“新”的数据有哪些 81 //同样的,还有notLike/likeLeft/likeRight 82 queryWrapper.like("Name", "新"); 83 84 //找到该属性为null的数据 85 //同理,isNotNull是查找该属性不为空的数据 86 queryWrapper.isNull("Reason"); 87 88 //int[] companyIds = {16,17,18}; 89 //in方法需要的参数是,数据表的列名和一个集合。注意:数组不可以。 90 //同理notIn,表示不在这个集合元素中的数据 91 List<Integer> companyIds = new ArrayList<>(); 92 //也可以array转list 93 //List<Integer> companyIds = Arrays.asList(17, 18); 94 companyIds.add(17); 95 companyIds.add(18); 96 queryWrapper.in("CompanyId",companyIds); 97 98 //inSql可以实现和in相同的效果,且第二个参数可以为sql语句,如:select CompanyId from table_name where IsPass = 0; 99 //notInSql表示不在这个范围中的数据 100 queryWrapper.inSql("companyIds", "16,17,18"); 101 102 /** 103 * 其他一些方法举例 104 * groupBy("id", "name")--->group by id,name 105 * orderByAsc("id", "name")--->order by id ASC,name ASC 106 * orderByDesc("id", "name")--->order by id DESC,name DESC 107 * having("sum(age) > 10")--->having sum(age) > 10 108 * having("sum(age) > {0}", 11)--->having sum(age) > 11 109 * 110 */ 111 112 List<CompanyEquipment> companyEquipments1 = equipmentMapper.selectList(queryWrapper); 113 companyEquipments1.forEach(System.out::println); 114 115 //CompanyEquipment companyEquipment = equipmentMapper.selectOne(queryWrapper); 116 //System.out.println(companyEquipment); 117 } 118 119 @Test 120 /** 121 * 常见的数据库更新操作 122 */ 123 public void update(){ 124 /** 125 * 有两种方式:byId、byWrapper,都是约束条件的作用,也就是说必须有实体对象 126 */ 127 CompanyEquipment equipment = new CompanyEquipment(); 128 //byId 129 //必需参数 130 equipment.setId(39); 131 //可选参数 132 equipment.setName("ABDKWA待审核设备"); 133 equipment.setIsPass(-1); 134 135 int updateCount = equipmentMapper.updateById(equipment); 136 System.out.println(updateCount); 137 138 139 //by条件构造器 140 //id非必需,根据需求传入修改的字段 141 equipment.setReason("不予通过,材料缺少,证书已过期"); 142 UpdateWrapper<CompanyEquipment> updateWrapper = new UpdateWrapper<>(); 143 updateWrapper.ne("IsPass",1); 144 int updateCount2 = equipmentMapper.update(equipment, updateWrapper); 145 System.out.println(updateCount2); 146 } 147 148 149 @Test 150 /** 151 * 删除 152 */ 153 public void delete() { 154 //通过id删除,只需要传入一个id即可 155 int idCount = equipmentMapper.deleteById(28); 156 157 //根据id的集合实现批量删除 158 List<Integer> ids = new ArrayList<>(); 159 ids.add(1); 160 ids.add(2); 161 int idsCount = equipmentMapper.deleteBatchIds(ids); 162 163 //通过条件构造器找到数据,多eq几次,效果相当于deleteByMap 164 QueryWrapper<CompanyEquipment> wrapper = new QueryWrapper<>(); 165 wrapper.eq("Name","一个设备设备zzz"); 166 int wrapperCount = equipmentMapper.delete(wrapper); 167 168 //通过Map确定需要删除的数据,和条件构造器效果相同 169 Map<String, Object> deleteMap = new HashMap<>(); 170 deleteMap.put("Name", "一个设备设备zzz"); 171 int mapCount = equipmentMapper.deleteByMap(deleteMap); 172 } 173 174 @Test 175 /** 176 * 插入 177 */ 178 public void insert() { 179 //直接将实体对象传入即可 180 CompanyEquipment equipment = new CompanyEquipment(); 181 182 //如果设置了主键自增,可以不设置id 183 equipment.setName("MP设备"); 184 equipment.setCompanyId(24); 185 int insertCount = equipmentMapper.insert(equipment); 186 System.out.println(insertCount); 187 } 188 }
自己就测试了这么多,查询的方法比较多,使用的时候分成多个方法练习,或者把其他部分注释掉。
Java小白,初入职场,啥都写,都很菜,欢迎各位大佬补充和指正!