1. 程式人生 > >【JAVAEE學習筆記】hibernate04:查詢種類、HQL、Criteria、查詢優化和練習為客戶列表增加查詢條件

【JAVAEE學習筆記】hibernate04:查詢種類、HQL、Criteria、查詢優化和練習為客戶列表增加查詢條件

沒有 arrays getpara tex response 寫法 sum exceptio 提高

一、查詢種類

1.oid查詢-get

2.對象屬性導航查詢

3.HQL

4.Criteria

5.原生SQL

二、查詢-HQL語法

技術分享
//學習HQL語法
public class Demo {
    
    //基本語法
    @Test
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
String hql = " from cn.itcast.domain.Customer ";//完整寫法 String hql2 = " from Customer "; //簡單寫法 String hql3 = " from java.lang.Object "; Query query = session.createQuery(hql3); List list = query.list(); System.out.println(list);
//---------------------------------------------------- tx.commit(); session.close(); } @Test //排序 public void fun2(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //----------------------------------------------------
String hql1 = " from cn.itcast.domain.Customer order by cust_id asc ";//完整寫法 String hql2 = " from cn.itcast.domain.Customer order by cust_id desc ";//完整寫法 Query query = session.createQuery(hql2); List list = query.list(); System.out.println(list); //---------------------------------------------------- tx.commit(); session.close(); } @Test //條件查詢 public void fun3(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------------------- String hql1 = " from cn.itcast.domain.Customer where cust_id =? ";//完整寫法 String hql2 = " from cn.itcast.domain.Customer where cust_id = :id ";//完整寫法 Query query = session.createQuery(hql2); // query.setParameter(0, 2l); query.setParameter("id", 2l); List list = query.list(); System.out.println(list); //---------------------------------------------------- tx.commit(); session.close(); } @Test //分頁查詢 public void fun4(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------------------- String hql1 = " from cn.itcast.domain.Customer ";//完整寫法 Query query = session.createQuery(hql1); //limit ?,? // (當前頁數-1)*每頁條數 query.setFirstResult(2); query.setMaxResults(2); List list = query.list(); System.out.println(list); //---------------------------------------------------- tx.commit(); session.close(); } @Test //統計查詢 //count 計數 //sum 求和 //avg 平均數 //max //min public void fun5(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------------------- String hql1 = " select count(*) from cn.itcast.domain.Customer ";//完整寫法 String hql2 = " select sum(cust_id) from cn.itcast.domain.Customer ";//完整寫法 String hql3 = " select avg(cust_id) from cn.itcast.domain.Customer ";//完整寫法 String hql4 = " select max(cust_id) from cn.itcast.domain.Customer ";//完整寫法 String hql5 = " select min(cust_id) from cn.itcast.domain.Customer ";//完整寫法 Query query = session.createQuery(hql5); Number number = (Number) query.uniqueResult(); System.out.println(number); //---------------------------------------------------- tx.commit(); session.close(); } @Test //投影查詢 public void fun6(){ Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); //---------------------------------------------------- String hql1 = " select cust_name from cn.itcast.domain.Customer "; String hql2 = " select cust_name,cust_id from cn.itcast.domain.Customer "; String hql3 = " select new Customer(cust_id,cust_name) from cn.itcast.domain.Customer "; Query query = session.createQuery(hql3); List list = query.list(); System.out.println(list); //---------------------------------------------------- tx.commit(); session.close(); } }
學習HQL語法

技術分享

技術分享
public class Demo2 {
    //回顧-原生SQL
    // 交叉連接-笛卡爾積(避免)
//        select * from A,B 
    // 內連接
//        |-隱式內連接
//            select * from A,B  where b.aid = a.id
//        |-顯式內連接
//            select * from A inner join B on b.aid = a.id
    // 外連接
//        |- 左外
//            select * from A left [outer] join B on b.aid = a.id
//        |- 右外
//            select * from A right [outer] join B on b.aid = a.id
//---------------------------------------------------------------------
//HQL的多表查詢
        //內連接(迫切)
        //外連接
//            |-左外(迫切)
//            |-右外(迫切)
    
    @Test
    //HQL 內連接 => 將連接的兩端對象分別返回.放到數組中.
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        String hql = " from Customer c inner join c.linkMens ";
        
        Query query = session.createQuery(hql);
        
        List<Object[]> list = query.list();
        
        for(Object[] arr : list){
            System.out.println(Arrays.toString(arr));
        }
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    //HQL 迫切內連接 => 幫我們進行封裝.返回值就是一個對象
    public void fun2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        String hql = " from Customer c inner join fetch c.linkMens ";
        
        Query query = session.createQuery(hql);
        
        List<Customer> list = query.list();
        
        System.out.println(list);
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    //HQL 左外連接 => 將連接的兩端對象分別返回.放到數組中.
    public void fun3(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        String hql = " from Customer c left join c.linkMens ";
        
        Query query = session.createQuery(hql);
        
        List<Object[]> list = query.list();
        
        for(Object[] arr : list){
            System.out.println(Arrays.toString(arr));
        }
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    @Test
    //HQL 右外連接 => 將連接的兩端對象分別返回.放到數組中.
    public void fun4(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        String hql = " from Customer c right join c.linkMens ";
        
        Query query = session.createQuery(hql);
        
        List<Object[]> list = query.list();
        
        for(Object[] arr : list){
            System.out.println(Arrays.toString(arr));
        }
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
}
學習HQL語法(不常用) - 多表查詢語法

三、查詢-Criteria語法

技術分享
public class Demo {
    
    @Test
    //基本語法
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Criteria c = session.createCriteria(Customer.class);
        
        List<Customer> list = c.list();
        
        System.out.println(list);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    //條件語法
    public void fun2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Criteria c = session.createCriteria(Customer.class);
        
//        c.add(Restrictions.idEq(2l));
        c.add(Restrictions.eq("cust_id",2l));
        
        List<Customer> list = c.list();
        
        System.out.println(list);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    //分頁語法 - 與HQL一樣
    public void fun3(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Criteria c = session.createCriteria(Customer.class);
        //limit ?,? 
        c.setFirstResult(0);
        c.setMaxResults(2);
        
        List<Customer> list = c.list();
        
        System.out.println(list);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    //排序語法 
    public void fun4(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Criteria c = session.createCriteria(Customer.class);
        
        c.addOrder(Order.asc("cust_id"));
        //c.addOrder(Order.desc("cust_id"));
        
        List<Customer> list = c.list();
        
        System.out.println(list);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    //統計語法 
    public void fun5(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Criteria c = session.createCriteria(Customer.class);
        
        //設置查詢目標
        c.setProjection(Projections.rowCount());
        
        List list = c.list();
        
        System.out.println(list);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    
}
學習Criteria語法

  非離線

  技術分享

  離線

  技術分享

技術分享
public class Demo2 {
    
    @Test
    public void fun1(){
        //Service/web層
        DetachedCriteria dc  = DetachedCriteria.forClass(Customer.class);
        
        dc.add(Restrictions.idEq(6l));//拼裝條件(全部與普通Criteria一致)
        
        //----------------------------------------------------
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        Criteria c = dc.getExecutableCriteria(session);
        
        List list = c.list();
        
        System.out.println(list);
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
}
學習離線Criteria

四、查詢優化

  類級別查詢

    get方法:沒有任何策略.調用即立即查詢數據庫加載數據.

    load方法: 應用類級別的加載策略

技術分享
public class Demo {
    
    @Test
    // get方法 : 立即加載.執行方法時立即發送sql語句查詢結果
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Customer c = session.get(Customer.class, 2l);
        
        System.out.println(c);
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    @Test
    // load方法(默認):是在執行時,不發送任何sql語句.返回一個對象.使用該對象時,才執行查詢.
    // 延遲加載: 僅僅獲得沒有使用.不會查詢.在使用時才進行查詢.
    // 是否對類進行延遲加載: 可以通過在class元素上配置lazy屬性來控制.
        //lazy:true  加載時,不查詢.使用時才查詢b
        //lazy:false 加載時立即查詢.
    public void fun2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Customer c = session.load(Customer.class, 2l);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        System.out.println(c);
        
    }
    
}
懶加載|延遲加載

技術分享
public class Demo {
    
    //集合級別的關聯
    //fetch:select 單表查詢
    //lazy:true 使用時才加載集合數據.
    @Test
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        Customer c = session.get(Customer.class, 2l);
        
        Set<LinkMan> linkMens = c.getLinkMens();//關聯級別
        
        System.out.println(linkMens);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    //集合級別的關聯
        //fetch:select 單表查詢
        //lazy:false 立即記載集合數據
        @Test
        public void fun2(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            //----------------------------------------------------
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens();//關聯級別
            
            System.out.println(linkMens);
            
            //----------------------------------------------------
            tx.commit();
            session.close();
            
        }
        //集合級別的關聯
        //fetch:select 單表查詢
        //lazy:extra 極其懶惰.與懶加載效果基本一致. 如果只獲得集合的size.只查詢集合的size(count語句)
        @Test
        public void fun3(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            //----------------------------------------------------
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens();//關聯級別
            
            System.out.println(linkMens.size());
            
            System.out.println(linkMens);
            
            //----------------------------------------------------
            tx.commit();
            session.close();
            
        }
        //集合級別的關聯
        //fetch:join    多表查詢
        //lazy:true|false|extra 失效.立即加載.
        @Test
        public void fun4(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            //----------------------------------------------------
            
            Customer c = session.get(Customer.class, 2l);
            
            Set<LinkMan> linkMens = c.getLinkMens();//關聯級別
            
            System.out.println(linkMens.size());
            
            System.out.println(linkMens);
            
            //----------------------------------------------------
            tx.commit();
            session.close();
            
        }
        
        @Test
        //fetch: subselect 子查詢
        //lazy: true 懶加載
        public void fun5(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            //----------------------------------------------------
                
            String  hql = "from Customer";
            
            Query query = session.createQuery(hql);
            
            List<Customer> list = query.list();
            
            for(Customer c:list){
                System.out.println(c);
                System.out.println(c.getLinkMens().size());
                System.out.println(c.getLinkMens());
            }
            
            //----------------------------------------------------
            tx.commit();
            session.close();
            
        }
        @Test
        //fetch: subselect 子查詢
        //lazy: false 立即加載
        public void fun6(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            //----------------------------------------------------
                
            String  hql = "from Customer";
            
            Query query = session.createQuery(hql);
            
            List<Customer> list = query.list();
            
            for(Customer c:list){
                System.out.println(c);
                System.out.println(c.getLinkMens().size());
                System.out.println(c.getLinkMens());
            }
            
            //----------------------------------------------------
            tx.commit();
            session.close();
            
        }
        @Test
        //fetch: subselect 子查詢
        //lazy: extra 極其懶惰
        public void fun7(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
            //----------------------------------------------------
                
            String  hql = "from Customer";
            
            Query query = session.createQuery(hql);
            
            List<Customer> list = query.list();
            
            for(Customer c:list){
                System.out.println(c);
                System.out.println(c.getLinkMens().size());
                System.out.println(c.getLinkMens());
            }
            
            //----------------------------------------------------
            tx.commit();
            session.close();
            
        }
    
}
關聯級別 延遲加載 & 抓取策略(客戶再獲取多個聯系人)

技術分享
public class Demo2 {
    
    @Test
    //fetch:select    單表查詢
    //lazy:proxy  
        //customer-true 懶加載
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        LinkMan lm = session.get(LinkMan.class, 3l);
        
        Customer customer = lm.getCustomer();
        
        System.out.println(customer);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    @Test
    //fetch:join    多表
    //lazy: 失效  
    public void fun3(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        LinkMan lm = session.get(LinkMan.class, 3l);
        
        Customer customer = lm.getCustomer();
        
        System.out.println(customer);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    @Test
    //fetch:select    單表查詢
    //lazy:proxy  
        //customer-false 立即加載
    public void fun2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        LinkMan lm = session.get(LinkMan.class, 3l);
        
        Customer customer = lm.getCustomer();
        
        System.out.println(customer);
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
}
關聯級別 延遲加載 & 抓取策略(通過聯系人獲得客戶)

  結論:為了提高效率.fetch的選擇上應選擇select. lazy的取值應選擇 true. 全部使用默認值.

  no-session問題解決: 擴大session的作用範圍.

  技術分享

技術分享
public class Demo {
    
    @Test
    public void fun1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        //----------------------------------------------------
        
        String hql = "from Customer ";
        Query query = session.createQuery(hql);
        List<Customer> list = query.list();
        
        for(Customer c:list){
            System.out.println(c.getLinkMens());
        }
        
        //----------------------------------------------------
        tx.commit();
        session.close();
        
    }
    
    
}
抓取數量

技術分享

五、練習:為客戶列表增加查詢條件

在上一次筆記的代碼基礎上,在顯示客戶列表之前,加入篩選的條件:

技術分享
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1獲得查詢條件
        String cust_name = request.getParameter("cust_name");
        //2判斷查詢條件是否不為空
        DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
        
        if(cust_name!=null && !"".equals(cust_name)){
            dc.add(Restrictions.like("cust_name", "%"+cust_name+"%"));
        }
            //不為空=>添加條件
        //3 調用Service查詢所有客戶
        List<Customer> list = cs.getAll(dc);
        //4 將客戶列表放入request域
        request.setAttribute("list", list);
        //5 轉發到list.jsp顯示
        request.getRequestDispatcher("/jsp/customer/list.jsp").forward(request, response);
    
    }
Servlet層代碼 技術分享
    public List<Customer> getAll(DetachedCriteria dc) {
        Session session =  HibernateUtils.getCurrentSession();
        //打開事務
        Transaction tx = session.beginTransaction();
        
        List<Customer> list = customerDao.getAll(dc);
        
        //關閉事務
        tx.commit();
        return list;
    }
Service層代碼 技術分享
    public List<Customer> getAll(DetachedCriteria dc) {
        //1 獲得session
                Session session = HibernateUtils.getCurrentSession();
        //2 將離線對象關聯到session
                Criteria c = dc.getExecutableCriteria(session);
        //3 執行查詢並返回
        return c.list();
    }
Dao層代碼

【JAVAEE學習筆記】hibernate04:查詢種類、HQL、Criteria、查詢優化和練習為客戶列表增加查詢條件