上一章已经把通用mapper简单的方法说完了,这一章说说组合sql如何简单配置
1、首先看下Example这个类,先看下里面的属性
public class Example implements IDynamicTableName {
protected String orderByClause;
protected boolean distinct;
protected boolean exists;
protected boolean notNull;
protected boolean forUpdate;
protected Set<String> selectColumns;
protected String countColumn;
protected List<Example.Criteria> oredCriteria;
protected Class<?> entityClass;
protected EntityTable table;
protected Map<String, EntityColumn> propertyMap;
protected String tableName;
protected Example.OrderBy ORDERBY;
public Example(Class<?> entityClass) {
this(entityClass, true);
}
public Example(Class<?> entityClass, boolean exists) {
this(entityClass, exists, false);
}
orderByClause:单条件排序(也可以多条件排序,但是需要手动拼)
ORDERBY:多条件排序
distinct:去重,需要配合selectColumns使用
exists:判断属性是否存在,为 true时,如果属性不存在就抛出异常,false时,如果不存在就不使用该属性的条件
notNull:条件是否为null,true时属性不为null的,false时属性为null的值
forUpdate:行级锁
selectColumns:列名,配合其他属性使用
countColumn:汇总
tableName:表名(可以不填,默认取注入实体里的表名@Table(name = “表名”))
entityClass:实体类
oredCriteria:Example的内部类集合,用来拼接where后面的条件,每一对象都是一个条件,它组成的对象数组,就是一组条件
2、属性的作用大概就是这些,下面说说如何具体使用
Example相比于自带的那些CRUD的方法最大的优点就是,更加灵活多变就像写sql一样,可以根据自己的需要来动态拼接
先说下where后面的筛选条件,这就要说到Criteria了,Criteria里面提供了许多筛选方法,如下图
Example 传入的User.class会自动获取@Table里面的表名,拼到查询语句上
@Table(name = “user”)
简单的说下里面的几个方法,大同小异
andEqualTo方法,这就相当于加了个and条件,and user_id = ‘123’,这里你只要传入实体的字段名即可,通用mapper会自动帮你转换成数据库字段名
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("userId","123");
andCondition这个方法就比较灵活,你可以自己拼好查询条件放进去,可以拼接所有你想要的sql,比如子查询,外连接,分组等等,但是需要保证sql拼的没有问题,否则会抛异常
criteria.andCondition("user_id > 50 and user_id < 100");
andIn(子查询)这方法里面的value值是数组,它会把你传进去的数组,按照子查询的条件拼接好
拼接好的结果:and user_id in (‘1’,‘2’,‘3’)
andNotIn() 结果 :and user_id not in (‘1’,‘2’,‘3’)
List<String> ids= userList.stream().map(User::getUserId).collect(Collectors.toList());
criteria.andIn("userId",ids);
andLike(模糊查询),这里也是传入实体的字段名即可
criteria.andLike("name","%测试%");
一个相当于name is not null,另一个相当于 name is null
criteria.andIsNotNull("name");
criteria.andIsNull("name");
看到这里大家肯定很疑惑,大部分条件都有了为什么没有or,在Criteria中是没有直接or的方法,所以碰到使用or会有点麻烦,如下代码,将两个Criteria用or连接起来
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andIsNull("name");
Example.Criteria criteria2 = example.createCriteria();
criteria.andIsNotNull("name");
example.or(criteria2);
如果嫌麻烦还有个简单的方法,就是andCondition方法,你可以直接拼到里面,这样就简单多了
criteria.andCondition("name = '测试' or name = '测试2'");
Criteria里面常用的方法大概都说完了
3、下面说说Example里面的方法:
orderByClause和orderBy这两个方法:
Example example = new Example(User.class);
example.setOrderByClause("user_id asc");
orderByClause既可以单属性排序,也可以多属性,但是需要自己拼接好,还需要注意里面的属性必须和表里面的属性名一致,可以自行驼峰转换
example.setOrderByClause("user_id asc,phone desc");
如果感觉麻烦可以用orderBy:
example.orderBy("userId");
这里直接写实体里面的属性名就行,后面还有3个方法,asc、desc、orderBy
多条件排序
example.orderBy("userId").asc();
example.orderBy("phone").desc();
getSelectColumns方法可以获取传入实体的所有属性名,根据需要使用
Set<String> columns = example.getSelectColumns();
distinct去重,可以单个也可以多个,需要配合selectProperties一起使用(selectProperties:需要去重的字段,可以一个,也可以多个)
example.setDistinct(true);
example.selectProperties("name");
example.selectProperties(new String[]{"name","phone"});
count某个属性
example.setCountProperty("name");
开启行级锁
example.setForUpdate(true);
清除所有条件
example.clear();
获取表名
example.getDynamicTableName();
这里再说下修改方法,修改方法分为两种:
第一种按照ID修改:
按照ID修改,你的实体里必须有@Id注解,类似下面代码
User user = new User();
user.setUserId("111");
user.setUsername("李四");
userMapper.updateByPrimaryKeySelective(user);
相当于sql
update user set username = '李四' where user_id = '111'
第二种按照条件修改:
这种情况是你根据除了ID的其他条件修改:
// set的值
User user = new User();
user.setPhone("1111111");
// where后的条件
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("username", "李四");
userMapper.updateByExampleSelective(user, example);
相当于sql
update user set phone= '1111111' where username= '李四'
Example里面基本的方法大部分都说完了,每个都是一个小方法,根据所需可以互相组合使用,大部分简单的sql应该都可以组合出来,刚开始用可能不太习惯,多用几次就会得心应手了,如果感觉这套也很麻烦,可以基于通用Mapper基础上,再封装一套自己的CRUD
本人简单的封装了一套CRUD,随便找个方法大家看下:
/**
* description 模糊查询
*
* @param t
* @version 1.0
* @date 2020/6/15 14:24
*/
@Override
public List<T> like(T t) throws IllegalAccessException {
StringBuilder sql = new StringBuilder();
sql.append("1!=1 ");
Field[] fields = t.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (field.get(t) != null) {
String name = NameUtil.underscoreName(field.getName());
sql.append("or " + name + " like '%" + field.get(t) + "%'");
}
}
Example example = new Example(t.getClass());
example.createCriteria().andCondition(sql.toString());
return this.mapper.selectByExample(example);
}
像模糊查询这种常用的方法,封装好用起来真的很舒服
大概就这些了,如果还有需要我会后续补充。