JPA


  • 查詢語言:Query Language
    • 條件表達式:where+having+on
      • 輸入參數:支持位置參數 ?1,和命名參數 :userName,但這兩者不能混用
      • 條件組合:屬性導航:user.userName,一元運算 + -,邏輯操作 NOT AND OR,
        比較Comparison:= > >= < <= <>
        區間Between:[NOT] BETWEEN,支持數字、字符串、日期
        集合In:[NOT] IN,f in ('a', 'b') 等價於 f='a' or f='b'
        相似Like:[NOT] LIKE,支持單個字符_、多個字符%、轉義字符\_
        空值Null:IS [NOT] NULL,
        空集合:IS [NOT] EMPTY,select o from Order o where o.lineItems is empty,
        集合成員:[NOT] MEMBER OF,select p from Person p where 'Joe' member of p.nicknames;
        存在性Exist:[NOT] EXISTS,select emp from Employee emp where exists ( select spouseEmp from Employee spouseEmp where spouseEmp = emp.spouse );//spouse配偶
        全部或任意:All+Any+Some,select emp from Employee where emp.salary > All { select m.salary from Manager m where m.department=emp.department };//部門高新員工
        子查詢Subquery:select goodCustomer from Customer goodCustomer where goodCustomer.balanceOwed < ( select avg(c.balanceOwed)/2.0 from Customer c );//優質客戶
      • 原生標准操作
        字符串:concat,substr,trim,lower,
        算術:abs,sqrt,mod,size,index(select w.name from Course c join c.studentsWaitlist w where c.name='Calculus' and index(w)=0;)
        聚合:count,max,min,avg,sum,distinct
        日期:current_date,current_time,current_timestamp
        過程調用:select c from Customer c where function( 'hasGoodCredit', c.balance, c.creditLimit );
        分支語句:update Employee e set e.salary = 
        case e.rating when 1 then e.salary*1.1
                              when 2 then e.salary*1.05
                              else e.salary*1.01
        end
        類型判斷:select e from Employee e where type(e) in ( Exempt, Contractor )
    • 分組和結果限定
      select c.status, avg(c.filledOrderCount), count(c) from Customer c group by c.status having c.status in ( 1, 2 );//統計狀態1和2的客戶信息
      select c, count(o) from Customer c Join c.orders o group by c having count(o) >= 5;//查詢訂單數大於等於5的客戶
    • 排序
      select o from Customer c JOIN c.orders o JOIN c.address a where a.state='CA' order by o.quantity DESC, o.totalcost;//總量倒序,花費升序
    • 批量更新和刪除
      delete from Customer c where c.status='inactive' and c.orders is empty;//刪除未激活且沒有訂單的用戶
      update Employee e set e.address.building=22 where e.address.building=14 and e.project='Java EE';//修改Java EE項目組成員的地址
  • 查詢條件:Criteria,標准條件
    • CriteriaBuilder,@PersistenceUnit EntityManagerFactory.getCriteriaBuilder(); 或 @PersistenceContext EntityManager.getCriteriaBuilder();
      CriteriaQuery<T> createQuery(Class<T> resultClass);//創建查詢,返回結果類型為resultClass
      CriteriaQuery<Tuple> createTupleQuery();//創建查詢,返回元組類型,Tuple包含多個TupleElements
      CriteriaUpdate<T> createCriteriaUpdate(Class<T> targetEntity);//創建對targetEntity的批量修改操作
      CriteriaDelete<T> createCriteriaDelete(Class<T> targetEntity);//創建對targetEntity的批量刪除操作
      CompoundSelection<Tuple> tuple(Selection<?>... selections);//創建tupe-valued查詢
      CompoundSelection<Object[]> array(Selection<?>... selections);//創建array-valued查詢
      Order asc(Expression<?> x);//創建表達式值的升序,desc為降序
      Expression<Double> avg(Expression<N> x);//計算平均值,還有count[Distinct],sum,max+min(數字),greatest+least(字符串、日期等),
      Predicate exists(Subquery<?> subquery);//判斷子查詢是否存在,還有all,some,any,isTrue,isFalse,is[Not]Null
      Predicate and(Expression<Boolean> x, Expression<Boolean> y);//邏輯與,還有or,not
      Predicate or(Predicate... restrictions);//多個條件或,還有與and
      Predicate conjunction();//條件與,沒有時返回true;還有disjunction,條件或,沒有時返回false;
      Predicate equal(Expression<?> x, Expression<?> y);//判斷是否相等,還有greaterThan[OrEqualTo](Comparable),between,gt+ge+lt+le(Number)
      Predicate notEqual(Expression<?> x, Object value);//判斷是否不等,還有lessThan[OrEqualTo],like+notLike
      Expression<Number> sum(Expression<?> x, N y);//算術運算,還有neg+abs+prod積+diff差+quot商+mod模+sqrt平方根+concat+substring+trim+upper+length+locate
      Expression<Long> toLong(Expression<?> x);//類型轉換,還有Integer+Float+Double+BigDecimal+BigInteger+String
      Expression<T> literal(T value);//轉換常量值,
      Predicate is[Not]Empty(Expression<c> collection);//測試集合非空,還有size+is[Not]Member,q.where(cb.isEmpty(order.get("lineItems"))); => where order.lineItems is empty
      Expression<Collection<V>> values(M map);//從map的values()創建集合條件,還有keys
      Expression<java.sql.Date> currentDate();//當前日期,還有java.sql.Time=currentTime,java.sql.Timestamp=currentTimestamp
      In<T> in(Expression<T> expression);//q.having( cb.in( customer.get("status").value(1).value(2) ) ); => having c.status in ( 1,2 )
    • CriteriaQuery -> AbstractQuery
      Root<X> from(Class<X> entityClass);//獲得查詢根,或與已有根計算笛卡爾積
      AbstractQuery<T> where(Predicate... restrictions);//限定條件(替換之間的條件)
      AbstractQuery<T> groupBy(Expression<?>... grouping);//分組,還有having+orderBy
      CriteriaQuery<T> select(Selection<?> selection);//設置選擇結果
      CriteriaQuery<T> multiselect(Selection<?>... selections);//多個選擇結果
      執行復雜條件查詢
      @PersistenceContext EntityManager em;
      TypedQuery<T> query = em.createQuery(CriteriaQuery<T> cq);//創建查詢對象
      query.setFirstResult().setMaxResults().getResultList();//獲得查詢結果
    • CriteriaUpdate+CriteriaDelete,有from+where
      CriteriaUpdate<T> set(Path attribute, X value);//更新屬性

      update customer c set c.status='outstanding' where c.balance<1000;
      CriteriaUpdaate<Customer> q=cb.createCriteriaUpdate(Customer.class);
      Root<Customer> c=q.from(Customer.class);
      q.set(c.get("status"), "outstanding")
      .where( cb.lt(c.get("balance"), 1000) );
    • Root實體根+Join表連接 -> From查詢 -> Path路徑+Predicate與或 -> Expression表達式 -> Selection選擇返回值
      Selection alias(String alias);//設置別名
      Predicate isNull();//是否空,還有isNotNull+
      Predicate in(Object... values);//集合元素,
      Path<Y> get(String attributeName);//獲取路徑
      Join join(String attributeName, JoinType type);//鏈接屬性表,還有joinCollection,joinSet,joinList(t.index()限定多個對象的個數),joinMap(t.key()限定對象映射的key)
      Join on(Predicate... restrictions);//表鏈接
    • 查詢樣例,最好先組織SQL和JPQL語句,然后再翻譯為對象方法調用
      • 獲取全部或限定條件,select c from customer c where c.name="Jack";
        CriteriaQuery<Customer> q = CriteriaBuilder.createQuery(Customer.class);//返回類型為Customer
        Root<Customer> customer = q.from(Customer.class);//查詢表Customer
        q.select(customer);//查詢整個Customer對象
        q.where(cb.equal( customer.get("name"), 'Jack'));//限定name="Jack"的對象
      • 連接統計,select s.name, count(p) from Supplier s left join s.products on p.status='inStock' group by s.name;
        CriteriaQuery<Tuple> q = cb.createTupleQuery();//配合后面的multiselect
        Root<Supplier> s = q.from(Supplier.class);//
        Join<Supplier, Product> p = s.join("products", JoinType.LEFT);//連接產品表
        p.on(cb.equal(p.get("status"), "inStock"));//限定連接條件,s.join("products", JoinType.LEFT).on(cb.equal(p.get("status"), "inStock"));
        q.groupBy( s.get("name") );
        q.multiselect( s.get("name"), cb.count(p) );//等價於q.select(cb.tuple(s.get("name"), cb.count(p)));,還有cb.array,cb.construct(Type.class, ... args)
      • 深度獲取fetch join,select d from Department d left join fetch d.employees where d.deptno=1;
        CriteriaQuery<Department> q = cb.createQuery(Department.class);
        Root<Department> d = q.from(Department.class);
        d.fetch("employees", JoinType.LEFT);//查詢結果中d.employees有值
        q.where( cb.equal(d.get("deptno"), 1) );
        q.select(d);
      • 路徑導航,select p.vendor from Employee e join e.contactInfo.phones p where e.contactInfo.address.zipcode="95054";
        CriteriaQuery<Vendor> q = cb.createQuery<Vendor.class>;//返回結果為Vendor
        Root<Employee> e = q.from(Employee.class);//從Employee開始查詢
        Join<ContactInfo, Phone> phone = e.join("contactInfo").join("phones");//連接多張表
        q.where( cb.equal(e.get("contactInfo").get("address").get("zipcode"), "95054") );
        q.select( phone.get("vendor") );
      • 類型轉換,select b.ISBN from Order o join treat(o.product AS Book) b;
        CriteriaQuery<String> q = cb.createQuery(String.class);
        Root<Order> order = q.from(Order.class);
        Join<Order, Book> book = cb.treat( order.join("product"), Book.class);
        q.select( book.get("isbn") );
      • 分支查詢,
        select e.name ,
        case when e.rating=1 then e.salary*1.1
                when e.rating=2 then e.salary*1.2
                else e.salary&1.01
        from Employee e where e.department.name='Engineering';
        CriteriaQuery<Tuple> q=cb.createTupleQuery();
        Root<Employee> e=q.from(Employee.class);
        q.where( cb.equal(e.get("department").get("name"), "Engineering") );
        q.multiselect( e.get("name"), cb.selectCase()
                                                             .when(cb.equal(e.get("rating"), 1), cb.prod(e.get("salary"), 1.1))
                                                             .when(cb.equal(e.get("rating"), 2), prod(e.get("salary"), 1.2))//這里需要常量的話調用cb.literal("value")
                                                             .otherWise(cb.prod(e.get("salary"), 1.01)) );
      • 參數
        select c from Customer c where c.status = :stat;
        CriteriaQuery<Customer> q=cb.createQuery(Customer.class);
        Root<Customer> c=q.from(Customer.class);
        ParameterExpression<Integer> param=cb.parameter(Integer.class, "stat");
        q.select(c).where(cb.equal(c.get("status"), param));
      • 子查詢,select goodCustomer from Customer goodCustomer where goodCustomer.balanceOwed < ( select avg(c.balanceOwed) from Customer c );
        CriteriaQuery<Customer> q=cb.createQuery(Customer.class);
        Root<Customer> goodCustomer=q.from(Customer.class);
        Subquery<Double> sq=q.subquery(Double.class);//子查詢返回double值
        Root<Customer> customer=sq.from(Customer.class);
        q.where(cb.lt(goodCustomer.get("balanceOwed"), sq.select(cb.avg(customer.get("balanceOwed")))));//goodCustomer.balanceOwed < avg(customer.balanceOwed)
        q.select(goodCustomer);

        select emp from Employee emp where emp.salary > all ( select m.salary from Manager m where m.department=emp.department );
        CriteriaQuery<Employee> q=cb.createQuery(Employee.class);
        Root<Employee> emp=q.from(Employee.class);
        Subquery<BigDecimal> sq=q.subquery(BigDecimal.class);
        Root<Manager> manager=sq.from(Manager.class);
        sq.select(manager.get("salary"));
        sq.where(cb.equals(manager.get("department"), emp.get("department")));
        q.select(emp).where(cb.gt(emp.get("salary"), cb.all(sq)));
  • EntityManager
    • 獲得EntityManager
      @PersistenceContext EntityManager em;
      @PersistenceUnit EntityManagerFactory emf; emf.createEntityManager()//
      javax.persistence.Persistence.createEntityManagerFactory("order");//從persistence.xml文件讀取unit配置
  • 統計接口及實現:
    調用優先級Criteria API > Java Persistence Query Language > SQL
    有些統計語句可能是在很復雜只好執行原始的SQL語句了(sql條件需在可控范圍內,最好檢查一下參數安全性),但前兩種在適當的時候還是應當多用的(防SQL注入)
    public class TongjiReposityImpl implements TongjiRepository {
        @PersistenceContext private EntityManager entityManager;
        @Override
        public CriteriaBuilder builder() { //Criteria API
            return entityManager.getCriteriaBuilder();
        }
        @Override
        public long count(CriteriaQuery<Long> query) {
            TypedQuery<Long> typedQuery = entityManager.createQuery(query);
            return typedQuery.getSingleResult();
        }
        @Override
        public Object[] sums(CriteriaQuery<Tuple> query) {
            List<Tuple> list = list(query, 0, 0);
            return list!=null && list.size()>0 ? list.get(0).toArray() : null;
        }
        @Override
        public List<Tuple> list(CriteriaQuery<Tuple> query, int firstResult, int maxResults) {
            TypedQuery<Tuple> typedQuery = entityManager.createQuery(query);
            typedQuery.setFirstResult(firstResult);
            if(maxResults>0) typedQuery.setMaxResults(maxResults);
            return typedQuery.getResultList();
        }
        @Override
        public int count(String jpql, Object... args) { //Java Persistence Query Language
            Query query = entityManager.createQuery(jpql);
            if(args!=null && args.length>0) {
                for(int i=0; i<args.length; i++) {
                    query.setParameter(i+1, args[i]);
                }
            }
            return ((Number)query.getSingleResult()).intValue();
        }
        @Override
        public Object[] sums(String jpql, Object... args) {
            List<?> list = list(jpql, args);
            if(list!=null && list.size()>0) {
                Object obj = list.get(0);
                if(obj instanceof Object[]) {
                    return (Object[])obj;
                }else {
                    return new Object[] {obj};
                }
            }
            return null;
        }
        @Override
        public List<?> list(String jpql, Object... args) {
            Query query = entityManager.createQuery(jpql);
            if(args!=null && args.length>0) {
                for(int i=0; i<args.length; i++) {
                    query.setParameter(i+1, args[i]);
                }
            }
            return query.getResultList();
        }
        @Override
        public int count(String sql) { //SQL
            Query query = entityManager.createNativeQuery(sql);
            return ((Number)query.getSingleResult()).intValue();
        }
        @Override
        public Object[] sums(String sql) {
            List<?> list = list(sql);
            if(list!=null && list.size()>0) {
                Object obj = list.get(0);
                if(obj instanceof Object[]) {
                    return (Object[])obj;
                }else {
                    return new Object[] {obj};
                }
            }
            return null;
        }
        @Override
        public List<?> list(String sql) {
            Query query = entityManager.createNativeQuery(sql);
            return query.getResultList();
        }
    }  
  • sql輔助生成工具類
    /**
     * select column from table where condition group by column having condition order by column limit from,length
     */
    public class SqlBuilder {
        private String select;
        private String from;
        private StringBuilder where = new StringBuilder();
        private String groupBy;
        private String having;
        private String orderBy;
        private String limit;
        
        public static SqlBuilder builder() {
            return new SqlBuilder();
        }
        
        /**
         * @param select
         * <li>*
         * <li>column1,column2,...
         * <li>count(column1),sum(column2),avg(column3),...
         * <li>user.id,user.name,account.amount,...
         */
        public SqlBuilder select(String select) {
            this.select = select;
            return this;
        }
        
        /**
         * @param from
         * <li>ts_user
         * <li>ts_user u left join ts_account a on u.ts_user_id = a.ts_user_id
         * <li>jpql: TsUser user left join user.tsAccount account
         */
        public SqlBuilder from(String from) {
            this.from = from;
            return this;
        }
        
        /**
         * @param where
         * <li>null, to reset where
         * <li>name like '%Jack%'
         * <li>id in (1,2,3)
         * <li>exists (select a.id from acount a where a.user_id=user.id)
         * <li>name is empty
         */
        public SqlBuilder where(String where) {
            if(StringUtils.isEmpty(where)) {
                this.where.setLength(0);
            }else {
                this.where.append(" and " + where);
            }
            return this;
        }
        
        /**
         * @param columnOperator
         * <li>column1 >=
         * <li>column2 !=
         */
        public SqlBuilder where(String columnOperator, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + columnOperator + " '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder groupBy(String groupBy) {
            this.groupBy = groupBy;
            return this;
        }
        
        public SqlBuilder having(String having) {
            this.having = having;
            return this;
        }
        
        public SqlBuilder orderBy(String orderBy) {
            this.orderBy = orderBy;
            return this;
        }
        
        /**
         * @param limit
         * <li>limit 0,10
         */
        public SqlBuilder limit(String limit) {
            this.limit = limit;
            return this;
        }
        
        public SqlBuilder eq(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " = '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder ne(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " != '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder like(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " like '%" + sqlParam(value.toString()) + "%'");
            }
            return this;
        }
        
        public SqlBuilder notLike(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " not like '%" + sqlParam(value.toString()) + "%'");
            }
            return this;
        }
        
        public SqlBuilder in(String column, Collection<?> value) {
            if(!CollectionUtils.isEmpty(value)) {
                where.append(" and " + column + " in (" + StringUtils.collectionToDelimitedString(value, ",""'""'") + ")");
            }
            return this;
        }
        
        public SqlBuilder notIn(String column, Collection<?> value) {
            if(!CollectionUtils.isEmpty(value)) {
                where.append(" and " + column + " not in (" + StringUtils.collectionToDelimitedString(value, ",""'""'") + ")");
            }
            return this;
        }
        
        public SqlBuilder gt(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " > '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder gte(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " >= '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder lt(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " < '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder lte(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                where.append(" and " + column + " <= '" + sqlParam(value.toString()) + "'");
            }
            return this;
        }
        
        public SqlBuilder between(String column, Object from, Object to) {
            if(StringUtils.isEmpty(from) && StringUtils.isEmpty(to)) return this;
            if(!StringUtils.isEmpty(from)) where.append(" and " + column + " >= '" + sqlParam(from.toString()) + "'");
            else if(!StringUtils.isEmpty(to)) where.append(" and " + column + " <= '" + sqlParam(to.toString()) + "'");
            else where.append(" and " + column + " between '" + sqlParam(from.toString()) + "' and '" + sqlParam(to.toString()) + "'");
            return this;
        }
        
        public String sql() {
            if(select == null || from == null//必須得有selece和from部分
                throw new RuntimeException("sql must contain select + from parts.");
            
            StringBuilder sql = new StringBuilder("select " + select+" from "+from);
            if(where.length() > 4) sql.append(" where " + where.substring(5));
            if(groupBy != null) sql.append(" group by " + groupBy);
            if(having != null) sql.append(" having " + having);
            if(orderBy != null) sql.append(" order by " + orderBy);
            if(limit != null) sql.append(" limit " + limit);
            return sql.toString();
        }
        //過濾掉引號'",逗號,分號;注釋號--等sql敏感符號
        public static String sqlParam(String sqlParam) {
            return sqlParam.replaceAll("([';]+|(--)+)""");
        }
    }
  • jpql輔助工具類,與SqlBuilder類似
    public class JpqlBuilder {
        private String select;
        private String from;
        private StringBuilder where = new StringBuilder();
        private List<Object> args = new ArrayList<Object>();
        private String groupBy;
        private String having;
        private String orderBy;
        private String limit;
        
        public static JpqlBuilder builder() {
            return new JpqlBuilder();
        }
        
        /**
         * @param select
         * <li>*
         * <li>user.id,user.name,account.amount,...
         */
        public JpqlBuilder select(String select) {
            this.select = select;
            return this;
        }
        
        /**
         * @param from
         * <li>jpql: TsUser user left join user.tsAccount account
         */
        public JpqlBuilder from(String from) {
            this.from = from;
            return this;
        }
        
        /**
         * @param where
         * <li>null, to reset where
         * <li>name like '%Jack%'
         */
        public JpqlBuilder where(String where) {
            if(StringUtils.isEmpty(where)) {
                this.where.setLength(0);
                args.clear();
            }else {
                this.where.append(" and " + where);
            }
            return this;
        }
        
        /**
         * @param columnOperator
         * <li>column1 >=
         * <li>column2 !=
         */
        public JpqlBuilder where(String columnOperator, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + columnOperator + " ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder groupBy(String groupBy) {
            this.groupBy = groupBy;
            return this;
        }
        
        public JpqlBuilder having(String having) {
            this.having = having;
            return this;
        }
        
        public JpqlBuilder orderBy(String orderBy) {
            this.orderBy = orderBy;
            return this;
        }
        
        /**
         * @param limit
         * <li>limit 0,10
         */
        public JpqlBuilder limit(String limit) {
            this.limit = limit;
            return this;
        }
        
        public JpqlBuilder eq(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " = ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder ne(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " != ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder like(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " like ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder notLike(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " not like ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder in(String column, Collection<?> value) {
            if(!CollectionUtils.isEmpty(value)) {
                where.append(" and " + column + " in (");
                boolean first = true;
                for(Object obj : value) {
                    args.add(obj);
                    if(first) {
                        first = false;
                        where.append("?"+args.size());
                    }else {
                        where.append(" , ?"+args.size());
                    }
                }
                where.append(")");
            }
            return this;
        }
        
        public JpqlBuilder notIn(String column, Collection<?> value) {
            if(!CollectionUtils.isEmpty(value)) {
                where.append(" and " + column + " not in (");
                boolean first = true;
                for(Object obj : value) {
                    args.add(obj);
                    if(first) {
                        first = false;
                        where.append("?"+args.size());
                    }else {
                        where.append(" , ?"+args.size());
                    }
                }
                where.append(")");
            }
            return this;
        }
        
        public JpqlBuilder gt(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " > ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder gte(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " >= ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder lt(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " < ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder lte(String column, Object value) {
            if(!StringUtils.isEmpty(value)) {
                args.add(value);
                where.append(" and " + column + " <= ?" + args.size());
            }
            return this;
        }
        
        public JpqlBuilder between(String column, Object from, Object to) {
            if(StringUtils.isEmpty(from) && StringUtils.isEmpty(to)) return this;
            if(!StringUtils.isEmpty(from)) {
                args.add(from);
                where.append(" and " + column + " >= ?" + args.size());
            }else if(!StringUtils.isEmpty(to)) {
                args.add(to);
                where.append(" and " + column + " <= ?" + args.size());
            }else {
                args.add(from);
                args.add(to);
                where.append(" and " + column + " between ?" + (args.size()-1) + " and ?" + args.size());
            }
            return this;
        }
        
        public String jpql() {
            if(select == null || from == null//必須得有selece和from部分
                throw new RuntimeException("sql must contain select + from parts.");
            
            StringBuilder sql = new StringBuilder("select " + select+" from "+from);
            if(where.length() > 4) sql.append(" where " + where.substring(5));
            if(groupBy != null) sql.append(" group by " + groupBy);
            if(having != null) sql.append(" having " + having);
            if(orderBy != null) sql.append(" order by " + orderBy);
            if(limit != null) sql.append(" limit " + limit);
            return sql.toString();
        }
        
        public Object[] args() {
            return args.toArray();
        }
    }  





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM