1. 程式人生 > >Hibernate進階學習4

Hibernate進階學習4

Hibernate進階學習4

深入學習hibernate的查詢語句

 

測試HQL查詢

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import java.util.List; /** * @author: 肖德子裕 * @date: 2018/11/16 10:26 * @description: 測試HQL語句(hibernate獨有的面向物件的語法)(適合不復雜的多表查詢) */ public class Test1 { /** * 排序查詢 */ @Test public void test1(){ //建立Session物件 Session session = HibernateUtils.openSession();
//開啟事務並獲取事務物件 Transaction tx = session.beginTransaction(); /********************* 資料庫操作 **********************/ //1)書寫HQL語句 String hql="from Customer order by cust_id"; //2)建立查詢物件 Query query = session.createQuery(hql); //3)執行查詢 List<Customer> list = query.list(); System.out.println(list);
/*******************************************************/ tx.commit(); session.close(); } /** * 統計查詢 */ @Test public void test2(){ //建立Session物件 Session session = HibernateUtils.openSession(); //開啟事務並獲取事務物件 Transaction tx = session.beginTransaction(); /********************* 資料庫操作 **********************/ //1)書寫HQL語句 String hql="select count(*) from Customer"; String hql1="select sum(cust_id) from Customer"; String hql2="select avg(cust_id) from Customer"; String hql3="select max(cust_id) from Customer"; String hql4="select min(cust_id) from Customer"; //2)建立查詢物件 Query query = session.createQuery(hql2); //3)執行查詢 Number number = (Number) query.uniqueResult(); System.out.println(number); /*******************************************************/ tx.commit(); session.close(); } /** * 投影查詢 */ @Test public void test3(){ //建立Session物件 Session session = HibernateUtils.openSession(); //開啟事務並獲取事務物件 Transaction tx = session.beginTransaction(); /********************* 資料庫操作 **********************/ //1)書寫HQL語句 String hql="select new Customer(cust_id,cust_name) from Customer"; //2)建立查詢物件 Query query = session.createQuery(hql); //3)執行查詢 List<Customer> list = query.list(); System.out.println(list); /*******************************************************/ tx.commit(); session.close(); } }
HQL
package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

/**
 * @author: 肖德子裕
 * @date: 2018/11/19 14:35
 * @description: 測試HQL多表查詢(hibernate獨有的面向物件的語法)(適合不復雜的多表查詢)
 */
public class Test2 {
    /**
     * 內連線
     */
    @Test
    public void test1(){
        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        //1)書寫HQL語句
        String hql="from Customer c inner join c.linkMens";
        //2)建立查詢物件
        Query query = session.createQuery(hql);
        //3)執行查詢
        List<Object[]> list = query.list();

        for (Object[] obj:list){
            System.out.println(Arrays.toString(obj));
        }

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 迫切內連線
     * 將查詢到的關聯的物件也封裝到查詢的物件中
     */
    @Test
    public void test2(){
        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        //1)書寫HQL語句
        String hql="from Customer c inner join fetch c.linkMens";
        //2)建立查詢物件
        Query query = session.createQuery(hql);
        //3)執行查詢
        List<Customer> list = query.list();

        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 左(右)外連線
     */
    @Test
    public void test3(){
        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        //1)書寫HQL語句
        //String hql="from Customer c left join c.linkMens";
        String hql="from Customer c right join c.linkMens";
        //2)建立查詢物件
        Query query = session.createQuery(hql);
        //3)執行查詢
        List<Object[]> list = query.list();

        for (Object[] obj:list){
            System.out.println(Arrays.toString(obj));
        }

        /*******************************************************/

        tx.commit();
        session.close();
    }
}
HQL2

 

測試Criteria查詢

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.*;
import org.junit.Test;

import javax.print.attribute.standard.Destination;
import java.util.List;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:26
 * @description: 測試criteria語句(hibernate獨有的無語句的全面向物件的查詢語法)(適合單表查詢)
 */
public class Test3 {
    /**
     * 排序查詢
     */
    @Test
    public void test(){
        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        Criteria criteria = session.createCriteria(Customer.class);
        //criteria.addOrder(Order.asc("cust_id"));
        criteria.addOrder(Order.desc("cust_id"));
        List list = criteria.list();
        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }

    /**
     * 離線查詢
     * 就是在不建立session的情況下也能進行資料庫操作(比如在service和web層呼叫)
     */
    @Test
    public void test1(){
        //建立離線物件
        DetachedCriteria dc=DetachedCriteria.forClass(Customer.class);
        dc.add(Restrictions.idEq(3L));

        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        Criteria criteria = dc.getExecutableCriteria(session);
        List list = criteria.list();
        System.out.println(list);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}
criteria

 

測試類級別載入策略

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.domain" >
    <class name="Customer" table="cst_customer" lazy="false" >
        <id name="cust_id"  >
            <generator class="native"></generator>
        </id>
        <property name="cust_name" column="cust_name" ></property>
        <property name="cust_source" column="cust_source" ></property>
        <property name="cust_industry" column="cust_industry" ></property>
        <property name="cust_level" column="cust_level" ></property>
        <property name="cust_linkman" column="cust_linkman" ></property>
        <property name="cust_phone" column="cust_phone" ></property>
        <property name="cust_mobile" column="cust_mobile" ></property>
    
    <!-- 
        lazy屬性: 決定是否延遲載入
            true(預設值): 延遲載入,懶載入
            false: 立即載入
            extra: 極其懶惰
        fetch屬性: 決定載入策略.使用什麼型別的sql語句載入集合資料
            select(預設值): 單表查詢載入
            join: 使用多表查詢載入集合
            subselect:使用子查詢載入集合
     -->
     <!-- batch-size: 抓取集合的數量為3.
             抓取客戶的集合時,一次抓取幾個客戶的聯絡人集合.
      -->
        <set name="linkMens" batch-size="3"  >
            <key column="lkm_cust_id" ></key>
            <one-to-many class="LinkMan" />
        </set>
    </class>
</hibernate-mapping>
customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.domain" >
    <class name="LinkMan" table="cst_linkman" >
        <id name="lkm_id"  >
            <generator class="native"></generator>
        </id>
        <property name="lkm_gender"  ></property>
        <property name="lkm_name"  ></property>
        <property name="lkm_phone"  ></property>
        <property name="lkm_email"  ></property>
        <property name="lkm_qq"  ></property>
        <property name="lkm_mobile"  ></property>
        <property name="lkm_memo"  ></property>
        <property name="lkm_position"  ></property>
        <!-- 
        fetch 決定載入的sql語句
            select: 使用單表查詢
            join : 多表查詢
        lazy  決定載入時機
            false: 立即載入
            proxy: 由customer的類級別載入策略決定.
         -->
        <many-to-one name="customer" column="lkm_cust_id" class="Customer" fetch="join" lazy="proxy"  >
        </many-to-one>
    </class>
</hibernate-mapping>
linkman.hbm.xml
package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.*;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:26
 * @description: 類級別載入策略
 */
public class Test4 {
    /**
     * 懶載入|延遲載入
     */
    @Test
    public void test(){
        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        //立即載入
        //Customer customer = session.get(Customer.class, "2L");

        //延遲載入:查詢時只返回一個代理物件,在使用時,根據關聯的session查詢資料庫返回結果
        //為了更好的效能,建議延遲載入;延遲載入貌似只是推遲了查詢
        Customer customer = session.load(Customer.class, "2L");
        System.out.println(customer);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}
test

 

測試關聯級別載入策略

package com.hibernate.test;

import com.hibernate.domain.Customer;
import com.hibernate.domain.LinkMan;
import com.hibernate.utils.HibernateUtils;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import java.util.Set;

/**
 * @author: 肖德子裕
 * @date: 2018/11/16 10:26
 * @description: 關聯級別載入策略
 */
public class Test5 {
    /**
     * lazy與fetch的使用
     */
    @Test
    public void test(){
        //建立Session物件
        Session session = HibernateUtils.openSession();
        //開啟事務並獲取事務物件
        Transaction tx = session.beginTransaction();

        /********************* 資料庫操作 **********************/

        //立即載入
        Customer customer = session.get(Customer.class, "2L");

        Set<LinkMan> linkMens = customer.getLinkMens();
        System.out.println(linkMens.size());
        System.out.println(linkMens);

        /*******************************************************/

        tx.commit();
        session.close();
    }
}
test