zoukankan      html  css  js  c++  java
  • hibernate:通用DAO+动态生成HQL语句

    写WEB项目写的多了,感觉DAO层的代码太相似了,几乎写DAO的时候只要写好了一个类的DAO后另外几个类的DAO都是ctrl+C ctrl+V然后修改修改其中的参数后就完工了。前段时间无聊就去研究了下java的反射结果动态生成HQL语句的工具类就这样被我写出来了,贴上源码

    public class BaseDao {
        
        protected Session session;
        Transaction transaction;
        /**
         * 打开session并且创建事物
         */
        protected void open(){
            if(session == null || !session.isOpen()){
                session = HibernateSessionFactory.getSession();
                transaction = session.beginTransaction();
            }
        }
        /**
         * 关闭session并且提交事物
         */
        protected void close(){
            if(session!=null){
                transaction.commit();
                session.close();
            }
        }
    }
    /**
     * 通用DAO接口
     * @author Administrator
     *
     */
    public interface InCommonDao {
        public void add(Object o);
        public void delete(Object o);
        public void delete(long id,Class c);
        public void update(Object o);
        public Object query(long id,Class c);
        //public Object query(Object o);
        public List query(String sql , List condition);
    }
    /**
     * 通用DAO接口实现
     * @author Administrator
     *
     */
    public class CommonDaoImpl extends BaseDao implements InCommonDao {
    
        @Override
        public void add(Object o) {
            // TODO Auto-generated method stub
            this.open();
            this.session.save(o);
            this.close();
        }
    
        @Override
        public void delete(Object o) {
            // TODO Auto-generated method stub
            this.open();
            this.session.delete(o);
            this.close();
        }
    
        @Override
        public void delete(long id, Class c) {
            // TODO Auto-generated method stub
            this.open();
            Object o = this.query(id, c);
            session.delete(o);
            this.close();
        }
    
        @Override
        public void update(Object o) {
            // TODO Auto-generated method stub
            this.open();
            session.clear();
            this.session.saveOrUpdate(o);
            this.close();
        }
    
        @Override
        public Object query(long id, Class c) {
            // TODO Auto-generated method stub
            this.open();
            return session.get(c, id);
        }
    
        @Override
        public List query(String sql, List condition) {
            // TODO Auto-generated method stub
            this.open();
            Query query = session.createQuery(sql);
            if (condition != null && condition.size() > 0) {
                for (int i = 0; i < condition.size(); i++) {
                    query.setParameter(i, condition.get(i));
                }
            }
            return query.list();
        }
        
        public Object query(String sql, List condition,Boolean bool) {
            // TODO Auto-generated method stub
            this.open();
            Query query = session.createQuery(sql);
            if (condition != null && condition.size() > 0) {
                for (int i = 0; i < condition.size(); i++) {
                    query.setParameter(i, condition.get(i));
                    //System.out.println(condition.get(i));
                }
            }
            return query.uniqueResult();
        }
    
        /*
         * @Override public Object query(Object o) { // TODO Auto-generated method
         * stub this.open(); session.refresh(o); return o; this.open(); return
         * query(((User)o).getId()); }
         */
    }
    /**
     * 给对象做反射并且定于返回HQL语句方法的抽象类
     * @author Administrator
     *
     */
    public abstract class SQLSuper {
        
        protected StringBuffer SQL;
    
        public StringBuffer getSQL() {
            return SQL;
        }
    
        public void setSQL(StringBuffer sQL) {
            SQL = sQL;
        }
    
        public abstract String getSQL(Object obj , List condition,OrderBy orderBy);
        
        /**
         * 返回所有类的名字
         * @param tables
         * @return List<String>
         */
        protected List<String> getClassNames(List<?> tables){
            List<String> classNames = null;
            if(tables != null && tables.size()!=0){
                classNames = new ArrayList<String>();
                for(Object obj : tables){
                    /*if(obj instanceof Content){
                        classNames.add(obj.getClass().getSimpleName());
                    }else if(obj instanceof Member){
                        classNames.add(obj.getClass().getSimpleName());
                    }else if(obj instanceof NewsInfo){
                        classNames.add(obj.getClass().getSimpleName());
                    }else if(obj instanceof Topic){
                        classNames.add(obj.getClass().getSimpleName());
                    }*/
                    classNames.add(obj.getClass().getSimpleName());
                }
            }
            return classNames;
        }
        
        /**
         * 返回类的名字
         * @param table
         * @return
         */
        protected String getClassName(Object table){
            String className = null;
            if(table != null){
                    /*if(table instanceof Content){
                        className=table.getClass().getSimpleName();
                    }else if(table instanceof Member){
                        className=table.getClass().getSimpleName();
                    }else if(table instanceof NewsInfo){
                        className=table.getClass().getSimpleName();
                    }else if(table instanceof Topic){
                        className=table.getClass().getSimpleName();
                    }*/
                className=table.getClass().getSimpleName();
            }
            return className;
        }
        
        /**
         * 给传入的对象做反射
         * @param o
         * @return
         */
        protected Class<?> getClassReverberate(Object o){
            String ClassName = o.getClass().getName();
            Class<?> demo = null;
            try {
                demo = Class.forName(ClassName);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return demo;
        }
        
        /**
         * 返回类中的所有属性
         * @param o
         * @return List<String>
         */
        protected List<String> getClassPropertyName(Object o) {
            Class<?> demo = this.getClassReverberate(o);
            List<String> classPropertyNames = null;
            Field[] field = demo.getDeclaredFields();
            classPropertyNames = new ArrayList<String>();
            for (int i = 0; i < field.length; i++) {
                classPropertyNames.add(field[i].getName());
            }
            return classPropertyNames;
        }
        
        /**
         * 使用反射调用对象的get方法
         * @param obj
         *            操作的对象
         * @param att
         *            操作的属性
         * */
        public Object getter(Object obj, String att) {
            try {
                Method method = obj.getClass().getMethod("get" + firstLower(att));
                return method.invoke(obj);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
     
        /**
         * 使用反射调用对象的set方法
         * @param obj
         *            操作的对象
         * @param att
         *            操作的属性
         * @param value
         *            设置的值
         * @param type
         *            参数的属性
         * */
        public void setter(Object obj, String att, Object value,
                Class<?> type) {
            try {
                Method method = obj.getClass().getMethod("set" + firstLower(att), type);
                method.invoke(obj, value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        /**
         * 给setter()的操作的属性首字母大写
         * @param att setter()操作的属性
         * @return 
         */
        protected String firstLower(String att) {
            StringBuffer sb = new StringBuffer();
            sb.append(att.substring(0,1).toUpperCase());
            sb.append(att.substring(1, att.length()));
            return sb.toString();
        }
    }
    /**
     * 返回HQL语句的工具类,实现SQLSuper抽象类
     * @author Administrator
     *
     */
    public class SQLUtil extends SQLSuper {
        @Override
        public String getSQL(Object obj , List condition ,OrderBy orderBy) {
            /*if(condition == null){
                condition = new ArrayList();
            }*/
            StringBuffer sb = new StringBuffer();
            sb.append(" from ");
            sb.append(this.getClassName(obj));
            //sb.append(" where ");
            StringBuffer conditionSQL = new StringBuffer();
            List<String> classPropertyName = this.getClassPropertyName(obj);
            for (int i = 0; i < classPropertyName.size(); i++) {
                Object gett = this.getter(obj, classPropertyName.get(i).toString());
                if (gett == null || gett.equals("-1") || gett.toString().equals("-1")) {
                    continue;
                }
                /*if (i > 0) {
                    conditionSQL.append(" and ");
                }*/
                if(gett instanceof List){
                    //Object[] array = (Object[])gett;
                    //Array array = (Array) gett;
                    List array = (List) gett;
                    if(array.size()==1){
                        conditionSQL.append(classPropertyName.get(i).replace('_', '.')+" > ?");
                        condition.add(array.get(0));
                    }else if(array.size()==2){
                        conditionSQL.append(classPropertyName.get(i).replace('_', '.')+" between ? and ?");
                        condition.add(array.get(0));
                        condition.add(array.get(1));
                    }
                }else{
                    conditionSQL.append(classPropertyName.get(i).replace('_', '.')+" = ? ");
                    
                    condition.add(gett);
                }
                conditionSQL.append(" and ");
                
            }
            if(conditionSQL.toString().length()>0){
                sb.append(" where ");
                sb.append(conditionSQL.toString());
                sb.append(" 1 = 1 ");
            }
            sb.append(" order by ");
            sb.append(orderBy.getColumn());
            sb.append("  ");
            sb.append(orderBy.getType());
            System.out.println(sb.toString());
            for (Object o : condition) {
                System.out.println(o);
            }
            return sb.toString();
        }
        /*public static void main(String[] args) {
            House house = new House();
            house.setId(2);
            house.setStreet_id(3);
            SQLUtil sql = new SQLUtil();
            System.out.println(sql.getSQL(house));
        }*/
    
    }
    /**
     * HTL语句的排序属性类
     * @author Administrator
     *
     */
    public class OrderBy {
        private String column = "id";
        /**
         * desc or asc
         */
        private String type = "asc";
        public String getColumn() {
            return column;
        }
        public void setColumn(String column) {
            this.column = column;
        }
        public String getType() {
            return type;
        }
        public void setType(String type) {
            this.type = type;
        }
        
    }

    动态生成HQL语句是通过反射进行的,那么就需要传入实体类了吧。但是Hibernate映射的实体类确实不能用,需要进行修改

    修改的示例:

    hibernate的映射实体类

    public class House implements java.io.Serializable {
    
        // Fields
    
        private Long id;
        private User user;
        private Type type;
        private Street street;
        private String title;
        private String descrition;
        private Date ployDate;
        private Double price;
        private String contact;
        private Long area;
    
        // Constructors
    
        /** default constructor */
        public House() {
        }
    
        /** full constructor */
        public House(User user, Type type, Street street, String title,
                String descrition, Date ployDate, Double price, String contact,
                Long area) {
            this.user = user;
            this.type = type;
            this.street = street;
            this.title = title;
            this.descrition = descrition;
            this.ployDate = ployDate;
            this.price = price;
            this.contact = contact;
            this.area = area;
        }
    
        // Property accessors
    
        public Long getId() {
            return this.id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public User getUser() {
            return this.user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        public Type getType() {
            return this.type;
        }
    
        public void setType(Type type) {
            this.type = type;
        }
    
        public Street getStreet() {
            return this.street;
        }
    
        public void setStreet(Street street) {
            this.street = street;
        }
    
        public String getTitle() {
            return this.title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getDescrition() {
            return this.descrition;
        }
    
        public void setDescrition(String descrition) {
            this.descrition = descrition;
        }
    
        public Date getPloyDate() {
            return this.ployDate;
        }
    
        public void setPloyDate(Date ployDate) {
            this.ployDate = ployDate;
        }
    
        public Double getPrice() {
            return this.price;
        }
    
        public void setPrice(Double price) {
            this.price = price;
        }
    
        public String getContact() {
            return this.contact;
        }
    
        public void setContact(String contact) {
            this.contact = contact;
        }
    
        public Long getArea() {
            return this.area;
        }
    
        public void setArea(Long area) {
            this.area = area;
        }
    
    }

    修改后用来反射生成where条件的实体类

    public class House {
    
        private long id = -1;
        private long user_id = -1;
        private long type_id = -1;
        private long street_id = -1;
        private String title;
        // private String descrition;
        // private Date ployDate;
        /**
         * price[0] 为开始价格
         * price[1] 为结束价格
        */
        private List price;
    
        /**
         * area[0] 为开始大小
         * area[1] 为结束大小
        */
        private List area;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public long getUser_id() {
            return user_id;
        }
    
        public void setUser_id(long user_id) {
            this.user_id = user_id;
        }
    
        public List getPrice() {
            return price;
        }
    
        public void setPrice(List price) {
            this.price = price;
        }
    
        public List getArea() {
            return area;
        }
    
        public void setArea(List area) {
            this.area = area;
        }
    
        public long getType_id() {
            return type_id;
        }
    
        public void setType_id(long type_id) {
            this.type_id = type_id;
        }
    
        public long getStreet_id() {
            return street_id;
        }
    
        public void setStreet_id(long street_id) {
            this.street_id = street_id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    }

    下面就贴上一个示例,这个示例是从项目中的BIZ层拿出来的。

    public class HouseBizImpl implements InHouseBiz {
    
        CommonDaoImpl commonDaoImpl = new CommonDaoImpl();
        @Override
        public List<House> getAllHouses(String price,String street,String housetype,String floorage,String title) {
            // TODO Auto-generated method stub
            com.vincent.hoseRental.entity.condition.House house = new com.vincent.hoseRental.entity.condition.House();
            if(price!=null  &&  !price.trim().equals("")){
                String[] ps = price.split("-");
                List dps = new ArrayList(2);
                dps.add(Double.parseDouble(ps[0]));
                try{
                    dps.add(Double.parseDouble(ps[1]));
                }catch (Exception e) {
                }
                house.setPrice(dps);
            }
            if(street!=null && ! street.trim().equals("")){
                house.setStreet_id(Long.parseLong(street));
            }
            if(housetype!=null  && ! housetype.trim().equals("")){
                house.setType_id(Long.parseLong(housetype));
            }
            if(floorage!=null && ! floorage.trim().equals("")){
                String[] ps = floorage.split("-");
                List dps = new ArrayList(2);
                dps.add(Long.parseLong(ps[0]));
                try{
                    dps.add(Long.parseLong(ps[1]));
                }catch (Exception e) {
                }
                house.setArea(dps);
            }
            if(title!=null && ! title.trim().equals("")){
                house.setTitle(title);
            }
            SQLUtil sqlUtil = new SQLUtil();
            List condition = new ArrayList();
            OrderBy orderBy = new OrderBy();
            orderBy.setColumn("ploy_date");
            orderBy.setType("desc");
            String sql = sqlUtil.getSQL(house, condition,orderBy);
            return commonDaoImpl.query(sql, condition);
            //return houseDao.queryHouse();
        }
    
        @Override
        public House getHouseById(int id) {
            // TODO Auto-generated method stub        
            return (House)commonDaoImpl.query(id, House.class);
        }
    
        @Override
        public void deleteHouse(int id) {
            // TODO Auto-generated method stub
            commonDaoImpl.delete(id, House.class);
        }
        
        @Override
        public void addHouse(String title, long houseType, long floorage,
                double price, long district, long street, String contact,
                String descrition,User user) {
            // TODO Auto-generated method stub
            House house = new House();
            house.setArea(floorage);
            house.setContact(contact);
            house.setDescrition(descrition);
            house.setPloyDate(new Date());
            house.setPrice(price);
            Street s = new Street(street);
            s.setDistrict(new District(district));
            house.setStreet(s);
            house.setTitle(title);
            house.setType(new Type(houseType));
            house.setUser(user);
            commonDaoImpl.add(house);
        }
    
        @Override
        public void updateHouse(long id,String title, long houseType, long floorage,
                double price, long district, long street, String contact,
                String descrition,User user) {
            House house = new House();
            house.setId(id);
            house.setArea(floorage);
            house.setContact(contact);
            house.setDescrition(descrition);
            house.setPloyDate(new Date());
            house.setPrice(price);
            Street s = new Street(street);
            s.setDistrict(new District(district));
            house.setStreet(s);
            house.setTitle(title);
            house.setType(new Type(houseType));
            house.setUser(user);
            commonDaoImpl.update(house);
        }
    
    }

    其实这里还缺少一个分组的条件,既然是Hibernate那就很简单了,BIZ层将生成好的HQL语句和条件给DAO层的时候附带一个分组类的对象过去,在query对象中作下分组就OK了。

  • 相关阅读:
    [ html canvas 案例 -- 绘制文本图片 ] canvas案例 -- 绘制文本图片演示
    [ javascript 创建随机颜色 ] 多种方式来创建随机颜色
    [ html canvas shadowOffsetX shadowOffsetY shadowBlur shadowColor ] canvas绘图属性 shadowOffsetX shadowOffsetY shadowBlur shadowColor 属性演示
    [ html canvas font textAlign textBaseline measureText().width ] canvas绘图属性 font textAlign textBaseline measureText().width 属性演示
    [ html canvas ] canvas绘制太阳系实例代码
    [ html canvas quadraticCurveTo ] canvas绘图quadraticCurveTo()属性研究实例演示之二
    [ html canvas arcTo ] canvas绘图 arcTo()属性研究实例演示之二
    [ html createLinearGradient createRadialGradient 绘制背景渐变方式 ] canvas绘制渐变 createLinearGradient createRadialGradient 绘制背景渐变方式 属性实例
    hadoop常见问题汇总
    hive数据导入
  • 原文地址:https://www.cnblogs.com/BrightMoon/p/3332275.html
Copyright © 2011-2022 走看看