Hibernate

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate相关的知识,希望对你有一定的参考价值。

1.1Hibernate的检索方式

1.1.1Hibernate的检索方式概述

Hibernate提供了以下几种检索对象的方式:

  • 导航对象图检索方式:根据已经家就在的对象导航到其他对象。
    • Customer customer = session.get(Customer.class,1);customer.getOrders();获取客户的订单。  
  • OID检索方式:按照对象的OID来检索对象。
    • get()/load()方法来进行检索。  
  • HQL检索方式:使用面向对象的HQL查询语言。
  • QBC检索方式:使用QBC API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口。
  • 本地SQL检索方式:使用本地数据库的SQL查询语句。

 

1.1.2HQL

  • HQL(HIbernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似,在HIbernate提供的各种检索方式中,HQL是使用最广的一种检索方式。它有如下功能:
    • 在查询语句中设定各种查询条件。
    • 支持投影查询,即仅查询出对象的部分属性。
    • 支持分页查询。
    • 支持连接查询。
    • 支持分组查询,允许使用having和group by关键字。
    • 提供内置聚集函数(分组函数),如sum(),min()和max()等。
    • 能够调用用户定义的SQL函数或标准的SQL函数。
    • 支持子查询。
    • 支持动态绑定参数。
  • HQL检索方式包括以下的步骤:
    • 通过session的createQuery()方法创建一个Query对象,它包括一个HQL查询语句。HQL查询语句中可以包含命名参数。
    • 动态绑定参数。
    • 调用Query的ist()方法执行查询语句,该方法返回java.util.List类型的查询结果,在List集合中存放了符合查询条件的持久化对象。
  • Query接口支持方法链编程风格,它的setXXX()方法返回自身实例,而不是void类型。
  • HQL vs SQL:
    • HQL查询语句是面向对象的,HIbernate负责解析HQL查询语句,然后根据对象-关系映射文件中的映射信息,把HQL查询语句翻译成相应的SQL语句,HQL查询语句中的主体是域模型中的类或类的属性
    • SQL查询语句是与关系数据库绑定在一起的。SQL查询语句中的主体是数据库表及表的字段

 

1.1.3搭建环境、具体的实体类和映射文件以及核心配置文件

  • 实体类
    • Customer.java类
package cn.hibernate3.demo4;

import java.io.Serializable;
import java.util.HashSet;
/**
 * 客户实体
 */
import java.util.Set;
public class Customer implements Serializable{
    private Integer cid;
    private String cname;
    //一个客户有多个订单
    private Set<Order> orders = new HashSet<Order>();
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Set<Order> getOrders() {
        return orders;
    }
    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }
    
    
}
    • Order.java类
package cn.hibernate3.demo4;

import java.io.Serializable;
/**
 * 订单实体
 */
public class Order implements Serializable{
    private Integer oid;
    private String addr;
    //订单属于某一个客户
    private Customer customer ;
    
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
    public String getAddr() {
        return addr;
    }
    public void setAddr(String addr) {
        this.addr = addr;
    }
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    
    
}
  • 映射文件
    • 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="cn.hibernate3.demo4.Customer" table="customer">
        <!-- 配置唯一标识 -->
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <!-- 配置普通属性 -->
        <property name="cname" column="cname" type="java.lang.String"/>
        <!-- 建立映射 -->
        <!-- 配置集合 -->
        <!-- 
            set标签中的name表示关联对象的属性名称
                
         -->
        <set name="orders">
            <!-- key标签中的column用来一对多的多的一方的外键 -->
            <key column="cno"/>
            <!-- 配置一个one-to-many -->
            <one-to-many class="cn.hibernate3.demo4.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="cn.hibernate3.demo4.Order" table="orders">
        <!-- 配置唯一标识 -->
        <id name="oid" column="oid">
            <generator class="native"/>
        </id>
        <!-- 配置普通属性 -->
        <property name="addr" column="addr" type="java.lang.String"/>
        <!-- 建立映射 -->
        <!-- 
            many-to-one标签
                属性:
                    name:关联对象的属性名称。
                    column:表中外键的名称。
                    class:关联对象的全路径。
         -->
        <many-to-one name="customer" column="cno" class="cn.hibernate3.demo4.Customer"></many-to-one>
    </class>
</hibernate-mapping>
  • 核心配置文件hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <!-- 配置数据库的基本信息 -->
    <!-- 驱动的名称 -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <!-- 访问数据库的url -->
    <property name="hibernate.connection.url">
        jdbc:mysql:///hibernate_day03
    </property>
    <!-- 用户名 -->
    <property name="hibernate.connection.username">root</property>
    <!-- 密码 -->
    <property name="hibernate.connection.password">root</property>
    <!-- 方言 -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <!-- C3P0连接池设定-->
    <!-- 使用c3po连接池  配置连接池提供的供应商-->
    <property name="connection.provider_class">
        org.hibernate.connection.C3P0ConnectionProvider
    </property>
    <!--在连接池中可用的数据库连接的最少数目 -->
    <property name="c3p0.min_size">5</property>
    <!--在连接池中所有数据库连接的最大数目  -->
    <property name="c3p0.max_size">20</property>
    <!--设定数据库连接的过期时间,以秒为单位,
        如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
    <property name="c3p0.timeout">120</property>
    <!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
    <property name="c3p0.idle_test_period">3000</property>
    <!-- 可选配置 -->
    <!-- 显示SQL -->
    <property name="hibernate.show_sql">true</property>
    <!-- 格式化SQL -->
    <property name="hibernate.format_sql">true</property>
    <!-- hbm:映射 2:to ddl:create drop alter -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <mapping resource="cn/hibernate3/demo4/Customer.hbm.xml" />
    <mapping resource="cn/hibernate3/demo4/Order.hbm.xml" />

</session-factory>
</hibernate-configuration>
  • 工具类HibernateUtils.java
package cn.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate抽取工具类
 */
public class HibernateUtils {
    private static Configuration configuration;
    private static SessionFactory sessionFactory;
    static{
        configuration = new Configuration().configure();
        sessionFactory = configuration.buildSessionFactory();
    }
    
    
    public static Session openSession(){
        return sessionFactory.openSession();
    }
    
    public static void main(String[] args) {
        openSession();
    }
}
  • 初始化数据
  @Test
    //初始化数据
    public void demo1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Customer customer = new Customer();
        customer.setCname("小金");
        
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setAddr("江苏"+i);
            order.setCustomer(customer);
            customer.getOrders().add(order);
        }
        
        session.save(customer);
        
        tx.commit();
        session.close();
    }
  @Test
    //初始化数据
    public void demo1(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Customer customer = new Customer();
        customer.setCname("小名");
        
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setAddr("北京"+i);
            order.setCustomer(customer);
            customer.getOrders().add(order);
        }
        
        session.save(customer);
        
        tx.commit();
        session.close();
    }
    • 需要配置级联关系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="cn.hibernate3.demo4.Customer" table="customer">
        <!-- 配置唯一标识 -->
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <!-- 配置普通属性 -->
        <property name="cname" column="cname" type="java.lang.String"/>
        <!-- 建立映射 -->
        <!-- 配置集合 -->
        <!-- 
            set标签中的name表示关联对象的属性名称
                
         -->
        <set name="orders" cascade="save-update">
            <!-- key标签中的column用来一对多的多的一方的外键 -->
            <key column="cno"/>
            <!-- 配置一个one-to-many -->
            <one-to-many class="cn.hibernate3.demo4.Order" />
        </set>
    </class>
</hibernate-mapping>

技术分享

技术分享

 

1.1.4简单查询及别名查询

  • HQL:简单查询
  @Test
    //查询所有数据
    public void demo2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Query query = session.createQuery("from Customer");
        List<Customer> list = query.list();
        for (Customer customer : list) {
            System.out.println(customer.getCname());
        }
        
         
        tx.commit();
        session.close();
    }
  • QBC:简单查询
    @Test
    //查询所有数据
    public void demo2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Criteria criteria = session.createCriteria(Customer.class);
        List<Customer> list = criteria.list();
        for (Customer customer : list) {
            System.out.println(customer.getCname());
        }
        
         
        tx.commit();
        session.close();
    }
  • SQL:简单查询
  @Test
    //查询所有数据
    public void demo2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        SQLQuery query = session.createSQLQuery("select * from customer");
        List<Customer> list = query.addEntity(Customer.class).list();
        for (Customer customer : list) {
            System.out.println(customer.getCname());
        }
        
         
        tx.commit();
        session.close();
    }
  @Test
    //查询所有数据
    public void demo2(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        SQLQuery query = session.createSQLQuery("select * from customer");
        List<Object[]> list = query.list();
        for (Object[] obj : list) {
            System.out.println(Arrays.toString(obj));
        }
        
         
        tx.commit();
        session.close();
    }
  • HQL:使用别名

 

 

 

  

  

  

  

 

    

 

以上是关于Hibernate的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate的HQL多表查询

使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)

Hibernate CriteriaQuery where - ManyToOne 字段

Hibernate + MySQL:如何为数据库和表设置编码 utf-8

hibernate在使用getCurrentSession时提示no session found for current thread

Java类型相互转换byte[]类型,blob类型