NutzCN Logo
问答 dao.count 不支持条件查询吗?
发布于 10天前 作者 苍蓝猛兽 95 次浏览 复制 上一个帖子 下一个帖子
标签:

如题

需求

一般带条件查询的话,总条数也要跟着条件查询,这样才能对的上。

9 回复

哪里看出来不支持了??

dao.count(User.class, Cnd.where(....));

@wendal 多谢,还有一个问题
我写了一个带条件查询的工具类,没有调查nutz有没有自带,如下:

CommonUtil

public static Criteria getCriteria(Object obj) {
		List<SqlExpressionGroup> eList = new ArrayList<SqlExpressionGroup>();
		Criteria cri = Cnd.cri();
		Class<?> clz = obj.getClass();
		Field[] fields = clz.getDeclaredFields();
		for (Field field : fields) {
			if (!field.isAccessible()) {
				field.setAccessible(true);
			}
			// 判断值为不为空
			try {
				if (!Lang.isEmpty(field.get(obj))) {
					// 获取nutz字段注解
					Column column = field.getAnnotation(Column.class);
					if (column == null) {
						continue;
					}
					// 获取数据库字段名称
					String columnName = (column.value() == "" || column.value().length() == 0) ? field.getName()
							: column.value();
					// 封装条件并塞入条件集合
					// 假使这里都是=操作
					if (field.get(obj).toString().length() != 0) {
						SqlExpressionGroup expression = Cnd.exps(columnName, "=", field.get(obj));
						eList.add(expression);
					}
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		if (!eList.isEmpty()) {
			for (SqlExpressionGroup expression : eList) {
				cri.where().and(expression);
			}
		}
		return cri;
	}

##

public QueryResult findAll(SysLog log, Page page) {
		Pager pager = dao.createPager(page.getPage(), page.getRows());
		Criteria cri = CommonUtil.getCriteria(log);
		// 动态排序也可以,这里就不写了。
		cri.getOrderBy().desc("date");
		List<SysLog> logs = dao.query(SysLog.class, cri, pager);
		pager.setRecordCount(dao.count(SysLog.class, cri));
		return new QueryResult(logs, pager);
	}

需求还是一样

请问还有更好的写法吗?

看Cnd.from命令

@wendal

Cnd.from

/**
     * 用默认规则(忽略零值和空值)生成Cnd实例
     * @param dao Dao实例,不能为null
     * @param obj 对象, 若为null,则返回值为null, 不可以是Class/字符串/数值/布尔类型
     * @return Cnd实例
     */
    public static Cnd from(Dao dao, Object obj) {
        return from(dao, obj, dftFromFieldMatcher);
    }
    
    /**
     * 根据一个对象生成Cnd条件, FieldMatcher详细控制.<p/>
     * <code>assertEquals(" WHERE name='wendal' AND age=0", Cnd.from(dao, pet, FieldMatcher.make("age|name", null, true).setIgnoreDate(true)).toString());</code>
     * @param dao Dao实例
     * @param obj 基对象,不可以是Class,字符串,数值和Boolean
     * @param matcher 过滤字段属性, 可配置哪些字段可用/不可用/是否忽略空值/是否忽略0值/是否忽略java.util.Date类及其子类的对象/是否忽略@Id所标注的主键属性/是否忽略 \@Name 所标注的主键属性/是否忽略 \@Pk 所引用的复合主键 
     * @return Cnd条件
     */
    public static Cnd from(Dao dao, Object obj, FieldMatcher matcher) {
        final SqlExpressionGroup exps = new SqlExpressionGroup();
        boolean re = Daos.filterFields(obj, matcher, dao, new Callback2<MappingField, Object>() {
            public void invoke(MappingField mf, Object val) {
                exps.and(mf.getName(), "=", val);
            }
        });
        if (re)
            return Cnd.where(exps);
        return null;
    }

现象

用Cnd.from确实很方面,但是往往查询都是like,看源码是写死了等号,这个有办法指定每个字段的操作符吗?

我的做法

Operator

/**
 * 条件查询操作符
 * 
 * @author zhulongxiang
 *
 */
@Documented
@Target(ElementType.FIELD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Operator {
	String value() default "";
}

SysLog

import java.util.Date;

import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.json.Json;

import com.elvish.oda.busin.anno.Operator;

@Table("t_sys_log")
public class SysLog {
	@Column
	private Long id;
	@Column
	@Operator("like")
	private String username;
	@Column
	private Date date;
	@Column
	@Operator("like")
	private String url;
	@Column
	@Operator("like")
	private String method;
	@Column
	private String ip;
	@Column("class_method")
	private String classMethod;
	@Column
	private Object args;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public String getClassMethod() {
		return classMethod;
	}

	public void setClassMethod(String classMethod) {
		this.classMethod = classMethod;
	}

	public Object getArgs() {
		return args;
	}

	public void setArgs(Object args) {
		this.args = args;
	}

	@Override
	public String toString() {
		return Json.toJson(this);
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

}

CommonUtil

public static Criteria getCriteria(Object obj) {
		Criteria cri = Cnd.cri();
		Class<?> clz = obj.getClass();
		Field[] fields = clz.getDeclaredFields();
		for (Field field : fields) {
			if (!field.isAccessible()) {
				field.setAccessible(true);
			}
			// 判断值为不为空
			try {
				if (!Lang.isEmpty(field.get(obj))) {
					if (field.get(obj).toString().length() == 0) {
						continue;
					}
					// 获取nutz字段注解
					Column column = field.getAnnotation(Column.class);
					if (column == null) {
						continue;
					}
					// 获取数据库字段名称
					String columnName = (column.value() == "" || column.value().length() == 0) ? field.getName()
							: column.value();
					// 获取操作符
					Operator oper = field.getAnnotation(Operator.class);
					if (oper == null) {
						continue;
					}
					// 封装条件并塞入条件集合
					SqlExpressionGroup expression = Cnd.exps(columnName, oper.value(), field.get(obj));
					cri.where().and(expression);
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return cri;
	}

测试

public QueryResult findAll(SysLog log, Page page) {
		Pager pager = dao.createPager(page.getPage(), page.getRows());
		Criteria cri = CommonUtil.getCriteria(log);
		// Criteria cri = Cnd.from(dao, log);

		// 动态排序也可以,这里就不写了。
		// cri.getOrderBy().desc("date");
		List<SysLog> logs = dao.query(SysLog.class, cri, pager);
		pager.setRecordCount(dao.count(SysLog.class, cri));
		return new QueryResult(logs, pager);
	}

结果

sql中拼接操作符。查询正确。

求指教

nutz是否可以提供这种简易写法?

@wendal

求指教

nutz有没有更简易写法,上面说错了

参照Cnd.make的方式写一个自己喜欢的呗

@wendal 木有看到有些操作符的地方呀??有空的话,可否简单写个示例

什么操作符???

    public static Cnd from(Dao dao, Object obj, FieldMatcher matcher) {
        final SqlExpressionGroup exps = new SqlExpressionGroup();
        boolean re = Daos.filterFields(obj, matcher, dao, new Callback2<MappingField, Object>() {
            public void invoke(MappingField mf, Object val) {
                exps.and(mf.getName(), "=", val); // 把等号换成你想要的
            }
        });
        if (re)
            return Cnd.where(exps);
        return null;
    }

想每个字段都有自己的方式? 那得自定义一套规则了, 我看你最初的代码也就全部等号

添加回复
请先登陆
回到顶部