现在做的项目中一个查询功能查询条件都超过8个,现在的做法是后台判断条件然后再拼接where。这种办法太麻烦了,也不容易扩展。各位大虾有什么好的办法?小弟感激不尽!
如果你用MyBatis,这些都不是问题,处理动态条件查询是Mybatis的强项,而且效率比手动去拼sql高。
官方地址:[url=http://www.mybatis.org/core/dynamic-sql.html]mybatis动态查询[/url]
给个例子:
[code="xml"] parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
state = #{state}
AND title like #{title}
AND author_name like #{author.name}
[/code]
可以考虑如下方式 定义一个QueryModel(保存错误条件)、定义generateWhere用来生成条件、定义setValues根据条件赋值:
[code="java"] @Override
public List getByCondition( final BudgetQueryModel qm, final int firstRecord, final int maxRecords) {
return getHibernateTemplate().execute(new HibernateCallback>() {
@Override
public List doInHibernate(Session session) throws HibernateException, SQLException {
String hql = "from BudgetModel o where 1=1 "+ generateWhere(qm);
Query q = session.createQuery(hql);
setValues(q, qm);
q.setFirstResult(firstRecord);
q.setMaxResults(maxRecords);
return q.list();
}
});
}
protected void setValues(Query q, BudgetQueryModel qm) {
if(qm.getEditor() != null && qm.getEditor().getUuid() != 0) {
q.setParameter("editorUuid", qm.getEditor().getUuid());
}
if(qm.getAuditor() != null && qm.getAuditor().getUuid()!=0) {
q.setParameter("auditorUuid", qm.getAuditor().getUuid());
}
if(qm.getState() != null) {
q.setParameter("state", qm.getState());
}
if(qm.getChildCompanyCode() != null) {
q.setParameter("childCompanyCode", qm.getChildCompanyCode() + "__");
}
if(qm.getStateList() != null && qm.getStateList().size() >0) {
q.setParameterList("stateList", qm.getStateList());
}
}
protected String generateWhere(BudgetQueryModel qm) {
StringBuffer s = new StringBuffer();
if(qm.getEditor() != null && qm.getEditor().getUuid() != 0) {
s.append(" and editor.uuid=:editorUuid");
}
if(qm.getAuditor() != null && qm.getAuditor().getUuid()!=0) {
s.append(" and auditor.uuid=:auditorUuid");
}
if(qm.getState() != null) {
s.append(" and state=:state");
}
if(qm.getChildCompanyCode() != null) {
s.append(" and editor.company.code like :childCompanyCode");
}
if(qm.getStateList() != null && qm.getStateList().size() >0) {
s.append(" and state in (:stateList)");
}
return s.toString();
}[/code]
缺点:出现性能问题 调优比较麻烦
1.如果是纯jdbc的话,增强扩展性需要对条件语句做很多封装,类似于hibernate里面Criteria中Expression表达式语句。
2.如果orm采用ibatis,那么直接在配置文件中组装语句,条件可通过map传递,只需要把结果映射为对象即可。
3.如果采用hibernate,无论是hql、sql都需要自己拼接where条件语句。除非你使用Criteria