框架结构
特性
排除字段
流程
排除非表字段的三种方式
使用场景:实体类中的某个属性不对应表中的任何字段,只是用于保存临时数据,或者临时组装的数据。
使用方式:
1、transient修饰实体类属性(修饰的属性不会被序列化)。
缺陷:有些需求需要序列化该字段。
2、static修饰属性(Lombok对静态属性不会提供get、set方法)。
缺陷:每个对象的属性值一致。
3、@TableField(exist=false),这个注解用来表示数据表中不存在该字段,默认是true。
推荐使用第三种方式
Mybatis-Plus简介
Mybatis增强工具,只做增强,不作改变,简化开发,提高效率。
官网地址:https://mybatis.plus/
github项目地址:https://github.com/baomidou/mybatis-plus
码云项目地址:https://gitee.com/baomidou/mybatis-plus
Mybatis-Plus特点:
1、无侵入(只做增强,不作改变)、损耗小(程序启动时,进行注入增强的功能)、强大的CRUD操作(通用Service、通用Mapper,通过少量配置可实现单表操作,类似Hibernate)、支持条件构造器,支持各类需求。
2、支持Lambda形式调用、提供了Lambda条件构造器,支持多种数据库(主流的Mysql、Oracle、SQL Server等)
3、支持主键生成策略、支持ActiveRecord模式(实体类只需要继承Model,然后通过实体类完成CRUD操作)。
4、支持自定义全局通用操作(支持全局通用方法注入)、支持关键词自动转义(数据库关键词自动转义)
5、内置代码生成器(实体、Mapper接口、Mapper.xml文件、Service、Controller)、内置分页插件(基于Mybatis的物理分页)、内置性能分析插件
6、内置全局拦截插件(提供了全表的delete、update智能分析阻断,也可以自定义拦截规则,以防误操作)、内置sql注入剥离器(支持sql注入剥离,有效防止注入攻击)
public class ServiceTest{
@Autowired
private UserService userService;
@Test
public void getOne(){
User one = userService.getOne(Wrappers.<User> lambdaQuery().gt(User::getAge. 25), false);
System.out.println(one);
}
//批量插入
@Test
public void batchInsert(){
User user1 = new User();
user1.setName("青山");
user1.setAge(20);
User user2 = new User();
user2.setName("绿水");
user2.setAge(21);
User user3 = new User();
user3.setName("小桥");
user3.setAge(22);
List<User> userList = Arrays.asList(user1, user2, user3);
boolean saveBatch = userService.saveBatch(userList);
System.out.println(saveBatch);
}
//批量插入
@Test
public void batchInsertOrUpdate(){
//插入
User user1 = new User();
user1.setName("青山1");
user1.setAge(20);
//插入
User user2 = new User();
user2.setName("绿水1");
user2.setAge(21);
//更新
User user3 = new User();
user3.setId(10004);
user3.setName("小桥");
user3.setAge(22);
List<User> userList = Arrays.asList(user1, user2, user3);
boolean saveBatch = userService.saveOrUpdateBatch(userList);
System.out.println(saveBatch);
}
//查询
@Test
public void chain(){
List<User> userList = userService.lambdaQuery().gt(User::getAge, 25).like(User::getName, "雨").list();
userList.forEach(System.out::println);
}
//更新
@Test
public void chain1(){
boolean update = userService.lambdaUpdate().eq(User::getAge, 25).set(User::getAge, 26).update();
System.out.println(update);
}
//删除
@Test
public void chain2(){
boolean remove = userService.lambdaUpdate().eq(User::getAge, 25).remove();
System.out.println(remove);
}
}
/**
* @date 2020年2月23日
* @author 翁东州
* @所有方法的代码点击查看全文,整理了一整天累死了
*/
package first;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.additional.update.impl.LambdaUpdateChainWrapper;
import com.mp.dao.UserMapper;
import com.mp.entity.User;
import com.mp.service.UserService;
/**
* @date 2020年2月23日
* @author 翁东州
* @方法中文名称:
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class SimpleTest {
@Autowired
private UserMapper userMapper;
//展示所有
@Test
public void select() {
List<User> list = userMapper.selectList(null);
Assert.assertEquals(5, list.size());
list.forEach(System.out::println);
System.out.println();
}
//传统添加
public void insert() {
User user = new User();
user.setName("名字");
user.setAge(31);
user.setManagerId(123L);
user.setCreateTime(LocalDateTime.now());
int rows = userMapper.insert(user);
System.out.println("影响记录数"+rows);
}
//单体展示
public void selectById() {
User user = userMapper.selectById(123L);
System.out.println(user);
}
//多条展示
public void selectByIds() {
List<Long> idList = Arrays.asList(123L,234L,345L);
List<User> users = userMapper.selectBatchIds(idList);
users.forEach(System.out::println);
}
//map形式查询
public void selectByMap() {
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "王天风");
columnMap.put("age", 25);
List<User> users = userMapper.selectByMap(columnMap);
users.forEach(System.out::println);
}
//wrapper 名字包含雨且年龄小于40
public void selectByWrapper() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//wrapper 名字包含雨,且年龄在20到40之间,email不为空
public void selectByWrapper2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq("name", "雨").between("age", 20, 40).isNotNull("email");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//wrapper 名字包含王,年龄大于等于25,按年龄降序排序,而后再按id升序排序
public void selectByWrapper3() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.likeRight("name", "王").or().ge("age", 25).orderByDesc("age").orderByAsc("id");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//创建日期为2019年2月14日且直属上级名字为王姓
public void selectByWrapper4() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.apply("date_format(create_time,'%Y-%m-%d')={0}", "2019-02-14 or true or true")
.inSql("manager_id", "select id from user where name like '王%'");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//名字为王姓,并且(年龄小于40或邮箱不为空)
public void selectByWrapper5() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.likeRight("name", "王").and(wq -> wq.lt("age", 40).or().isNotNull("email"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//名字为王姓,或者(年龄小于40并且年龄大于20并且邮箱不为空)
public void selectByWrapper6() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.likeRight("name", "王").or(wq -> wq.between("age", 20, 40).isNotNull("email"));
//queryWrapper.likeRight("name", "王").or(wq -> wq.lt("age", 40).gt("age", 20).isNotNull("email"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//名字为王姓,并且(年龄小于40或邮箱不为空)
public void selectByWrapper7() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.nested(wq -> wq.lt("age", 40).or().isNotNull("email")).likeRight("name", "王");
//queryWrapper.likeRight("name", "王").and(wq -> wq.lt("age", 40).or().isNotNull("email"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//年龄为30,31,34,35
public void selectByWrapper8() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.in("age", Arrays.asList(30,31,34,35));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//只返回满足条件的其中一条语句即可
public void selectByWrapper9() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.in("age", Arrays.asList(30,31,34,35)).last("limit 1");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//名字中包含雨并且年龄小于40,只展示id和名字
public void selectByWrapperSupper() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.select("id","name").like("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//名字中包含雨并且年龄小于40,展示不包括创建字段和上级id字段的其他字段
public void selectByWrapperSupper2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "雨").lt("age", 40)
.select(User.class, info -> !info.getColumn().equals("create_time")
&&!info.getColumn().equals("manager_id"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//测试condition
@Test
public void testCondition() {
String name = "王";
String email = "";
condition1(name,email);
}
//名字中包含王,当email为空时不查询
public void condition1(String name,String email) {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//传统方法
//if (StringUtils.isNotColumnName(name)) {
// queryWrapper.like("name", name);
//}
//if (StringUtils.isNotColumnName(email)) {
// queryWrapper.like("email", email);
//}
queryWrapper.like(StringUtils.isNotEmpty(name), "name",name)
.like(StringUtils.isNotEmpty(email), "email",email);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//查找姓名为刘红雨且年龄32岁的数据
public void selectByWrapperEntity() {
User whereUser = new User();
whereUser.setName("刘红雨");
whereUser.setAge(32);
QueryWrapper<User> queryWrapper = new QueryWrapper<User>(whereUser);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//allEq
public void selectByWrapperAllEq() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
Map<String, Object> params = new HashMap<String, Object>();
//姓名为王天风,年龄25
//params.put("name", "王天风");
//params.put("age", 25);
//queryWrapper.allEq(params);
//姓名为王天风,年龄为空则忽略
params.put("name", "王天风");
params.put("age", null);
//queryWrapper.allEq(params,false);
//剔除name查询条件
queryWrapper.allEq((k,v)->!k.equals("name"), params);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
//Map格式,查询姓名包含雨,年龄小于40的数据
public void selectByWrapperMaps() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "雨").lt("age", 40);
List<Map<String, Object>> userList = userMapper.selectMaps(queryWrapper);
userList.forEach(System.out::println);
}
//Map格式,按照直属上级id分组,查询每组的平均年龄,最大年龄,最小年龄,只去年龄总和小于500的组
public void selectByWrapperMaps2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.select("avg(age) avg_age","min(age) min_age","max(age) max_age")
.groupBy("manager_id").having("sum(age)<{0}",500);
List<Map<String, Object>> userList = userMapper.selectMaps(queryWrapper);
userList.forEach(System.out::println);
}
//obj格式,查询姓名包含雨,年龄小于40的数据
public void selectByWrapperobjs() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.select("id","name").like("name", "雨").lt("age", 40);
List<Object> userList = userMapper.selectObjs(queryWrapper);
userList.forEach(System.out::println);
}
//查询姓名包含雨,年龄小于40的数据条数的总条数
public void selectByWrapperCount() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "雨").lt("age", 40);
Integer count = userMapper.selectCount(queryWrapper);
System.out.println("总记录数"+ count);
}
//查询姓名包含雨,年龄小于40的数据条数的一条数据
public void selectByWrapperOne() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "雨").lt("age", 40);
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);
}
//lambda,三种起手
public void selectLambda() {
//LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
//LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
lambdaQuery.like(User::getName, "雨").lt(User::getAge, 40);
List<User> userList = userMapper.selectList(lambdaQuery);
userList.forEach(System.out::println);
}
//lambda,名字为王姓,并且(年龄小于40或邮箱不为空)
public void selectLambda2() {
LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
lambdaQuery.likeRight(User::getName, "王")
.and(lqw ->lqw.lt(User::getAge, 40).or().isNotNull(User::getEmail));
List<User> userList = userMapper.selectList(lambdaQuery);
userList.forEach(System.out::println);
}
//lambda,名字为王姓,并且(年龄小于40或邮箱不为空),LambdaQueryChainWrapper一气呵成
public void selectLambda3() {
List<User> userList = new LambdaQueryChainWrapper<User>(userMapper).like(User::getName, "雨").ge(User::getAge, 20).list();
userList.forEach(System.out::println);
}
//分页
public void selectPage() {
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.ge("age", 26);
Page<User> page = new Page<User>(1,10);//1为第一页,10为一页10行
IPage<User> iPage = userMapper.selectPage(page, queryWrapper);
System.out.println("总页数"+iPage.getPages());
System.out.println("总记录数"+iPage.getTotal());
List<User> userList = iPage.getRecords();
userList.forEach(System.out::println);
}
//传统根据id更新,根据id更新数据
public void updateById() {
User user = new User();
user.setId(123L);
user.setAge(25);
user.setEmail("wtf2@baomidou.com");
int rows = userMapper.updateById(user);
System.out.println("影响记录数"+ rows);
}
//传统根据Wrapper更新,姓名为李艺伟且年龄为28的数据,更改其id,年龄和邮箱
public void updateByWrapper2() {
UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>();
updateWrapper.eq("name", "李艺伟").eq("age", 28);
User user = new User();
user.setId(123L);
user.setAge(25);
user.setEmail("wtf2@baomidou.com");
int rows = userMapper.update(user,updateWrapper);
System.out.println("影响记录数"+ rows);
}
//Wrapper更新,姓名为李艺伟且年龄为29的数据,更改年龄为30
public void updateByWrapper3() {
UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>();
updateWrapper.eq("name", "李艺伟").eq("age", 29).set("age", 30);
int rows = userMapper.update(null,updateWrapper);
System.out.println("影响记录数"+ rows);
}
//lambda的Wrapper更新,姓名为李艺伟且年龄为29的数据,更改年龄为30
public void updateByWrapperLambda() {
LambdaUpdateWrapper<User> lambdaUpdate = Wrappers.<User>lambdaUpdate();
lambdaUpdate.eq(User::getName, "李艺伟").eq(User::getAge, 30).set(User::getAge, 31);
int rows = userMapper.update(null,lambdaUpdate);
System.out.println("影响记录数"+ rows);
}
//lambda的Wrapper更新,姓名为李艺伟且年龄为29的数据,更改年龄为30,一气呵成
public void updateByWrapperLambdaChain() {
boolean update = new LambdaUpdateChainWrapper<User>(userMapper)
.eq(User::getName, "李艺伟").eq(User::getAge, 29).set(User::getAge, 31).update();
System.out.println(update);
}
//根据id删除数据
public void deleteById() {
int rows = userMapper.deleteById(123L);
System.out.println("删除条数"+rows);
}
//根据map中名称为向后,年龄25删除数据
public void deleteByMap() {
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "向后");
columnMap.put("age",25);
int rows = userMapper.deleteByMap(columnMap);
System.out.println("删除条数"+rows);
}
//根据id删除多条数据
public void deleteByBatchIds() {
int rows = userMapper.deleteBatchIds(Arrays.asList(123L,234L,345L));
System.out.println("删除条数"+rows);
}
//根据wrapper删除数据
public void deleteByWrapper() {
LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.<User>lambdaQuery();
lambdaQueryWrapper.eq(User::getAge, 27).or().gt(User::getAge, 41);
int rows = userMapper.delete(lambdaQueryWrapper);
System.out.println("删除条数"+rows);
}
//AR模式添加
public void insert2() {
User user = new User();
user.setName("刘华");
user.setAge(29);
user.setEmail("lh@baomidou.com");
user.setManagerId(123L);
user.setCreateTime(LocalDateTime.now());
boolean insert = user.insert();//类继承Model
System.out.println(insert);
}
//AR模式查找
public void selectById2() {
User user = new User();
user.setId(123L);
User selectById = user.selectById();
System.out.println(selectById);
}
//AR模式更新
public void updateById2() {
User user = new User();
user.setId(123L);
user.setName("刘华");
user.setAge(29);
user.setEmail("lh@baomidou.com");
user.setManagerId(123L);
user.setCreateTime(LocalDateTime.now());
boolean updateById = user.updateById();//类继承Model
System.out.println(updateById);
}
//AR模式添加或更新
public void insertOrUpdate() {
User user = new User();
user.setName("刘华");
user.setAge(29);
user.setEmail("lh@baomidou.com");
user.setManagerId(123L);
user.setCreateTime(LocalDateTime.now());
boolean insertOrUpdate = user.insertOrUpdate();//类继承Model
System.out.println(insertOrUpdate);
}
@Autowired
private UserService userService;
//使用service,获取一条数据
public void getOne() {
User one = userService.getOne(Wrappers.<User>lambdaQuery().gt(User::getAge, 25));//多条报错
System.out.println(one);
}
//使用service,获取一条数据
public void batch() {
User user1 = new User();
user1.setName("徐丽1");
user1.setAge(28);
User user2 = new User();
user2.setId(123L);
user2.setName("徐丽2");
user2.setAge(29);
List<User> users = Arrays.asList(user1,user2);
boolean saveBatch = userService.saveBatch(users);
//保存或更新
//userService.saveOrUpdateBatch(users);
System.out.println(saveBatch);
}
//使用service,lambda查询年龄大于25且名字包含雨的数据,一气呵成
public void chain1() {
List<User> users = userService.lambdaQuery().gt(User::getAge, 25).like(User::getName, "雨").list();
users.forEach(System.out::println);
}
//使用service,lambda更新年龄为25的数据为26,一气呵成
public void chain2() {
boolean update = userService.lambdaUpdate().eq(User::getAge, 25).set(User::getAge, 26).update();
System.out.println(update);
}
//使用service,lambda删除年龄为25的数据,一气呵成
public void chain3() {
boolean remove = userService.lambdaUpdate().gt(User::getAge, 25).remove();
System.out.println(remove);
}
}
属性配置
主键策略
1、MP支持的主键策略介绍
默认主键策略是基于雪花算法的自增ID
2、局部主键策略实现,IdType.class
定义六种:AUTO NONE INPUT(2) ID_WORKER(3)-雪花算法 UUID(4) ID_WORKER_STR(5)
@TableId(type=IdType.AUTO).......数据库主键改成自增/或者非自增
@TableId(type=IdType.UUID)
private String id;
数据库对应改成varchar类型32
注意:主键类型和主键策略类型要一致,如果设定了主键,那么不会自动填充主键策略
3、全局主键策略实现全局策略配置,全局用UUID ,局部策略优先于全局策略
属性文件配置:mybatis-plus.global-config.db-config.id-type:uuid
public class MybatisplusInsertTest{
@Autowired
private UserMapper userMapper;
@Test
public void insert(){
//这里的id是自增的
//@TableId(type=IdType.AUTO)
User user = new User();
user.setName("长江水");
user.setAge(28);
user.setEmail("9834273096@qq.com");
user.setManagerId(1000002);
int insert = userMapper.insert(user);
System.out.println("insert = " + insert);
System.out.println("主键:" + user.getId());
}
@Test
public void insert1(){
//这里的id是UUID
// @TableId(type=IdType.UUID)
User user = new User();
user.setName("大浪淘金");
user.setAge(28);
user.setEmail("9834273096@qq.com");
user.setManagerId(1000002);
int insert = userMapper.insert(user);
System.out.println("insert = " + insert);
System.out.println("主键:" + user.getId());
}
@Test
public void insert2(){
//这里的id是基于雪花算法生成
// @TableId(type=IdType.ID_WORKER_STR)
User user = new User();
user.setName("滔滔江水");
user.setAge(25);
user.setEmail("9234273096@qq.com");
user.setManagerId(1000002);
int insert = userMapper.insert(user);
System.out.println("insert = " + insert);
System.out.println("主键:" + user.getId());
}
}
public class MybatisplusARTest{
@Test
public void insert(){
User user = new User();
user.setName("一点红");
user.setAge(27);
user.setEmail("877673096@qq.com");
user.setManagerId(1000001);
boolean insert = user.insert(user);
System.out.println("insert = " + insert);
}
@Test
public void selectById(){
User user = new User();
User userSelect = user.selectById(10005);
System.out.println(userSelect);
}
@Test
public void selectById2(){
User user = new User();
user.setId(10005);
User userSelect = user.selectById();
System.out.println(userSelect);
}
@Test
public void updateById(){
User user = new User();
user.setId(10005);
user.setName("雪花飘");
boolean userUpdate = user.updateById();
System.out.println(userUpdate);
}
@Test
public void deleteById(){
User user = new User();
user.setId(10005);
boolean userDelete = user.deleteById();
System.out.println(userDelete);
}
@Test
public void insertOrUpdate(){
User user = new User();
user.setName("花儿红");
user.setAge(27);
user.setEmail("877673096@qq.com");
user.setManagerId(1000001);
//如果不设置Id,就是insert,如果设置了Id,就会先查询,存在就update,不存在就insert
boolean insertOrUpdate = user.insertOrUpdate();
System.out.println(insertOrUpdate);
}
}
删除操作
public class MyBatisPlusDeleteTest{
@Autowired
private UserMapper userMapper;
@Test
public void deleteById(){
Integer rows = userMapper.deleteById(10001);
System.out.println("删除条数:" + rows);
}
@Test
public void deleteByMap(){
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "张无忌");
columnMap.put("age", 31);
//DELETE FROM user WHERE name = '张无忌' AND age = 31
Integer rows = userMapper.deleteByMap(columnMap);
System.out.println("删除条数:" + rows);
}
//带条件构造器的删除方法
@Test
public void deleteByWrapper(){
LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
wrapper.eq(User::getAge, 27).or().gt(User::getAge, 41);
//删除多条
//DELETE FROM user WHERE age = 27 or age > 41
Integer rows = userMapper.delete(deleteByWrapper);
System.out.println("删除条数:" + rows);
}
}
MyBatisPlus 的更新方法
public class MyBatisPlusUpdateTest{
@Autowired
private UserMapper userMapper;
//根据updateById方法进行更新
@Test
public void updateByIds(){
User user = new User();
user.setId(10001);
user.setAge(23);
user.setName("龙在天涯");
user.setEmail("37635636756@163.com");
Integer rows = userMapper.updateById(user);
System.out.println("影响记录数:" + rows);
}
@Test
public void updateByWrapper(){
UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>();
updateWrapper.eq("name", "张无忌").eq("age", 28); //where 表达式
// UPDATE user SET age = 25 , email = 'uyddhjdhgg@163.com' WHERE name = '张无忌' and age = 28
User user = new User();
user.setEmail("uyddhjdhgg@163.com");
user.setAge(25);
Integer rows = userMapper.update(user, updateWrapper);
System.out.println("影响记录数:" + rows);
}
@Test
public void updateByWrapper1(){
User whereUser = new User();
whereUser.setId(10002);
UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>(whereUser); //将实体传递给条件构造器
updateWrapper.eq("name", "张无忌").eq("age", 28); //where 表达式
// UPDATE user SET age = 25 , email = 'uyddhjdhgg@163.com' WHERE name = '张无忌' and age = 28
User user = new User();
user.setEmail("uyddhjdhgg@163.com");
user.setAge(25);
Integer rows = userMapper.update(user, updateWrapper);
System.out.println("影响记录数:" + rows);
}
@Test
public void updateByWrapper2(){
UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>();
updateWrapper.eq("name", "张无忌").eq("age", 28).set("age", 30); //UPDATE user SET age = 30 WHERE name = '张无忌' and age 28
Integer rows = userMapper.update(null, updateWrapper); //省略实体,设置为null
System.out.println("影响记录数:" + rows);
}
@Test
public void updateByWrapperLambda(){
LambdaUpdateWrapper<User> lambdaUpdate = Wrappers.<User>lambdaUpdate();
//UPDATE user SET age = 31 , email = 'uywyeiu@126.com' WHERE name = '张无忌' and age = 30
lambdaUpdate.eq(User::getName, "张无忌").eq(User::getAge, 30)
.set(User::getAge, 31).set(User::getEmail, "uywyeiu@126.com");
Integer rows = userMapper.update(null, lambdaUpdate);
System.out.println("影响记录数:" + rows);
}
@Test
public void updateByWrapperLambdaChain(){
boolean updateBool = new LambdaUpdateChainWrapper<User>(userMapper)
.eq(User::getName, "张无忌").eq(User::getAge, 31)
.set(User::getAge, 34).set(User::getEmail, "434444322@qq.com")
.update();
System.out.println(updateBool); //成功:true 失败:false
}
}
/**
* TODO 分页插件的用法
* 实现分页,方法1
*/
@Test
public void selectPage() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//SELECT COUNT(1) FROM user WHERE age >= 26
queryWrapper.ge("age", 26);
//SELECT * FROM user WHERE age >= ? LIMIT ?,?
Page<User> page = new Page<User>(1, 2);
IPage<User> iPage = userMapper.selectPage(page, queryWrapper);
System.out.println("总页数:" + iPage.getPages());
System.out.println("总记录数:" + iPage.getTotal());
List<User> userList = iPage.getRecords();
userList.forEach(System.out::println);
}
/**
* TODO 分页插件的用法
* 实现分页,方法2
*/
@Test
public void selectPage2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//SELECT COUNT(1) FROM user WHERE age >= 26
queryWrapper.ge("age", 26);
//SELECT * FROM user WHERE age >= ? LIMIT ?,?
Page<User> page = new Page<User>(1, 2);
IPage<Map<String, Object>> selectMapsPage = userMapper.selectMapsPage(page, queryWrapper);
System.out.println("总页数:" + selectMapsPage.getPages());
System.out.println("总记录数:" + selectMapsPage.getTotal());
List<Map<String, Object>> userList = selectMapsPage.getRecords();
userList.forEach(System.out::println);
}
分页的方法
public interface UserMapper extends BaseMapper<User> {
//注解的方式实现自定义SQL
@Select("select * from user ${ew.customeSqlSegment}")
List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
/**
//对应的XML写法
<select id="selectAll" resultType="com.entity.User">
select * from user ${ew.customeSqlSegment}
</select>
*/
}
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mp.dao.UserMapper;
import com.mp.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description
* @auther mohuani
* @create 2019-12-25 11:37
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class RetrieveTest {
@Autowired
private UserMapper userMapper;
@Test
public void selectById() {
User user = userMapper.selectById(1088250446457389058L);
System.out.println(user);
}
@Test
public void selectBatchIds() {
List<Long> list = Arrays.asList(1088248166370832385L, 1094590409767661570L, 1209509417456001025L);
List<User> userList = userMapper.selectBatchIds(list);
userList.forEach(System.out::println);
}
@Test
public void selectByMap() {
//where name='李艺伟' and age = 28
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "李艺伟");
columnMap.put("age", 28);
List<User> userList = userMapper.selectByMap(columnMap);
userList.forEach(System.out::println);
}
/**
* 1、名字中包含雨并且年龄小于40
* name like '%雨%' and age<40
*/
@Test
public void selectByWrapper() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//QueryWrapper<User> queryWrapper = Wrappers.<User>query();
queryWrapper.like("name", "雨").lt("age", 40);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 2、名字中包含雨年并且龄大于等于20且小于等于40并且email不为空
* name like '%雨%' and age between 20 and 40 and email is not null
*/
@Test
public void selectByWrapper2() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "雨").between("age" ,20 ,40).isNotNull("email");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 3、名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照id升序排列
* name like '王%' or age>=25 order by age desc,id asc
*/
@Test
public void selectByWrapper3() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.likeRight("name", "王").or().gt("age", 25).orderByDesc("age").orderByAsc("id");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
*
* 创建时间为2019年2月14日并且直属上级为名字为王姓:
* date_format(create_time,'%Y-%m-%d') and manager_id in (select id from user where name like '王%')
*
*/
@Test
public void selectByWrapper4(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//动态条件构造器:apply。范围条件构造器:insql。
//注意:如果{0}替换为实际值,可能会造成sql注入。
queryWrapper.apply("date_format(create_time,'%Y-%m-%d') = {0}","2019-02-14").inSql("manager_id","select id from user where name like '王%' ");
//queryWrapper.apply("date_format(create_time,'%Y-%m-%d') = '2019-02-14'").inSql("manager_id","select id from user where name like '王%' "); //此种写法存在SQL注入的风险
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 5.名字为王姓并且(年龄小于40或邮箱不为空)
* name like '王%' and (age < 40 or email is not null)
*
*/
@Test
public void selectByWrapper5(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.likeRight("name","王").and(wq->wq.lt("age", 40).or().isNotNull("email"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 6. 名字为王姓或者(年龄小于40并且年龄大于20并且邮箱不为空)
* name like '王%' or (age < 40 and ang > 20 and email is not null)
*
*/
@Test
public void selectByWrapper6(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.likeRight("name", "王").or(wq -> wq.lt("age", 40).gt("age", 20).isNotNull("email"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 7. (年龄小于40或邮箱不为空)并且名字为王姓
* (age < 40 or email is not null) and name like '王%'
*
*/
@Test
public void selectByWrapper7(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.nested(wq -> wq.lt("age", 40).or().isNotNull("email")).likeRight("name", "王");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 8. 年龄为30,31,34,35
* age in (30,31,34,35)
*
*/
@Test
public void selectByWrapper8(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.in("age". Arrays.asList(30,31,34,35));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 9. 值返回满足条件的其中一条语句即可
* limit 1
*
*/
@Test
public void selectByWrapper9(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//last函数 无视优化规则直接拼接到sql的最后,只能调用一次,调用多次以最后一次为准,有sql注入风险
queryWrapper.in("age". Arrays.asList(30,31,34,35)).last("limit 1");
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* select中字段不全部出现的查询
* 10. 名字中包含雨且年龄小于40
* (1)select id,name from user where name like '%雨%' and age < 40
* (2)select id,name,age, email from user where name like '%雨%' and age < 40
*/
@Test
public void selectByWrapper10(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//在select函数中指定需要查询的字段
//select id,name from user where name like '%雨%' and age < 40
//queryWrapper.select("id", "name").like("name", "雨")lt("age", 40);
//在select函数中排除不需要的字段
//select id,name,age, email from user where name like '%雨%' and age < 40
queryWrapper.like("name", "雨")lt("age", 40).select(User.class, info -> !info.getColumn().equals("create_time") && !info.getColumn().equals("manager_id"));
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* 实体对象作为条件构造器方法的参数
*/
@Test
public void selectByWrapperEntity(){
User user = new User();
user.setName("李艺伟");
user.setAge(28)
QueryWrapper<User> queryWrapper = new QueryWrapper<User>(user);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/*
* condition 条件判断,当条件为true则查询条件加入where
* 作用:该条件是否加入最后生成的sql中。
* 使用方法:如果为true就加入,如果false就不加入。
* 使用场景:类似于动态的sql拼接。
*/
@Test
public void testCondition(){
String name = "王";
String email = "";
condition(name, email);
}
private void condition(String name, String email){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//第一种写法
/*if(StringUtils.isNotEmpty(name)){
queryWrapper.like("name", name);
}
if(StringUtils.isNotEmpty(email)){
queryWrapper.like("email", email);
}*/
//第二种写法
queryWrapper.like(StringUtils.isNotEmpty(name), "name", name)
.like(StringUtils.isNotEmpty(email), "email", email);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* allEq函数用法
*/
@Test
public void selectByWrapperAllEq(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("name", "李艺伟");
columnMap.put("age", 28);
//columnMap.put("age", null);
//queryWrapper.allEq(columnMap, false); //忽略一个值
//queryWrapper.allEq(columnMap);
queryWrapper.allEq((k,v) -> !k.equals("name"), columnMap); //不等于name值的就加入条件
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
* selectMaps()用法
* selectMap:List集合的泛型不再是实体,而是map集合。其中key表示字段名,value表示字段值。
*
* 使用场景1:当实体类属性非常多时,不易查看。如果返回的是一个实体类,那么即使我们设定了返回字段,那么它的值为null,但是属性仍然存在。如果返回的是Map类型,当指定了返回字段时,那么没返回的就不会存在。
* 使用场景2:当返回的不是一条一条记录时,也就是返回的字段不在实体类属性中,比如一些统计,像平均值,最大值,最小值这样的。
*/
@Test
public void selectByWrapperMaps(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
//queryWrapper.like("name","雨").lt("age", 40);
queryWrapper.select("id", "name").like("name", "雨").lt("age", 40);
List<Map<String, Object>> userList = userMapper.selectMaps(queryWrapper);
userList.forEach(System.out::println);
}
/**
selectMaps用于返回自定义字段和查询特定字段时避免其他字段为null
selectObjs用于返回结果的第一个字段
selectCount不能带select,因为它查询的时记录数量,对应于sql中的count(1)
selectOne用于输出一条结果,如果多与一条报错
*/
/**
按照直属上级分组,查询每组的平均年龄,最大年龄,最小年龄并且只取年龄总和小于500的组
select avg(age) AS avg_age, min(age) AS min_age,max(age) AS max_age
from user group by manager_id
having sum(age) < 500
*/
@Test
public void selectByWrapperMaps2(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.select("avg(age) avg_age", "min(age) min_age", "max(age) max_age")
.groupBy("manager_id").having("sum(age) < {0}", 500);
List<User> userList = userMapper.selectList(queryWrapper);
userList.forEach(System.out::println);
}
/**
selectObject:List集合的泛型不再是实体,而是Object,只返回第一个字段的值。其他的会被舍弃。
使用场景:只返回一列时可以使用它。
*/
@Test
public void selectByWrapperObjs(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.select("id", "name").like("name", "雨").lt("age", 40);
List<Object> userList = userMapper.selectObjs(queryWrapper);
userList.forEach(System.out::println);
}
/**
selectCount:查询符合条件的总记录数的。
注意:使用它时,就不能指定返回的列了,因为它会在后面拼接COUNT(1)。
*/
@Test
public void selectByWrapperCount(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "雨").lt("age", 40);
Integer count = userMapper.selectCount(queryWrapper);
System.out.println("总记录数 = " + count);
}
/**
selectOne:查询符合条件的数据,只会返回一条数据。
注意:查询的结果必须是一条或者查不到(多于1条就会报错)。
*/
@Test
public void selectByWrapperOne(){
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.like("name", "雨").lt("age", 40);
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);
}
/**
lambda条件构造器
lambda条件构造器的创建有3种方式
1、通过查询构造器QueryWrapper创建
2、通过new直接创建lambda条件构造器
3、通过构造器工具类Wrappers创建(此时需要泛型)
*/
@Test
public void selectLambda(){
//方式1
//LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
//方式二
//LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
//方式三
LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
//where name like '%雨%' and age < 40
lambdaQuery.like(User::getName, "雨").lt(User::getAge, 40);
List<User> userList = userMapper.selectList(lambdaQuery);
userList.forEach(System.out::println);
}
/**
* 5.名字为王姓并且(年龄小于40或邮箱不为空)
* name like '王%' and (age < 40 or email is not null)
*/
@Test
public void selectLambda2(){
//方式1
//LambdaQueryWrapper<User> lambda = new QueryWrapper<User>().lambda();
//方式二
//LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
//方式三
LambdaQueryWrapper<User> lambdaQuery = Wrappers.<User>lambdaQuery();
//where name like '%雨%' and age < 40
lambdaQuery.likeRight(User::getName, "王").and(lqw -> lqw.lt(User::getAge, 40)
.or().isNotNull(User::getEmail));
List<User> userList = userMapper.selectList(lambdaQuery);
userList.forEach(System.out::println);
}
@Test
public void selectLambda3(){
//新版本
List<User> userList = new LambdaQueryChainWrapper<User>(userMapper).like(User::getName, "雨")
.ge(User::getAge, 20).list();
userList.forEach(System.out::println);
}
}
lambda条件构造器
通用Mapper
Map<String,Object> params = new HashMap<String,Object>();
params.put("name","王天风");
params.put("age",null);
queryWrapper.allEq((k,v)->!k.equals("name"),params);
List<User> userList = userMapper.selectList(queryWrapper);
这样查询条件即为传入实体中的属性值。
若查询条件需要模糊查询,可在实体字段上加注解:@TableFiled(condition=SqlCondition.LIKE) 表示该字段使用模糊查询
若查询条件要求不等值,可在实体字段上加注解:例如在age上加注解@TableFiled(condition="%s<#{%s}"),表示age<#{age}
通用Mapper
代码
package com.mp; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.mp.dao.UserMapper; import com.mp.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Description * @auther mohuani * @create 2019-12-25 11:37 */ @RunWith(SpringRunner.class) @SpringBootTest public class RetrieveTest { @Autowired private UserMapper userMapper; @Test public void selectById() { User user = userMapper.selectById(1088250446457389058L); System.out.println(user); } @Test public void selectBatchIds() { List<Long> list = Arrays.asList(1088248166370832385L, 1094590409767661570L, 1209509417456001025L); List<User> userList = userMapper.selectBatchIds(list); userList.forEach(System.out::println); } @Test public void selectByMap() { Map<String, Object> columnMap = new HashMap<>(); columnMap.put("name", "李艺伟"); columnMap.put("age", 28); List<User> userList = userMapper.selectByMap(columnMap); userList.forEach(System.out::println); } /** * 1、名字中包含雨并且年龄小于40 * name like '%雨%' and age<40 */ @Test public void selectByWrapper() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.like("name", "雨").lt("age", 40); List<User> userList = userMapper.selectList(queryWrapper); userList.forEach(System.out::println); } /** * 2、名字中包含雨年并且龄大于等于20且小于等于40并且email不为空 * name like '%雨%' and age between 20 and 40 and email is not null */ @Test public void selectByWrapper2() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.like("name", "雨").between("age" ,20 ,40).isNotNull("email"); List<User> userList = userMapper.selectList(queryWrapper); userList.forEach(System.out::println); } /** * 3、名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照id升序排列 * name like '王%' or age>=25 order by age desc,id asc */ @Test public void selectByWrapper3() { QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.likeRight("name", "王").or().gt("age", 25).orderByDesc("age").orderByAsc("id"); List<User> userList = userMapper.selectList(queryWrapper); userList.forEach(System.out::println); } }
QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
//QueryWrapper<User> query=Wrappers<User>query();
queryWrapper.like("name","雨").lt("age",40);
mapper查询用法
普通查询:使用方式为实现BaseMapper<T>接口对象调用该方法。
T selectById(Serializable id):使用场景为通过主键查询,只要该主键类型实现了Serialzable接口即可。
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList):使用场景为通过主键的集合去批量查询,前提主键的类型实现了Serializable接口。传入array
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String,Object> columnMap):使用场景为传入一个Map集合,key为表字段,value为表字段值。注意:Map的key为数据表的字段名,不是实体类属性名。
mybatis-plus:主键采用雪花算法生成值的前提是实体类的主键属性名称必须为id。
mybatis-plus:数据表字段带有_的可以自动映射到驼峰式命名的属性上(t_user 映射为 tUser)。
注解:
@TableName(“数据库表名”):使用场景实体类名称和数据表名不一致时,通过它指定表名,此时就可以使用mp的单表操作。
@TableId(“主键名”):使用场景实体类属性名称和数据表主键不是id时,通过它声明该属性为主键,就可以采用雪花算法生成主键值操作。
@TableField(“字段名”):使用场景实体类属性名称和数据表字段名不一致时,通过它指定数据表字段名称,就可以和实体类属性一起使用。
排除非表字段的三种方式
使用场景:实体类中的某个属性不对应表中的任何字段,只是用于保存临时数据,或者临时组装的数据。
使用方式
1、transient修饰实体类属性(修饰的属性不会被序列化)。缺陷:有些需求需要序列化该字段。
2、static修饰属性(前提手动实现get、set方法,Lombok对静态属性不会提供get、set方法)。缺陷:每个对象的属性值一致。
3、@TableField(exist=false),这个注解用来表示数据表中不存在该字段,默认是true。推荐
配置文件
mp特性