Hibernate学习---第一节:hibernate配置和入门程序

一、ORM 简介:

ORM 全称是 Object\ Relation Mapping, 即对象\关系映射

ORM 可以理解为一种规范,具体的 ORM 框架可作为应用程序和数据库的桥梁

面向对象程序设计语言与关系型数据库发展不同步时,需要一种中间解决方案,ORM 框架就是这样的解决方案

ORM 不是具体的产品,是一类框架的总称,基本特征:

(1)、完成面向对象的程序设计语言到关系数据库的映射

(2)、基于 ORM 框架完成映射后,即可利用面向对象程序设计语言的简单易用性,又可利用关系型数据库的技术优势

二、hibernate 简介:

1、hibernate 是当前最流行的的 ORM 框架之一, hibernate 采用低侵入式的设计,即采用完全的 Java对象 (POJO,VO) ,而不必继承 hibernate 的某个超类或实现 hibernate 的接口。

2、ORM 规范映射思想:

(1)、一张表映射成一个类

(2)、一行数据(记录)映射成一个对象

(3)、一列数据被映射成对象的属性

ORM 的作用: 负责把面向对象的持久化操作,转换为数据库的标准 SQL 语句执行

3、hibernate 的目录结构:

4、hibernate 工作流程:

5、所需 jar 包:

三、创建 java 工程:

1、持久化类,代码如下:

package learn.hibernate.bean;

import java.util.Date;

/**
 * 持久化类设计
 * 注意:
 *         持久化类通常建议要有一个持久化标识符(ID)
 *         持久化标识符通常建议使用封装类(例如:Integer  因为基本类型存在默认值)
 *         持久化类通常建议手动添加一个无参构造函数 (因为有些操作是通过放射机制进行的)
 *         属性通常建议提供  getter/setter 方法
 *         持久化类不能使用 final 修饰
 *         持久化类中如果使用了集合类型数据,只能使用集合所对应的接口类型来声明(List/Map/Set)
 *              如下:ArrayList list = new ArrayList();  不行
 *                 List list = new ArrayList(); 可行
 */
public class Person {

    private Integer id;
    private String name;
    private int age;
    private int passwork;
    private Date birthday;
    
    public Person() {
        
    }
    
    public Person(String name, int age, int passwork, Date birthday) {
        super();
        this.name = name;
        this.age = age;
        this.passwork = passwork;
        this.birthday = birthday;
    }
    
    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age
                + ", passwork=" + passwork + ", birthday=" + birthday + "]";
    }
    
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getPasswork() {
        return passwork;
    }
    public void setPasswork(int passwork) {
        this.passwork = passwork;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    
}

2、持久化类所对应的配置文件,代码如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 持久化映射文件(将java对象映射到数据库表) -->

<hibernate-mapping package="learn.hibernate.bean">
    
    <!-- 
     1、name (可选): 持久化类(或者接口)的Java全限定名。 如果这个属性不存在,Hibernate将假定这是一个非POJO的实体映射
     2、table (可选 - 默认是类的非全限定名): 对应的数据库表名,生成DDL时数据表名,如果省略,则名称同持久化类名称
     -->
    <class name="Person" table="t_person">
        <!-- 
        主键  name 属性值对应持久化类的属性名;  column(可选) 属性值表示在数据库生成的字段名
        generator元素中的  class 值表示生成策略
            1)  assigned:主键由外部程序负责生成,在 save() 之前指定。
            
            2)  hilo:通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。
            
            3)  seqhilo:与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence,适用于支持 Sequence 的数据库,如Oracle。
            
            4)  increment:主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。
            
            5)  identity:采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。
            
            6)  sequence:采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。
            
            7)  native:由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。
            
            8)  uuid.hex:由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
            
            9)  uuid.string:与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。
            
            10) foreign:使用另外一个相关联的对象的标识符作为主键。
         -->
        <id name="id" column="person_id">
            <generator class="native"/>
        </id>
        
        <!-- 
        name(可选):对应的java类的属性名称
        column(可选):对应的表中的字段
        type(可选):属性的类型,eg.java.lang.String
        not-null(可选):设置该属性是否为空,为true时表示非空,默认为false
        length(可选):字段的长度限制
         -->
        <property name="name" column="t_name"/>
        <property name="age"/>    
        <property name="passwork"/>
        <property name="birthday"/>
    </class>
    

</hibernate-mapping>

3、hibernate.cfg.xml 配置文件,代码如下:

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<!--声明Hibernate配置文件的开始-->
<hibernate-configuration>
    <!--表明以下的配置是针对session-factory配置的,SessionFactory是Hibernate中的一个类,这个类主要负责保存HIbernate的配置信息,以及对Session的操作-->
    <session-factory>
        <!--hibernate.dialect 只是Hibernate使用的数据库方言,就是要用Hibernate连接那种类型的数据库服务器--> 
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <!--配置数据库的驱动程序,Hibernate 在连接数据库时,需要用到数据库的驱动程序--> 
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!--设置数据库的连接url:jdbc:mysql://localhost/hibernate,其中localhost表示mysql服务器名称,此处为本机,    hibernate是数据库名--> 
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <!--连接数据库是用户名--> 
        <property name="hibernate.connection.username">root</property>
        <!--连接数据库是密码-->
        <property name="hibernate.connection.password">123456</property>
        <!-- 是否自动创建数据库表  他主要有一下几个值:  
  
          validate:当sessionFactory创建时,自动验证或者schema定义导入数据库。  
          
          create:每次启动都drop掉原来的schema,创建新的。  
          
          create-drop:当sessionFactory明确关闭时,drop掉schema。  
          
          update(常用):如果没有schema就创建,有就更新。  
          
        -->  
        <property name="hibernate.hbm2ddl.auto">update</property>
         <!--是否在后台显示Hibernate用到的SQL语句,开发时设置为true,便于差错,程序运行时可以在Eclipse的控制台显示Hibernate的执行Sql语句。项目部署后可以设置为false,提高运行效率--> 
        <property name="hibernate.show_sql">true</property>
        <!--指定映射文件 -->
        <mapping resource="learn\hibernate\bean\Person.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

4、测试类代码:

package learn.hibernate.test;

import java.util.Date;

import learn.hibernate.bean.Person;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class HibernateTest {

    public static void main(String[] args){
        
        /**
         * Configuration 是 hibernate 的入口,负责管理 Hibernate 的配置信息,
         * 这些配置信息都是从配置文件 hibernate.cfg.xml 或者 Hibernate.properties
         */
        /**
         *  使用configure()方法加载默认的hibernate.cfg.xml配置文件,
         *  因为配置文件中已经含有数据库映射信息,因此就不需要使用addClass方法加载各个类文件的映射文件
         */
        Configuration config = new Configuration().configure();
        
        /**
         *  Configuration 的实例会根据当前的配置信息,构造SessionFactory实例。
         *  SessionFactory 是线程安全的,一般情况下一个应用中数据库共享一个 SessionFactory 实例。
         *  Hibernate 的 SessionFactory 接口提供 Session 类的实例,Session 类用于完成对数据库的操作。
         *  由于 SessionFactory 实例是线程安全的(而 Session 实例不是线程安全的),
         *  所以每个操作都可以共用同一个 SessionFactory 来获取 Session。
         */
        SessionFactory sessionFactory = config.buildSessionFactory();
        
        Session session = sessionFactory.openSession();
        
        Transaction tx = session.beginTransaction();
        Person person = new Person("hwl",19, 123456, new Date());
        session.save(person);
        tx.commit();
        session.close();
        sessionFactory.close();
    }
}

5、在 MySQL 数据库中创建数据库,运行测试代码,会发现在数据库中会生成表和写入一条记录

详解一:Hibernate配置文件分为两种格式,一种是xml格式的配置文件,另一种是属性文件格式的配置文件,因此构建SessionFactory也有两种方法:

1  从XML文件读取配置信息构建SessionFactory从XML文件读取配置信息构建SessionFactory的具体步骤如下。

1) 创建一个Configuration对象,并通过该对象的configura()方法加载Hibernate配置文件,代码如下:

Configuration config = new Configuration().configure();

configure()方法:用于告诉Hibernate加载hibernate.cfg.xml文件。

Configuration在实例化时默认加载classpath中的hibernate.cfg.xml,

当然也可以加载名称不是hibernate.cfg.xml的配置文件,例如myhibernate.cfg.xml,可以通过以下代码实现。

Configuration config = new Configuration().configure("myhibernate.cfg.xml");

2) 完成配置文件和映射文件的加载后,将得到一个包括所有Hibernate运行期参数的Configuration实例,通过Configuration实例的buildSessionFactory()方法可以构建一个惟一的SessionFactory,代码如下:

SessionFactory sessionFactory = config.buildSessionFactory();

构建SessionFactory要放在静态代码块中,因为它只在该类被加载时执行一次。一个典型的构建SessionFactory的代码如下。

  public static SessionFactory sessionFactory;
  static{
     try{
       Configuration config = new Configuration();
       config.configure();
       sessionFactory = config.buildSessionFactory();
    }catch(RuntimeException e){e.printStackTrace();throw e;}
  }

2  从属性文件读取配置信息构建SessionFactory,从属性文件读取配置信息构建SessionFactory的具体步骤如下:

1) 创建一个Configuration对象,此时Hibernate会默认加载classpath中的配置文件hibernate.properties,代码如下:

Configuration config = new Configuration();

2) 由于在配置文件中缺少相应的配置映射文件的信息,所以此处需要通过编码方式加载,这可以通过Configuration对象的

addClass()方法或者addResource()来实现,具体代码如下:

config.addClass(MyBean.class);或者config.addClass(MyBean.hbm.xml);

注意:这里加载的路径取默认值

3) 完成配置文件和映射文件的加载后,将得到一个包括所有Hibernate运行期参数的Configuration实例,通过Configuration实例

的buildSessionFactory()方法可以构建一个惟一的SessionFactory,代码如下:

SessionFactory sessionFactory = config.buildSessionFactory();

 (来自:http://blog.csdn.net/ziliang871118/article/details/6181095)

 详解二:Session

public interface Session extends Serializable

Java应用程序与Hibernate之间的主要运行时接口。它是抽象了持久化服务概念的核心抽象API类。
Session的生命周期绑定在一个物理的事务(tansaction)上面。(长的事务可能跨越多个数据库事物。)
Session的主要功能是提供对映射的实体类实例的创建,读取和删除操作。实例可能以下面三种状态存在:
自由状态(transient): 不曾进行持久化,未与任何Session相关联
持久化状态(persistent): 仅与一个Session相关联
游离状态(detached): 已经进行过持久化,但当前未与任何Session相关联


游离状态的实例可以通过调用save()persist()或者saveOrUpdate()方法进行持久化。持久化实例可以通过调用 delete()变成游离状态。通过get()load()方法得到的实例都是持久化状态的。游离状态的实例可以通过调用 update()、0saveOrUpdate()lock()或者replicate()进行持久化。游离或者自由状态下的实例可以通过调用merge()方法成为一个新的持久化实例。
save()persist()将会引发SQL的INSERTdelete()会引发SQLDELETE,而update()merge()会引发SQLUPDATE。对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQLUPDATEsaveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE
其具体实现并不一定是线程安全的。每个线程/事务应该从一个SessionFactory获取自己的session实例。
如果其持久化对象类是可序列化的,则Session实例也是可序列化的。

一个典型的事务应该使用下面的形式:

Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }

如果Session抛出了异常, 事务必须回滚而session会被废弃。在异常发生后Session的内部状态可能会与数据库失去同步。

(来自:http://blog.csdn.net/shrek_xu/article/details/740991)

(注意:http://www.blogjava.net/redcoatjk/archive/2011/11/02/362491.html)

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。