Hibernate5.2之HQL查詢


                                                   Hibernate5.2之HQL查詢                                                                 

一. 介紹

   Hibernate的檢索方式分為4種:HQL查詢、原生SQL查詢、OID查詢、QBC查詢。本博客將會出系列教程分別來介紹這四種查詢方式,那么第一篇文章說什么了,筆者認為當然是HQL的查詢。那么是什么是HQL的查詢了,HQL的全稱是Hibernate Query Language, 是面向對象的查詢語言,他和SQL語言有些類似,在Hibernate所提供的各種檢索方式中,HQL是使用上最廣泛的。按照筆者一貫的風格,直接上代碼,本文所用的數據庫為Mysql數據庫。

二. 數據庫的創建

   創建orders和customer兩張表(即訂單、客戶表,一個客戶可以有多個訂單),customer和orders是一對多的關系,建表語句如下: 

create table customer(
    id int(11) primary key auto_increment,
    name varchar(20),
    phone_number varchar(20)  
);

create table orders(
  id int(11) primary key auto_increment,
  order_id varchar(20),
  create_time datetime,
  customer_id int(11)
);

       數據庫中已有數據以下兩張圖所示:

                                  customer表                                                                                                                            

                                                   

                                   orders表

        

三. POJO類的創建

public class Customer {
    private int id;
    private String name;
    private String phoneNum;
    private Set<Order> orderSet;
    //setter and getter
}


public class Order {
    private int id;
    private String orderId;
    private Date createTime;
    private Customer customer;
    
    public Order() {}
    
    public Order(int id, String orderId, Date createTime) {
        this.id = id;
        this.orderId = orderId;
        this.createTime = createTime;
    }
    //setter and getter
}

四. hbm文件配置

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>
    <class name="com.demo.hibernate.one2many.Customer" table="customer">
        <id name="id" type="int">
            <generator class="increment"></generator>
        </id>
        <property name="name" type="string" column="name"></property>
        <property name="phoneNum" type="string" column="phone_number"></property>
        <!-- inverse=true表示由對方去維護關聯關系 -->
        <set name="orderSet" inverse="true">
            <key column="customer_id"></key>
            <one-to-many class="com.demo.hibernate.one2many.Order"/>
        </set>
    </class>
</hibernate-mapping>

Order.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>
    <class name="com.demo.hibernate.one2many.Order" table="orders">
        <id name="id" type="int">
            <generator class="increment"></generator>
        </id>
        <property name="orderId" column="order_id" type="string"></property>
        <property name="createTime" column="create_time" type="timestamp"></property>
        <many-to-one name="customer" class="com.demo.hibernate.one2many.Customer" column="customer_id"></many-to-one>
    </class>
</hibernate-mapping>

五. 編寫單元測試

  在編寫單元測試之讀者需要在hibernate.cfg.xml文件中加入以上兩個hbm文件,在此筆者沒有給出相應的配置,讀者可查詢相關資料自行完成配置。如果有問題,請給筆者留言。

5.1 創建工具類

public class SessionUtils {
    //獲取SessionFactory
    public static SessionFactory getSessionFactory(){
        StandardServiceRegistry registry = null;
        SessionFactory sessionFactory = null;
        try{
            registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
            //不指定文件名默認是找hibernate.cfg.xml文件
            //registry = new StandardServiceRegistryBuilder().configure().build(); 
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        }catch(Exception ex){
            ex.printStackTrace();
            StandardServiceRegistryBuilder.destroy(registry);
        }
        return sessionFactory;
    }
     
    //打開並返回一個Session 
    public static Session openSession(){
        return getSessionFactory().openSession();
    }
    
    //關閉Session
    public static void closeSession(Session session){
        if(null != session){
            session.close();
        }
    }
}

5.2 編寫測試用例

       有關於HQL的查詢都會在以下的單元測試類中完成:

public class HibernateTest {
    private Session session;
    
    @Before
    public void openSession(){
        session = SessionUtils.openSession(); //打開會話
    }
    
    @After
    public void closeSession(){
        SessionUtils.closeSession(session);
    }
}

       A.獲取所有的Order對象,得到一個List集合

@Test
public void list(){
    String hql = "from Order";
    Query<Order> query = session.createQuery(hql, Order.class);
    List<Order> list = query.getResultList();
    for(Order o : list){
        System.out.println(o.getOrderId() + "::" + o.getCreateTime());
    }
}

     B.獲取Order的分頁數據,得到一個List集合

@Test
public void pageList(){
    String hql = "from Order";
    Query<Order> query = session.createQuery(hql, Order.class);
    /**
     * setFirstResult() 是設置從第幾條開始
     * setMaxResults() 是設置每頁多少條數據
     */
    query.setFirstResult(0).setMaxResults(4); 
    List<Order> list = query.getResultList();
    for(Order o : list){
        System.out.println(o.getOrderId() + "::" + o.getCreateTime());
    }
}

    C.多條件查詢,返回List集合(第一種形式:索引占位符)

@Test
public void multiCretiera(){
    String hql = "from Order where orderId like ? and createTime between ? and ?";
    Query<Order> query = session.createQuery(hql, Order.class);
    String beginDateStr = "2016-07-26 00:00:00";
    String endDateStr = "2016-07-26 23:59:59";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date beginDate = null;
    Date endDate = null;
    try {
        beginDate = sdf.parse(beginDateStr);
        endDate = sdf.parse(endDateStr);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    query.setParameter(0, "%D%").setParameter(1, beginDate).setParameter(2, endDate);
    List<Order> list = query.getResultList();
    for(Order o : list){
        System.out.println(o.getOrderId() + "::" + o.getCreateTime());
    }
}

     E.多條件查詢,返回List集合(第二種形式:命名占位符)

@Test
public void multiCretiera1(){
    String hql = "from Order where orderId like :orderId and createTime between :beginDate and :endDate";
    Query<Order> query = session.createQuery(hql, Order.class);
    String beginDateStr = "2016-07-26 00:00:00";
    String endDateStr = "2016-07-26 23:59:59";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Date beginDate = null;
    Date endDate = null;
    try {
        beginDate = sdf.parse(beginDateStr);
        endDate = sdf.parse(endDateStr);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    query.setParameter("orderId", "%D%").setParameter("beginDate", beginDate).setParameter("endDate", endDate);
    List<Order> list = query.getResultList();
    for(Order o : list){
         System.out.println(o.getId() + "::" + o.getOrderId());
    }
}

    F.大於條件的查詢,使用索引占位符

@Test
public void gt(){
    String hql = "from Order where id > ?";
    Query<Order> query = session.createQuery(hql, Order.class).setParameter(0, 3);
    List<Order> list = query.getResultList();
    for(Order o : list){
        System.out.println(o.getId() + "::" + o.getOrderId());
    }
}

    G.更新操作

@Test
public void update(){
    String hql = "update Order set createTime = ? where id = ?";
    Transaction tx = session.beginTransaction();
    Query<?> query = session.createQuery(hql).setParameter(0, new Date()).setParameter(1, 1);
    int i = query.executeUpdate();
    System.out.println(i);
    tx.commit();
    session.close();
}

     H.刪除操作

@Test
public void delete(){
    //in 后面的括號可加可不加
    String hql = "delete from Order where id in (:idList)"; 
    Transaction tx = session.beginTransaction();
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    Query<?> query = session.createQuery(hql).setParameter("idList", list);
    int i = query.executeUpdate();
    System.out.println(i);
    tx.commit();
    session.close();
}

    I.獲取某一列的值

@Test
public void singleValue(){
    String hql = "select orderId from Order";
    Query<String> query = session.createQuery(hql, String.class);
    List<String> list = query.getResultList();
    for(String o : list){
        System.out.println(o);
    }
}

    J.使用對象的方式封裝結果數據

@Test
public void getOrdersList(){
    String hql = "select new com.demo.hibernate.one2many.Order(o.id, o.orderId, o.createTime) from Order as o";
    Query<Order> query = session.createQuery(hql, Order.class);
    List<Order> list = query.getResultList();
    for(Order o : list){
        System.out.println(o.getId() + ";;" + o.getOrderId() + ";;");
     }
}

     K.獲取關聯對象的結果集

@Test
public void getCustomer(){
    String hql = "select o.customer from Order o where o.customer.id = 6";
    Query<Customer> query = session.createQuery(hql, Customer.class);
    List<Customer> list = query.getResultList();
    for(Customer o : list){
        System.out.println(o.getId() + ";;");
    }
}

     L.多列數據的查詢

@Test
public void getObjectArray(){
    //String hql = "select o.orderId, o.createTime from Order o";
    //String hql = "select o.customer.name, o.customer.phoneNum, o.orderId, o.createTime from Order o";
    //String hql = "select o.orderId, o.createTime from Order o join o.customer c";
    String hql = "select c.name, c.phoneNum, o.orderId, o.createTime from Order o join o.customer c";
    Query<Object[]> query = session.createQuery(hql, Object[].class);
    List<Object[]> list = query.getResultList();
    for(Object[] o : list){
        System.out.println(o[0] + ";;" + o[1] + ";;");
    }
}

     M.函數查詢

@Test
public void functionQuery(){
    String hql = "select max(id), count(*) from Order";
    Query<Object[]> query = session.createQuery(hql, Object[].class);
    Object[] obj = query.getSingleResult();
    System.out.println(obj[0] + "::" + obj[1] + "::");
}

     N.排序

@Test
public void descQuery(){
    String hql = "from Order order by id desc";
    Query<Order> query = session.createQuery(hql, Order.class);
    List<Order> list = query.getResultList();
    for(Order o : list){
        System.out.println(o.getId() + "::" + o.getOrderId());
    }
}

     O.右連接

@Test
public void rightJoin(){
    String hql = "select o.customer from Order o right join o.customer";
    Query<Customer> query = session.createQuery(hql, Customer.class);
    List<Customer> list = query.getResultList();
    for(Customer c : list){
        System.out.println(c.getId());
    }
}

 

下一篇:Hibernate5.2之原生SQL查詢


免責聲明!

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



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