`
busing
  • 浏览: 41353 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

查询框架

阅读更多
先定义一个枚举,配置条件查询是什么类型的,like = 还是between and。目前实现的是这三种

-------------------------------------------------------------------------

public enum CType {
    like,equal,between
}


-------------------------------------------------------------------------

定义annotation,用于注解在字段上面


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConditionType {
    CType value();
    String andField() default "";
    String queryField() default "";
}

-------------------------------------------------------------------------

根据bean的字段注解生成查询语句


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;


public class HqlCreator {

   
    public static void createHql(StringBuilder hql,Object object,List<Object> params)
    {
        try {
            //加载class
            Class clazz=object.getClass();
           
            //获取私有字段
            Field[] fields=clazz.getDeclaredFields();
           
            //遍历字段
            for (Field field : fields) {
               
                //如果字段上有 ConditionType 的注解
                if(field.isAnnotationPresent(ConditionType.class))
                {
                    //获取注解的value值
                    ConditionType conditionType=field.getAnnotation(ConditionType.class);
                    CType ct=conditionType.value();
                   
                    //调用get方法
                    Object objValue=invokeGetMethodByFieldName(field.getName(), object);
                   
                   
                    //获取字段类型
                    Class typeClass=field.getType();
                   
                    if(objValue==null)
                        continue;
                   
                    //检查字段是否为空
                    if(!checkTypeNull(typeClass,objValue)){
                        continue;
                    }
                   
                    //根据注解类型生成相应的语句和参数
                    if(ct.equals(CType.equal))
                    {   
                        hql.append(" and "+ field.getName() +" = ?");
                        params.add(objValue);
                    }
                    else if(ct.equals(CType.like))
                    {
                        hql.append(" and "+ field.getName() +" like ?");
                        params.add(Utils.returnLikeString(objValue.toString()));
                    }   
                    else if(ct.equals(CType.between))
                    {
                        hql.append(" and " +conditionType.queryField()+ " between ? and ?");
                        params.add(objValue);
                        Object andValue=invokeGetMethodByFieldName(conditionType.andField(), object);
                        params.add(andValue);
                    }
                   
                }
                System.out.println("生成hql语句为:"+hql.toString());
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
    }
   
   
    //调用get方法
    public static Object invokeGetMethodByFieldName(String fieldName,Object object)
    {
        fieldName=fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
        Method m=null;
        try {
            m = object.getClass().getMethod("get"+fieldName, null);
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Object objValue=null;
        try {
            objValue = m.invoke(object, null);
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return objValue;
    }
   
   
       private static boolean checkTypeNull(Class typeClass,Object objValue)
    {
        boolean flag=true;
       
        if(typeClass.equals(String.class))
        {
            if(objValue==null || Utils.isEmpty(objValue+""))
                flag=false;
        }
       
        if(typeClass.equals(Long.class))
        {
            if(objValue==null || Long.parseLong(objValue.toString())==0L)
                flag=false;
        }
       
        //后续如果出现类型判断有误,在此添加
       
        return flag;
    }

}


-------------------------------------------------------------------------

这个是用户查询时必要的几个参数,封转成bean啦


import java.util.List;

public class Paging {
    private String hql;
    private List<Object> params;
    private int start;
    private int limit;
   
   
    省略get、set   
}




-------------------------------------------------------------------------

这个就是吧 paging 这个bean进行查询的


public class CommonsDAO extends HibernateDaoSupport{
    private static final Logger log = Logger.getLogger(CommonsDAO.class);

    public List findByPageBean(final Paging page){
        if(page==null){
            return null;
        }
        List list = null;
        log.debug("分页查询");
        try {
            list = this.getHibernateTemplate().executeFind(
                    new HibernateCallback() {

                        public Object doInHibernate(Session session)
                                throws HibernateException, SQLException {
                            Query query = session.createQuery(page.getHql());
                            if(page.getParams()!=null)
                            {
                            for (int i = 0; i < page.getParams().size(); i++) {
                                query.setParameter(i, page.getParams().get(i));
                            }
                            }
                            if(page.getLimit()!=0)
                            {
                            query.setFirstResult(page.getStart());
                            query.setMaxResults(page.getLimit());
                            }
                            List list = query.list();
                            return list;
                        }
                    });
            log.debug("分页查询成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("分页查询失败",e);
            throw new RuntimeException("findByPageBean");
        }
        return list;
    }




public int findTotal(final Paging page) {
        int total=0;
        if(page==null)
        {
            return total;
        }
        log.debug("查询记录总数");
        try {
            total = Integer.parseInt((this.getHibernateTemplate().execute(
                    new HibernateCallback() {
                        public Object doInHibernate(Session session)
                                throws HibernateException, SQLException {
                            Query query = session.createQuery(page.getHql());
                            if(page.getParams()!=null)
                            {
                            for (int i = 0; i < page.getParams().size(); i++) {
                                query.setParameter(i, page.getParams().get(i));
                               
                            }
                            }
                            Object o=query.uniqueResult();
                            if(o!=null){
                                return Integer.parseInt(o.toString());
                            }
                            return 0;
                        }
                    }).toString()));
            log.debug("查询记录总数成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询记录总数失败",e);
            throw new RuntimeException("findTotal");
        }
        return total;
    }

-------------------------------------------------------------------------


现在我们写一个封装查询条件的bean


import java.util.Date;

public class ZcjzclBean {


    /**
    * @Fields cphm : 车牌号码
    */
    @ConditionType(CType.like)
    private String cphm;
   
    /**
    * @Fields jg : 价格
    */
    @ConditionType(value=CType.between,andField="jgEnd",queryField="jg")
    private Double jgStart;
    private Double jgEnd;
   
    /**
    * @Fields lc : 里程
    */
    @ConditionType(value=CType.between,andField="lcEnd",queryField="lc")
    private Long lcStart;
    private Long lcEnd;
   
    /**
    * @Fields lcdj : 里程单价
    */
    @ConditionType(value=CType.between,andField="lcdjEnd",queryField="lcdj")
    private Double lcdjStart;
    private Double lcdjEnd;
   
    /**
    * @Fields bylc : 保养里程
    */
    @ConditionType(value=CType.between,andField="bylcEnd",queryField="bylc")
    private Long bylcStart;
    private Long bylcEnd;
   
    /**
    * @Fields fzrid : 负责人id
    */
    @ConditionType(CType.equal)
    private Long fzrid;
   
    /**
    * @Fields sjid : 司机id
    */
    @ConditionType(CType.equal)
    private Long sjid;
   
    /**
    * @Fields gg : 规格
    */
    @ConditionType(CType.like)
    private String gg;
   
    /**
    * @Fields xh : 型号
    */
    @ConditionType(CType.like)
    private String xh;
   
    /**
    * @Fields zws : 座位数
    */
    @ConditionType(value=CType.between,andField="zwsEnd",queryField="zws")
    private Long zwsStart;
    private Long zwsEnd;
   
    /**
    * @Fields ys : 颜色
    */
    @ConditionType(CType.equal)
    private String ys;

    /**
    * @Fields gmrq : 购买日期
    */
    @ConditionType(value=CType.between,andField="gmrqEnd",queryField="gmrq")
    private Date gmrqStart;
    private Date gmrqEnd;
   
    /**
    * @Fields jzrq : 建账日期
    */
    @ConditionType(value=CType.between,andField="jzrqEnd",queryField="jzrq")
    private Date jzrqStart;
    private Date jzrqEnd;
   
    /**
    * @Fields zcjzrid : 资产建账人id
    */
    @ConditionType(CType.equal)
    private Long zcjzrid;

  省略get、set
-------------------------------------------------------------------------

编写查询代码



import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;


public class ZcjzclServiceImpl implements ZcjzclService {
    public static final Logger log=Logger.getLogger(ZcjzclServiceImpl.class);
    private CommonsDAO commonsDAO;
   
    public List<TZcjzcl> queryByCondition(ZcjzclBean bean,int start,int limit)
    {
        try {
            log.debug(" ");
            Paging page=getPage( bean, start, limit, false);
            List<TZcjzcl> cls=commonsDAO.findByPageBean(page);
            return cls;
        } catch (RuntimeException e) {
            log.error(" 异常");
            throw e;
        }
       
    }
   
   
    public int queryTotalByCondition(ZcjzclBean bean, int start, int limit) {
        try {
           
            log.debug(" ");
            Paging page=getPage( bean, start, limit, true);
            int total=commonsDAO.findTotal(page);
            return total;
        } catch (RuntimeException e) {
            log.error(" 异常",e);
            throw e;
        }
    }
   
   
    private Paging getPage(ZcjzclBean bean, int start, int limit,boolean isTotal)
    {
        try {
            log.debug("组装查询语句及条件");
            List<Object> params=new ArrayList<Object>();
            StringBuilder hql=new StringBuilder();
            if(isTotal)
                hql.append("select count(*) from TZcjzcl where 1=1 ");
            else
                hql.append("from TZcjzcl where 1=1 ");
           
            if(bean!=null)
            {
                HqlCreator.createHql(hql, bean, params);
            }
           
            Paging page=new Paging();
            page.setHql(hql.toString());
            page.setStart(start);
            page.setLimit(limit);
            page.setParams(params);
           
            return page;
        } catch (RuntimeException e) {
            log.error("组装查询语句及条件异常",e);
            throw e;
        }
    }
   
  
     省略get、set
}




-------------------------------------------------------------------------

要加什么条件直接在查询条件bean里面加就完啦。








分享到:
评论
10 楼 busing 2010-12-27  
jackerxff 写道
可以重写DetachedCriteria,底层通过jdbcTemplate实现,完全使用jdbcTemplate实现一套和Hibernate Criteria相当的查询,CRUD我已经全部实现了,当然查询时候还是依赖实体类,实现可以利用JPA注解,将JDBC返回的List<Map<String,Object>>装入实体类中。
   再更进一步,不用实体类,利用Javassist动态的生产实体类对象,再将数据装入,唯一不爽的是返回的是Object,由于EL,OGNL,FreeMarker,JSON-lib等都是利用反射获取相应的字段数据,这个不是问题(利用Javasssist动态生成field和相应的getter,不需setter,因为只能通过反射设置取值,只是上面的得利用getter方法,这样就像JavaScript 中可以动态修改prototype一样),这样就可以建立一个与具体表无关的查询,再利用重写的DetachedCriteria将查询表单中的字段与数据库表中的字段进行如楼主一样的适配,挺完美的通用查询解决方案,代码我已经实现,有需要可以贴上



  愿意的话传上来 大家学习下吧,都动态产生对象了额,直接从页面获取 实体名称,自己创建实体,赋值查询。确实很方便,就是写这种东西,反射必须要用
9 楼 jackerxff 2010-12-24  
可以重写DetachedCriteria,底层通过jdbcTemplate实现,完全使用jdbcTemplate实现一套和Hibernate Criteria相当的查询,CRUD我已经全部实现了,当然查询时候还是依赖实体类,实现可以利用JPA注解,将JDBC返回的List<Map<String,Object>>装入实体类中。
   再更进一步,不用实体类,利用Javassist动态的生产实体类对象,再将数据装入,唯一不爽的是返回的是Object,由于EL,OGNL,FreeMarker,JSON-lib等都是利用反射获取相应的字段数据,这个不是问题(利用Javasssist动态生成field和相应的getter,不需setter,因为只能通过反射设置取值,只是上面的得利用getter方法,这样就像JavaScript 中可以动态修改prototype一样),这样就可以建立一个与具体表无关的查询,再利用重写的DetachedCriteria将查询表单中的字段与数据库表中的字段进行如楼主一样的适配,挺完美的通用查询解决方案,代码我已经实现,有需要可以贴上
8 楼 woshicaiqiang 2010-12-24  
woding
7 楼 flynofry 2010-12-24  
yangguo 写道
请不要耦合hibernate,谢谢。

有些人总是说分层,但是dao接口里总是有具体化的东西(比如hibernate的东西)。搞形式玩。
6 楼 yangguo 2010-12-24  
请不要耦合hibernate,谢谢。
5 楼 busing 2010-12-24  
jackerxff 写道
和我的一样的代码,我写的更全面,还有就是使用DetachedCriteria(在组合查询条件时候相当的简单),在Service通过生成一个DetachedCriteria,利用注解将Form中的值传入DetachedCriteria,到DAO层使用hibernateTemplate.findByCriteria(criteria, page.getStart(), page.getLimit());搞定,这样如果无法满足查询,则可以在Action中提前生成DetachedCriteria,做一定的操作,再传给Service。
对于一个数据库设计良好的的系统,bean是不会膨胀的,这种方式专门处理多条件查询(一般大于5个),其他的可以另行设计,bean设计好继承关系,将公有的查询条件抽象到父类,bean文件也不会很大

还有改进下 @ConditionType,还可以直接生成页面

你说的DetachedCriteria ,有时间研究下。真能慢慢做,把增删改查都能做出来,包括页面。那就爽了额,但是最大的瓶颈是 遇到联表就束手无策了额…… 
4 楼 jackerxff 2010-12-24  
和我的一样的代码,我写的更全面,还有就是使用DetachedCriteria(在组合查询条件时候相当的简单),在Service通过生成一个DetachedCriteria,利用注解将Form中的值传入DetachedCriteria,到DAO层使用hibernateTemplate.findByCriteria(criteria, page.getStart(), page.getLimit());搞定,这样如果无法满足查询,则可以在Action中提前生成DetachedCriteria,做一定的操作,再传给Service。
对于一个数据库设计良好的的系统,bean是不会膨胀的,这种方式专门处理多条件查询(一般大于5个),其他的可以另行设计,bean设计好继承关系,将公有的查询条件抽象到父类,bean文件也不会很大

还有改进下 @ConditionType,还可以直接生成页面
3 楼 icanfly 2010-12-24  
那不是每个查询都得写一个查询bean,这样bean膨胀是不是太厉害了
2 楼 busing 2010-12-23  
zb7503 写道
遇到 条件联动的,日期选择的,怎么处理?

页面把添加传好就可以啊,日期用between and
1 楼 zb7503 2010-12-23  
遇到 条件联动的,日期选择的,怎么处理?

相关推荐

    自定义查询框架Criteria

    我尝试着模仿hibernate的criteria构建这么一个轻量级查询框架,提供一下特点: 1 可以根据前台传过来的查询数据自动构建查询条件 2 可以生成纯SQl 3 也可以直接使用preparestatement进行查询,返回我们想要的数据。 ...

    一个基于原生Java代码查询方式的JPA查询框架.zip

    标题“一个基于原生Java代码查询方式的JPA查询框架.zip”指的是一个使用Java Persistence API(JPA)的查询框架,该框架允许开发者使用原生的Java代码进行数据库查询,而不是依赖于HQL(Hibernate Query Language)...

    数据库查询框架测试

    数据库查询同一话, 客户端发送sql,服务端查询数据并且返回给客户端。使用udt通信,json格式交互。fastjson序列化数据。列存储方式,自己封装的表结构,列结构,行结构。优化了行。具体一点的介绍可以看我的博文。 ...

    行业分类-设备装置-一种建立通用查询框架的方法及装置.zip

    标题中的“行业分类-设备装置-一种建立通用查询框架的方法及装置”表明这是一个关于设备装置领域的技术,特别是涉及到了通用查询框架的构建方法和相关装置。这个主题是信息技术中的一个重要部分,因为它涉及到数据...

    通用查询框架(hibernate+Ajax+jstl)

    基于hibernate的开源通用查询框架: 1.支持全部hql语法 2.可以支持Ajax用的 xml数据结构,也可以支持jsp、jstl、struts等标签,根据配置不同的数据解析器,得到不同结构的数据。 3.集成完整的分页功能。 4....

    基于路网的三维虚拟现实场景间接可视查询框架.pdf

    《基于路网的三维虚拟现实场景间接可视查询框架》 本文主要探讨了在三维虚拟现实场景中,如何有效解决网络环境下B/S模式下加载大量不可视对象导致的资源消耗过高和加载速度过慢的问题。作者孔德瀚和刘永山提出了一...

    .NET查询框架

    .NET查询框架是微软开发平台上的一个重要组成部分,它提供了一种高效、灵活的方式来处理数据库查询,尤其是在数据访问层。本文将深入探讨.NET查询框架的核心概念、使用场景以及如何创建和执行查询。 首先,让我们...

    通用查询框架

    通用查询框架,是一种高度可定制化的数据查询工具,旨在提供灵活、高效且易于维护的SQL语句配置能力,以满足不同场景下的数据检索需求。在软件开发中,尤其是在企业级应用中,数据查询是一个核心部分,而通用查询...

    一个类似mybatis的查询框架,功能是查询阿里云的sls日志 可快速继承到springboot的一个starter

    一个类似mybatis的查询框架,功能是查询阿里云的sls日志。可快速继承到springboot的一个starter springboot项目中引入 &lt;groupId&gt;com.biubiu&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-aliyun-sls-ibatis ...

    Milvus相似性搜索引擎:相比 Faiss 和 SPTAG 这样的算子库,Milvus 提供完整的向量数据更新,索引与查询框架

    相比 Faiss 和 SPTAG 这样的算子库,Milvus 提供完整的向量数据更新,索引与查询框架。Milvus 利用 GPU 进行索引加速与查询加速,能大幅提高单机性能。部署使用简单,降低了 AI 应用落地的难度。

    通用查询框架 Awake-API

    Awake框架hql解析模块,支持Hql子查询的用法: http://hi.baidu.com/jfheng/blog/item/96ad1852d338a4080cf3e318.html 用Awake开发查询、统计分页列表,简单多了 Awake 在Ajax应用上存在的小瑕疵请大虾们帮忙解决:...

    工资查询系统,自己花钱买的,SSH框架

    【工资查询系统】是一种基于Java技术的Web应用,利用了SSH(Struts2、Spring、Hibernate)框架,专为组织或企业设计,便于管理和查询员工的工资信息。SSH框架是Java开发领域中常用的一种组合,它整合了Struts2的MVC...

    跳蚤J2EE快速开发框架

    此开发框架内置了权限管理/组织用户管理/通用查询框架/通用增删改框架; 利用通用查询框架可以快速构建一个查询,而开发人员只须编写一个XML和一条SQL语句即可. 利用通用增删改查框架可以快速构建一个单表的增删改查...

    基于P2P结构的kNN查询框架 (2007年)

    目的提出一种基于P2P结构的移动对象kNN查询框架。方法假设移动对象具有计算处理能力和储存空间,在此基础上进行P2P结构的设计。查询的发起、响应以及计算等不借助中心服务器,而将其转移到移动对象上进行处理。采用...

    DELPHI XE7 安卓手机开发框架

    9、查询框架 10、单选择框、多选择框、日期选择框 11、本地数据库SQLITE的访问及操作、及数据库图片操作 12、获取本版号 13、提示框、提示汉化 14、百度定位 15、扫描二维码和条码 16、拔电话,(安卓、IOS通用) 17...

    pixie, 面向PHP的数据库查询生成器,框架不可知,轻量级和具有表现力.zip

    pixie, 面向PHP的数据库查询生成器,框架不可知,轻量级和具有表现力 查询生成器 一种轻量级。表达式。框架无关的PHP查询生成器它也可以被称为数据库抽象。 Pixie支持 MySQL 。SQLite和 PostgreSQL,它使用统一的API...

    XE7 安卓框架

    XE7 框架功能 1、主菜单与主界面的切换 2、StyleBook的设计 ...9、查询框架 10、单选择框、多选择框、日期选择框 11、本地数据库SQLITE的访问及操作、及数据库图片操作 12、获取本版号 13、提示框、提示汉化

    跳蚤J2EE快速开发框架使用说明

    此开发框架内置了权限管理/组织用户管理/通用查询框架/通用增删改框架; 利用通用查询框架可以快速构建一个查询,而开发人员只须编写一个XML和一条SQL语句即可. 利用通用增删改查框架可以快速构建一个单表的增删改查...

    社区::open_mailbox_with_raised_flag:JavaScript的知识图查询框架

    JavaScript的知识图查询框架Web上分散RDF上的灵活SPARQL和GraphQL。 。 用Comunica查询 阅读我们的: 或直接跳入可用的查询引擎之一: :从JavaScript应用程序或CLI查询SPARQL / GraphQL() :用于查询本地RDF...

    基于Zookeeper的国土资源档案分布式查询框架设计与实现.pdf

    #资源达人分享计划#

Global site tag (gtag.js) - Google Analytics