可以先看以前的自定义查询
自定义的QueryMapper查询
现在我添加了注解查询,通过使用
/** 用户账号 */
@TableField(value = "user_name")
@MapperQuery(queryType = QueryType.EQ)
private String userName;
/** 用户昵称 */
@TableField(value = "nick_name")
@MapperQuery(queryType = QueryType.NE)
private String nickName;
通过使用@MapperQuery(queryType = QueryType.EQ)
注解来统一的实现查询,但是这个是全局的,就是好比,这里希望使用eq(相等),然后那里希望使用ne(不相等)来查,注解到实体类上这个就不行了,这个只能满足全部都使用统一的,并且都是and连接的
方法代码如下
/**
* TODO 自定义遍历查询方法(通过注解)
*
* @param object
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
* @author 猫颜
* @date 下午9:20
*/
public QueryWrapper<T> queryAllByAnnotation(T object) throws IllegalAccessException,
NoSuchMethodException,
InvocationTargetException {
Class<?> aClass = object.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
// QueryWrapper<T> queryWrapper = new QueryWrapper<>();
//第一个为serialVersionUID(舍去) i为1 绕过
//获取object的所有字段
for (int i = 1; i < declaredFields.length; i++) {
field = declaredFields[i];
//类中的成员变量为private,故必须进行此操
field.setAccessible(true);
// 不能直接获取到值,可以通过构造get方法,或者调用类的get方法来获取值
// 通过StringUtils的containsIgnoreCase方法来获取方法名称
// 通过上面那种方法,有循环嵌套,性能需要优化
// 所以采取拼接get方法名
/**
*
* @author 猫颜
* @date //获取属性名称
* for (Field field:
* declaredFields) {
* System.out.println(field.getName());
* methodNameFirst = field.getName().substring(0,1).toUpperCase();
* methodName = field.getName();
* methodName = "get"+methodNameFirst+methodName.substring(1);
* System.out.println("方法名称为:"+methodName);
*
* // 优化
* System.out.println("优化:"+"get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1));
* } 下午5:18
* @param object
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
*/
//获取get方法名称
getMethodName = "get" + declaredFields[i].getName().substring(0, 1).toUpperCase() + declaredFields[i].getName().substring(1);
System.out.println(getMethodName);
// 执行get方法获取属性值
//执行方法
Method method = aClass.getMethod(getMethodName, null);
Object getValue = method.invoke(object, null);
//System.out.println("输出为:"+invoke);
// System.out.println("优化:"+"get"+declaredFields[i].getName().substring(0,1).toUpperCase()+declaredFields[i].getName().substring(1));
// 如果值不为空,则添加到eq中
if (getValue != null) {
//映射关系
// return super.eq(,field.get(object));
//获取其注解的值
// 后面可以采用查询方法注释来解决,不同的查询所需的问题
System.out.println("实体类的字段名: "+field.getName());
System.out.println("表的列名值:" + field.getAnnotation(TableField.class).value());
System.out.println("get获取值:" + getValue.toString());
// 获取MapperQuery注解的类型
String mapperTypeName = field.getAnnotation(MapperQuery.class).queryType().name();
switch(mapperTypeName){
case "EQ":
//等于
MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "NE":
//不等于
MyQueryWrapper.this.ne(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "GT":
//大于
MyQueryWrapper.this.gt(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "GE":
//大于等于
MyQueryWrapper.this.ge(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "LT":
MyQueryWrapper.this.lt(field.getAnnotation(TableField.class).value(), getValue.toString());
//小于
break;
case "LE":
MyQueryWrapper.this.le(field.getAnnotation(TableField.class).value(), getValue.toString());
//小于等于
break;
case "LIKE":
MyQueryWrapper.this.like(field.getAnnotation(TableField.class).value(), getValue.toString());
//存在
break;
case "NOTLIKE":
MyQueryWrapper.this.notLike(field.getAnnotation(TableField.class).value(), getValue.toString());
//不存在
break;
default:
//默认是eq
MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
}
}
//MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
}
return MyQueryWrapper.this;
}
所以我又新写了一个,可以自定义的查询,一个更好的查询,但是目前只支持单数值查询,就是说between这样的查不了,因为实体类的值就一个嘛。
方法代码如下
/**
* TODO 自定义查询方法
*
* @param object
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T>
* @author 猫颜
* @date 上午11:33
*/
public QueryWrapper<T> queryAll(T object, HashMap<String, Object> queryRules) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
Class<?> aClass = object.getClass();
// for (Map.Entry<String,Object> entry:
// queryRules.entrySet()) {
// System.out.println("所有值"+entry.getKey());
// }
for (String declaredField :
queryRules.keySet()) {
if (StringUtils.equals(declaredField,"connect")){
switch (String.valueOf(queryRules.get(declaredField))) {
case "AND":
//并且
break;
case "OR":
//或
MyQueryWrapper.this.or();
break;
}
continue;
}
field = aClass.getDeclaredField(declaredField);
getMethodName = "get" + declaredField.substring(0, 1).toUpperCase() + declaredField.substring(1);
method = aClass.getMethod(getMethodName, null);
getValue = method.invoke(object, null);
if (getValue != null&&field!=null) {
System.out.println("实体类的字段名: " + declaredField);
System.out.println("表的列名值:" + field.getAnnotation(TableField.class).value());
System.out.println("get获取值:" + getValue.toString());
switch (String.valueOf(queryRules.get(field.getName()))) {
case "EQ":
//等于
MyQueryWrapper.this.eq(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "NE":
//不等于
MyQueryWrapper.this.ne(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "GT":
//大于
MyQueryWrapper.this.gt(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "GE":
//大于等于
MyQueryWrapper.this.ge(field.getAnnotation(TableField.class).value(), getValue.toString());
break;
case "LT":
MyQueryWrapper.this.lt(field.getAnnotation(TableField.class).value(), getValue.toString());
//小于
break;
case "LE":
MyQueryWrapper.this.le(field.getAnnotation(TableField.class).value(), getValue.toString());
//小于等于
break;
case "LIKE":
MyQueryWrapper.this.like(field.getAnnotation(TableField.class).value(), getValue.toString());
//存在
break;
case "NOTLIKE":
MyQueryWrapper.this.notLike(field.getAnnotation(TableField.class).value(), getValue.toString());
//不存在
break;
}
}
}
return MyQueryWrapper.this;
}
这里不仅仅要把实体类传入,还需要传入一个规则,采用HashMap来保存规则
这里的QueryType是枚举类
代码如下
public enum QueryType {
//并且(默认为and连接)
AND,
//或
OR,
//等于
EQ,
//不等于
NE,
//大于
GT,
//大于等于
GE,
//小于
LT,
//小于等于
LE,
//存在
LIKE,
//不存在
NOTLIKE
}
暂时只写了这几个
然后就是调用方法
@Test
void test() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
DqUser dqUser = new DqUser();
dqUser.setUserName("maoyan");
dqUser.setNickName("猫颜");
//Hashmap是无序的,所以要使用LinkedHashMap
HashMap<String, Object> queryRules = new LinkedHashMap<>();
// HashMap<String, Object> queryRules = new HashMap<>();
queryRules.put("userName", QueryType.EQ);
queryRules.put("connect",QueryType.OR);
queryRules.put("nickName",QueryType.EQ);
MyQueryWrapper<DqUser> myQueryWrapper = new MyQueryWrapper<>();
// myQueryWrapper.queryAllByAnnotation(dqUser);
myQueryWrapper.queryAll(dqUser,queryRules);
//System.out.println(myQueryWrapper.allEq(dqUser));
// QueryWrapper queryWrapper = new QueryWrapper<DqUser>();
// queryWrapper.eq("nick_name","maoyan");
DqUser dqUser1 = dqUserMapper.selectOne(myQueryWrapper);
System.out.println(dqUser1);
myQueryWrapper.clear();
}
这里规则hashmap使用的是LinkedHashMap
,因为hashmap传入没有规则,所以会乱,而LinkedHashMap是有规则的,当然你也可以更改代码为list,但是方法中也要相应的更改就可以了。
然后就是基本编写完成的论坛后端框架,功能都有,后续会慢慢让它变得更好
QucikDevelop论坛框架