Hibernate(以前写的给公司的培训资料)

Hibernate(以前写的给公司的培训资料)

Hibernate 培训资料

                                 

1.        Hibernate简介

Hibernate是非常流行的对象-关系映射工具。

2.        什么是ORM映射

         未命名1.bmp

ORMObject Relational Mapping)简单的说,就是对象与关系的映射,对于实际应用来讲,对象一般指面向对象中的对象,关系指关系型数据库,对于我们具体的项目来说,就是将java中的对象与关系型数据库(oraclemysql)中的表联系起来 Hibernate是很强大的工具,当我们将建立联系的工作交给它后,就可以专注于与java中的对象打交道,而不需要知道它代表的是哪些表。

3.         POJO(用来映射数据库中的表,构建我们的持久化层)

一个典型的POJO

public class Person{

       private long id;

       private String name;

       public void setId(BigDecimal value) {

              this.id = value;

       }

       public BigDecimal getId() {

              return this.id;

       }

       public void setName(String value) {

              this.name = value;

       }

       public String getName() {

              return this.name;

       }

}

表面上看来,一个POJO与一个普通的JavaBean没有什么区别,我们需要了解的是如何让POJO和一个表建立联系。

4.        建立联系的桥梁,映射文件XML

一个典型的映射文件Person.hbm.xml注意他的命名方式,一般是类名+hbmxml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping schema="SCOTT" package="mapping">

  <class name="Person" table="PERSON">

    <id name="id" type="long" unsaved-value="null">

      <column name="ID" not-null="true" index="SYS_C004143"/>

      <generator class="native"/>

    </id>

    <property name="name" type="string" column="NAME"/>

  </class>

</hibernate-mapping>

注意红线部分代表了Pojo对应的是那张表。

一般来说映射文件放在和Pojo同一个包

5.        和数据库的连接

Hibernate配置文件,可以采用xml或者property文件。

一个典型的配置文件

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

 <property name="hibernate.connection.username">toposs</property>

     <property name="hibernate.connection.password">toposs</property>

     <property name="hibernate.dialect">

org.hibernate.dialect.Oracle9Dialect

</property>

     <property name="hibernate.connection.url">

jdbc:oracle:thin:@172.16.1.3:1521:orcl

</property>

<property name="hibernate.connection.driver_class">

oracle.jdbc.driver.OracleDriver

</property>

    </session-factory>

</hibernate-configuration>

6.        HibernateEclipse中快速应用

6.1         新建一个工程,将Hibernate3.jar和你需要的数据库驱动添加到工程path

6.2         在数据库中新建一个名为person的表。
未命名2.bmp

6.3         在工程的默认package下建立一个POJOPerson类与表person对应。

public class Person{

 

       private long id;

 

       private String name;

 

 

       public void setId(long value) {

              this.id = value;

       }

 

 

       public long getId() {

              return this.id;

       }

 

 

       public void setName(String value) {

              this.name = value;

       }

 

 

       public String getName() {

              return this.name;

       }

}

6.4         现在我们来建立一个xml的映射文件(Person.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

  <class name="Person" table="PERSON">

    <id name="id" type="long" unsaved-value="0">

      <column name="ID" not-null="true"/>

      <generator class="increment"/>

    </id>

    <property name="name" type="string" column="NAME"/>

  </class>

</hibernate-mapping>

6.5         建立hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <property name="hibernate.connection.username">scott</property>

<property name="hibernate.connection.password">tiger</property>

<property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>

<property name="hibernate.connection.url">jdbc:oracle:thin:@172.16.1.2:1521:rsora</property>

<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>

       <property name="hiberante.show_sql">true</property>

       <mapping resource="Person.hbm.xml" />

    </session-factory>

</hibernate-configuration>

注意红线的部分将mapping文件写到resource中,如果有多个文件,要写多个文件,文件的路径是对于根目录的绝对路径

6.6         项目结构图未命名3.bmp

6.7         所有准备工作都已经做好了,下面在Person中建立一个main方法,我们做一个简单的插入数据库的工作

6.7.1   Main函数的代码

Public static main(String[] args){

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

        SessionFactory factory=config.buildSessionFactory();

        Session session=factory.openSession();

        Transaction tran=session.beginTransaction();

        Person p=new Person();

        p.setName("test");

        session.save(p);

       

        tran.commit();

        session.close();

}

6.7.2   点击Run As Java Application,运行这个main函数

6.7.3   然后查看数据库

未命名4.bmp
我们发现数据库已经新增加了一条记录

 

7.        最常见的关联关系,一对多关联。

7.1         用父子关系说明一对多(多对一关联)

在实际应用中,很少有一个表是独立的,大部分情况是表和表之间是有关联关系的,其中最常见的是一对多(多对一关联)。

父亲和儿子是典型的一对多关系,一个父亲有多个儿子,儿子只有一个父亲。在这个关系中,父亲是一方,儿子是多方。

7.2         在数据库中建立父子关系。

建表的sql语句:

CREATE TABLE father (

       Father_id          INTEGER NOT NULL,

       name        VARCHAR(10) NULL,

       PRIMARY KEY (father_id)  );

CREATE TABLE son (

       Son_id          INTEGER NOT NULL,

       Son_name        VARCHAR(10) NULL,

            Father_ID         INTEGER NULL

       PRIMARY KEY (son_id),

       FOREIGN KEY (father_id)

                             REFERENCES father

);

7.3         建立的表的结构

儿子的表
未命名5.bmp

父亲的表
未命名6.bmp

7.4         建立POJO

同样在我们的工程的defalt package下面新建类FatherSon

7.4.1   Father

public class Father {

 

    private long   fid;

 

    private String name;

 

    private Set    sons = new HashSet();

 

    public long getFid() {

 

        return fid;

    }

 

    public void setFid(long fid) {

 

        this.fid = fid;

    }

 

    public String getName() {

 

        return name;

    }

 

    public void setName(String name) {

 

        this.name = name;

    }

 

    public Set getSons() {

 

        return sons;

    }

 

    public void setSons(Set sons) {

 

        this.sons = sons;

    }

}

7.4.2   Son

public class Son {

 

    private long   sid;

 

    private String name;

 

    private Father father;

 

    public Father getFather() {

 

        return father;

    }

 

    public void setFather(Father father) {

 

        this.father = father;

    }

 

    public String getName() {

 

        return name;

    }

 

    public void setName(String name) {

 

        this.name = name;

    }

 

    public long getSid() {

 

        return sid;

    }

 

    public void setSid(long sid) {

 

        this.sid = sid;

    }

}

7.5         注意到什么不同了吗,在Father类里多了个SetSon类中多了个Father成员变量。

这里我们做的是双向关系,也可以做单向关系只在一方做关联。

7.6         映射文件的写法

7.6.1   Father.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

        <class name="Father" table="father">

       <id name="fid" type="long" unsaved-value="0">

           <column name="father_ID" not-null="true" />

           <generator class="increment" />

       </id>

       <property name="name" type="string" column="NAME" />

       <set name="sons" table="son" cascade="save-update">

           <key column="father_id"></key>

           <one-to-many class="Son" />

       </set>

        </class>

</hibernate-mapping>

 

7.6.2   Son.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

        <class name="Son" table="son">

       <id name="sid" type="long" unsaved-value="0">

           <column name="son_id" not-null="true" />

           <generator class="increment" />

       </id>

       <property name="name" type="string" column="son_NAME" />

       <many-to-one

           name="father"

           class="Father"

           cascade="none"

           outer-join="auto"

           update="true"

           insert="true"

           column="father_id"

       />

        </class>

</hibernate-mapping>

 

7.6.3   看到红线的部分是对应的关联关系的写法,其中没项具体的含义我们留到后面解释

7.7         不要忘了在配置文件中添加我们的映射文件。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC

       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

       "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

<property name="hibernate.connection.username">scott</property>

<property name="hibernate.connection.password">tiger</property>

       <property name="hibernate.dialect">

           org.hibernate.dialect.Oracle9Dialect

       </property>

       <property name="hibernate.connection.url">

           jdbc:oracle:thin:@172.16.1.2:1521:rsora

       </property>

       <property name="hibernate.connection.driver_class">

           oracle.jdbc.driver.OracleDriver

       </property>

       <property name="hiberante.show_sql">true</property>

       <mapping resource="Father.hbm.xml" />

       <mapping resource="Person.hbm.xml" />

       <mapping resource="Son.hbm.xml" />

        </session-factory>

</hibernate-configuration>

7.8         所有准备工作做好了,下面在原来的Main函数中添加代码

public static void main(String[] args) {

 

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

        SessionFactory factory=config.buildSessionFactory();

        Session session=factory.openSession();

        Transaction tran=session.beginTransaction();

        Father father=new Father();

        father.setName("fanta");

        Son son1=new Son();

        Son son2=new Son();

        son1.setName("son1");

        son2.setName("son2");

        father.getSons().add(son1);

        father.getSons().add(son2);

        session.save(father);

       

        tran.commit();

        session.close();

 

    }

7.9         点击Run As Java Application,运行这个main函数,看看数据库发生了什么
未命名7.bmp

未命名9.bmp

7.10     Father表插入了1条记录,son表插入了2条记录,然后回头看看我们的代码做了些什么

……

Father father=new Father();

father.setName("fanta");

Son son1=new Son();

Son son2=new Son();

        son1.setName("son1");

        son2.setName("son2");

        father.getSons().add(son1);

        father.getSons().add(son2);

        session.save(father);

        ……

我们看到显式的调用存储就只有红线的这句话,只存了father,并没有存son,那为什么数据库会有son的记录呢,这就是Hibernate帮我们做的事情,回忆一下FatherPOJO里有个Set

public class Father {

 

    private long   fid;

 

    private String name;

 

    private Set    sons = new HashSet();

 

     ……

因为我们将Set中添加了东西(增加了2个儿子),所以Hibernate在存储Father的时候顺便”(J)将他的2个儿子也插入到数据库中了。

 

8.         常用的一对多和多对一映射选项

8.1         多对一设置

<many-to-one

        name="propertyName"                                             (1)

        column="column_name"                                            (2)

        class="ClassName"                                                  (3)

        cascade="cascade_style"                                             (4)                                       

        unique="true|false"                                                   (5)

        not-null="true|false"                                                   (6)

        lazy="true|proxy|false"                                                (7)

/>

(1) name: 属性名。

(2) column (可选): 外间字段名。它也可以通过嵌套的 <column>元素指定。

(3) class (可选 - 默认是通过反射得到属性类型): 关联的类的名字。

(4) cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。

(5) unique (可选): 使用DDL为外键字段生成一个唯一约束。此外, 这也可以用作property-ref的目标属性。这使关联同时具有 一对一的效果。

(6) not-null (可选): 使用DDL为外键字段生成一个非空约束。

(7) lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="true"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。

 

8.2         一对多配置

<set

    name="propertyName"                                             (1)

    table="table_name"                                                  (2)

    lazy="true|false"                                                       (3)

    inverse="true|false"                                                    (4)

    cascade="all|none|save-update|delete|all-delete-orphan"                      (5)

    order-by="column_name asc|desc"                                    (6)

>  

    <key  column=”ColumnName”/>

    <one-to-many Class=”ClassName”/>

</set>

(1) name 集合属性的名称

(2) table (可选——默认为属性的名称)这个集合表的名称(不能在一对多的关联关系  中使用)

(3) lazy (可选--默认为true) 可以用来关闭延迟加载,指定一直使用预先抓取(对数组  不适用)

(4) inverse (可选——默认为false) 标记这个集合作为双向关联关系中的方向一端。

(5) cascade (可选——默认为none) 让操作级联到子实体

(6) order-by (可选) 指定表的字段(一个或几个)再加上asc或者desc(可选), 定义Set的迭代顺序

你可能感兴趣的:(Hibernate(以前写的给公司的培训资料))