零SQL实现CRUD你学会了没?我再教你啊-Wrapper

学习要求

良好的java基础, 熟悉SpringBoot框架,熟悉Mybatis框架  

教程目标

 了解并掌握MyBatis-Plus条件构造器

视频教程

MyBatisPlus实战教程与开发建议

概念

条件构造器-Wrapper按照官方的给出的解释是用于生成 sql 的 where 条件,但在使用的过程发现Wrapper不仅仅只是生产where条件,准确的来说,wrapper更新mybatis中的<sql></sql>动态标签,可以拼接where 条件也可拼接set 语法,同样也可以拼接 select 列列表等。

类体系结构

按功能分

修改型:UpdateWrapper   LambdaUpdateWrapper

查询型:QueryWrapper    LambdaQueryWrapper

按操作分

传统型:QueryWrapper   UpdateWrapper   

Lambda:LambdaQueryWrapper  LambdaUpdateWrapper

不管怎么分,它们都有一个共同的父类:AbstractWrapper, 父类里面定义wrapper核心的条件方法比如:

allEqeq ne gt ge lt le between notBetween like notLike likeLeft likeRight isNull  isNotNull  in notIn inSql notInSql groupBy orderByAsc orderByDesc orderBy having func or and nested apply last exists notExists 等

Update类型的Wrapper独有操作方法:set   setSql

Query类型的Wrapper独有操作方法:select

UpdateWrapper 与 LambdaUpdateWrapper  

这2个Wrapper都是用于对数据修改的条件构造器

需求:将id=1的员工name修改为zhangsanfeng

UpdateWrapper 

@Test
public void testUpdate(){
    UpdateWrapper<Employee>  wrapper = new UpdateWrapper<>();
    wrapper.eq("id", 1L);
    wrapper.set("name", "zhangsanfeng");
    employeeMapper.update(null, wrapper);
}

LambdaUpdateWrapper

@Test
public void testUpdateLambda(){
    LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
    wrapper.eq(Employee::getId, 1L);
    wrapper.set(Employee::getName, "zhangsanfeng");
    employeeMapper.update(null, wrapper);
}

LambdaUpdateWrapper 的update 跟 UpdateWrapper 的update操作一样,唯一区别点在于UpdateWrapper的操作列都是以字符串的形式存在,LambdaUpdateWrapper 的操作列使用lambda表达式。查看源码,你发现:Employee::getName其实最终会解析name属性来。简单的理解就是通过Employee类中的getName方法,将name属性解析出来。这么折腾好处是比直接写字符串方式多了一种操作前检查(避免出现手误)

@Override
public LambdaUpdateWrapper<T> set(boolean condition, SFunction<T, ?> column, Object val) {
	if (condition) {
	    sqlSet.add(String.format("%s=%s", columnToString(column), formatSql("{0}", val)));
	}
	return typedThis;
}


protected String columnToString(SFunction<T, ?> column, boolean onlyColumn) {
	return getColumn(LambdaUtils.resolve(column), onlyColumn);
}

private String getColumn(SerializedLambda lambda, boolean onlyColumn) {
	Class<?> aClass = lambda.getInstantiatedType();
	tryInitCache(aClass);
	String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
	ColumnCache columnCache = getColumnCache(fieldName, aClass);
	return onlyColumn ? columnCache.getColumn() : columnCache.getColumnSelect();
}

独有方法操作 

需求1其实还是一种写法,使用到:setSql

@Test
public void testUpdate(){
    UpdateWrapper<Employee>  wrapper = new UpdateWrapper<>();
    wrapper.eq("id", 1L);
    //wrapper.set("name", "zhangsanfeng");
    wrapper.setSql("name='zhangsanfeng'");
    employeeMapper.update(null, wrapper);
}

setSql表示使用拼接SQL片段方式进行操作,区别从打印的SQL可以看出

set方式

SQL:
UPDATE employee SET name=? WHERE (id = ?)
参数:
zhangsanfeng(String), 1(Long)

setSql方式

SQL:
UPDATE employee SET name='zhangsanfeng' WHERE (id = ?)
参数:
1(Long)

2个对比,可以很明显看出set方式使用预编译操作方法,而setSql 直接进行拼接,所以操作上更推荐set方式。

QueryWrapper 与 LambdaQueryWrapper

需求:查询name=zhangsan, age=18 的员工信息

QueryWrapper

@Test
public void testQuery(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.eq("name", "zhangsan");
    wrapper.eq("age", 18);
    List<Employee> list = employeeMapper.selectList(wrapper);
}

 LambdaQueryWrapper

@Test
public void testQueryLambda(){
    LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Employee::getName, "zhangsan");
    wrapper.eq(Employee::getAge, 18);
    List<Employee> list = employeeMapper.selectList(wrapper);
}

2个Wrapper操作跟上面update操作一个样,都是将字符串的操作列转换成lambda方式,其实没有本质上的区别。

独有方法操作

 query类型wrapper也有自己的独有的方法:select

@Test
public void testQuery(){
    QueryWrapper<Employee> wrapper = new QueryWrapper<>();
    wrapper.select("id", "name");
    wrapper.eq("name", "zhangsan");
    wrapper.eq("age", 18);
    List<Employee> list = employeeMapper.selectList(wrapper);
}

里面的wrapper.select("id", "name"); 方法表示查询结果返回id,name 2列,等价于:

SELECT id,name FROM employee WHERE (name = ? AND age = ?)

如果不加select 方法,默认查询所有列,等价于: 

SELECT * FROM employee WHERE (name = ? AND age = ?)

Wrapper实例构建方式

@Test
public void testWrapper(){
    //wrapper对象的创建
    //query
    QueryWrapper<Employee> queryWrapper1 = new QueryWrapper<>();
    QueryWrapper<Employee> queryWrapper2 = Wrappers.<Employee>query();
    
    LambdaQueryWrapper<Employee> queryWrapper3 = new LambdaQueryWrapper<>();
    LambdaQueryWrapper<Employee> queryWrapper4 = Wrappers.<Employee>lambdaQuery();
    LambdaQueryWrapper<Employee> queryWrapper5 = queryWrapper1.lambda();
    
    //update
    UpdateWrapper<Employee> updateWrapper1 = new UpdateWrapper<>();
    UpdateWrapper<Employee> updateWrapper2 = Wrappers.<Employee>update();

    LambdaUpdateWrapper<Employee> updateWrapper3 = new LambdaUpdateWrapper<>();
    LambdaUpdateWrapper<Employee> updateWrapper4 = Wrappers.<Employee>lambdaUpdate();
    LambdaUpdateWrapper<Employee> updateWrapper5 = updateWrapper1.lambda();
}

其中的Wrappers 是mybatis-plus官方提供的构建Wrapper实例的工具类。

传统Wrapper与LambadWrapper选择

单从可读性来看,建议使用传统的Wrapper,从预防手误来看,建议使用LambadWrapper

实际开发以公司规定为准则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪飞yes

我对钱没兴趣~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值