Java中Hibernate单向(1-N)映射实例详解

1.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-configuration>
<session-factory>
    <!-- 配置数据库方言 -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- 配置数据库的驱动 -->
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <!-- 配置数据库用户名 -->
    <property name="hibernate.connection.username">root</property>
    <!-- 配置数据库的密码 -->
    <property name="hibernate.connection.password">root</property>
    <!-- 配置数据库的url -->
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
    <!-- 配置数据池的最大容量 -->
    <property name="hibernate.c3p0.max_size">20</property>
    <!-- 配置数据池的最小容量 -->
    <property name="hibernate.c3p0.min_size">1</property>
    <!-- 配置数据链接的超时界限 -->
    <property name="hibernate.c3p0.timeout">5000</property>
    <!-- 在控制台显示后台是否打印执行的sql -->
    <property name="hibernate.show_sql">true</property>
    <!-- 是否以友好的格式显示打印的sql -->
    <property name="hibernate.format_sql">true</property>
    <!-- 打印一些辅助性的注释 -->
    <property name="hibernate.use_sql_comments">true</property>

    <property name="hibernate.c3p0.max_statements">100</property>
    <property name="hibernate.c3p0.idle_test_period">3000</property>
    <property name="hibernate.c3p0.acquire_increment">2</property>
    <property name="hibernate.c3p0.validate">true</property>
    <!-- 配置数据操作的方式,当为create的时候,每当我们运行这个MemberHandler的时候总是会删除以前的表,然后重新建表,这意味着以前的数据会被丢弃,所以实际应用中要用update -->
    <property name="hbm2ddl.auto">update</property>
    <!-- 将我们上面 Member 的映射文件添加进来 -->
    <mapping resource="org/Rudiment/hibernate/Member.hbm.xml" />
    <mapping resource="org/Rudiment/hibernate/Address.hbm.xml" />
</session-factory>
</hibernate-configuration>

2.(一)持久化类 Member.java

package org.Rudiment.hibernate;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Member{
    private Integer id;
    private Integer age;
    private String name;
    private Set<Address> addressSet = new HashSet<Address>();
   
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Address> getAddressSet() {
        return addressSet;
    }
    public void setAddressSet(Set<Address> addressSet) {
        this.addressSet = addressSet;
    }
}

3.Member.java 的映射规则文件 Member.cfg.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2013-9-9 19:50:34 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="org.Rudiment.hibernate">
    <class name="Member" table="TEST_MEMBER">
        <id name="id" column="ID">
            <generator class="native"></generator>
        </id>
        <property name="age" column="AGE"></property>
        <property name="name" column="NAME"></property>
        <!-- 注意这里的cascade需要配置为all,如果放空为默认的化会导致 hibernate报如下的错误信息:object references an unsaved transient instance - save the transient instance before flushing:org.Rudiment.hibernate.Address -->
        <set name="addressSet" cascade="all">
            <key column="member_id" />
            <one-to-many class="Address" />
        </set>
    </class>
</hibernate-mapping>

4.(多)持久化类 Address.java

package org.Rudiment.hibernate;

public class Address
{
    private Integer address_id;
    private String address_detail;
   
    public Address()
    {}
   
    public Address(String detail)
    {
        this.address_detail = detail;
    }
    public Integer getAddress_id() {
        return address_id;
    }
    public void setAddress_id(Integer address_id) {
        this.address_id = address_id;
    }
    public String getAddress_detail() {
        return address_detail;
    }
    public void setAddress_detail(String address_detail) {
        this.address_detail = address_detail;
    }
}

5. Address.java 的映射规则文件 Address.cfg.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2013-9-10 14:49:04 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="org.Rudiment.hibernate.Address" table="ADDRESS">
        <id name="address_id" type="java.lang.Integer">
            <column name="ADDRESS_ID" />
            <generator class="native" />
        </id>
        <property name="address_detail" type="java.lang.String">
            <column name="ADDRESS_DETAIL" />
        </property>
    </class>
</hibernate-mapping>

6. 操纵持久化类的处理类 MemberHandler.java

package org.Rudiment.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class MemberHandler
{
     public static void insert() {
             Configuration conf = new Configuration();
             conf.configure();
             ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();
             SessionFactory sf = conf.buildSessionFactory(sr);
             Session session = sf.openSession();
            session.beginTransaction();
            Member m = new Member();
            Address ad1 = new Address("广州天河");
            session.persist(ad1);
            m.setName("IT客栈");
            m.setAge(15);
            m.getAddressSet().add(ad1);
            session.save(m);
            Address ad2 = new Address("上海虹口");
            session.persist(ad2);
            m.getAddressSet().add(ad2);
            session.getTransaction().commit();
            session.close();
        }
   
    public static void main(String[] args) {
            insert();
    }
}

注:

当运行MemberHandler的时候将发现,后台数据库多了一个 test_member 和 address 的数据表,表的内容如下:

mysql> show tables;
+---------------------+
| Tables_in_hibernate |
+---------------------+
| address             |
| test_member         |
+---------------------+
2 rows in set (0.00 sec)

mysql> select * from test_member;
+----+------+--------+
| ID | AGE  | NAME   |
+----+------+--------+
|  1 |   15 | IT客栈 |
+----+------+--------+
1 row in set (0.00 sec)

mysql> select * from address;
+------------+----------------+-----------+
| ADDRESS_ID | ADDRESS_DETAIL | member_id |
+------------+----------------+-----------+
|          1 | 广州天河       |         1 |
|          2 | 上海虹口       |         1 |
+------------+----------------+-----------+
2 rows in set (0.05 sec)

mysql> select * from test_member,address;
+----+------+--------+------------+----------------+-----------+
| ID | AGE  | NAME   | ADDRESS_ID | ADDRESS_DETAIL | member_id |
+----+------+--------+------------+----------------+-----------+
|  1 |   15 | IT客栈 |          1 | 广州天河       |         1 |
|  1 |   15 | IT客栈 |          2 | 上海虹口       |         1 |
+----+------+--------+------------+----------------+-----------+
2 rows in set (0.08 sec)

mysql> desc test_member;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| ID    | int(11)      | NO   | PRI | NULL    | auto_increment |
| AGE   | int(11)      | YES  |     | NULL    |                |
| NAME  | varchar(255) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

mysql> desc address;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| ADDRESS_ID     | int(11)      | NO   | PRI | NULL    | auto_increment |
| ADDRESS_DETAIL | varchar(255) | YES  |     | NULL    |                |
| member_id      | int(11)      | YES  | MUL | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

Hibernate单向(1-N)含中间连接表映射范例

1.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-configuration>
<session-factory>
    <!-- 配置数据库方言 -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <!-- 配置数据库的驱动 -->
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <!-- 配置数据库用户名 -->
    <property name="hibernate.connection.username">root</property>
    <!-- 配置数据库的密码 -->
    <property name="hibernate.connection.password">root</property>
    <!-- 配置数据库的url -->
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
    <!-- 配置数据池的最大容量 -->
    <property name="hibernate.c3p0.max_size">20</property>
    <!-- 配置数据池的最小容量 -->
    <property name="hibernate.c3p0.min_size">1</property>
    <!-- 配置数据链接的超时界限 -->
    <property name="hibernate.c3p0.timeout">5000</property>
    <!-- 在控制台显示后台是否打印执行的sql -->
    <property name="hibernate.show_sql">true</property>
    <!-- 是否以友好的格式显示打印的sql -->
    <property name="hibernate.format_sql">true</property>
    <!-- 打印一些辅助性的注释 -->
    <property name="hibernate.use_sql_comments">true</property>

    <property name="hibernate.c3p0.max_statements">100</property>
    <property name="hibernate.c3p0.idle_test_period">3000</property>
    <property name="hibernate.c3p0.acquire_increment">2</property>
    <property name="hibernate.c3p0.validate">true</property>
    <!-- 配置数据操作的方式,当为create的时候,每当我们运行这个MemberHandler的时候总是会删除以前的表,然后重新建表,这意味着以前的数据会被丢弃,所以实际应用中要用update -->
    <property name="hbm2ddl.auto">update</property>
    <!-- 将我们上面 Member 的映射文件添加进来 -->
    <mapping resource="org/Rudiment/hibernate/Member.hbm.xml" />
    <mapping resource="org/Rudiment/hibernate/Address.hbm.xml" />
</session-factory>
</hibernate-configuration>

2.(一)持久化类 Member.java

package org.Rudiment.hibernate;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Member{
    private Integer id;
    private Integer age;
    private String name;
    private Set<Address> addressSet = new HashSet<Address>();
   
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Address> getAddressSet() {
        return addressSet;
    }
    public void setAddressSet(Set<Address> addressSet) {
        this.addressSet = addressSet;
    }
}

3.Member.java 的映射规则文件 Member.cfg.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2013-9-9 19:50:34 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="org.Rudiment.hibernate">
    <class name="Member" table="TEST_MEMBER">
        <id name="id" column="ID">
            <generator class="native"></generator>
        </id>
        <property name="age" column="AGE"></property>
        <property name="name" column="NAME"></property>
        <!-- 注意这里的cascade需要配置为all,如果放空为默认的化会导致 hibernate报如下的错误信息:object references an unsaved transient instance - save the transient instance before flushing:org.Rudiment.hibernate.Address -->
        <set name="addressSet" cascade="all" table="member_address">
            <key column="member_id" />
            <many-to-many class="Address" unique="true" />
        </set>
    </class>
</hibernate-mapping>

4.(多)持久化类 Address.java

package org.Rudiment.hibernate;

public class Address
{
    private Integer address_id;
    private String address_detail;
   
    public Address()
    {}
   
    public Address(String detail)
    {
        this.address_detail = detail;
    }
    public Integer getAddress_id() {
        return address_id;
    }
    public void setAddress_id(Integer address_id) {
        this.address_id = address_id;
    }
    public String getAddress_detail() {
        return address_detail;
    }
    public void setAddress_detail(String address_detail) {
        this.address_detail = address_detail;
    }
}

5.Address.java 的映射规则文件 Address.cfg.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2013-9-10 14:49:04 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="org.Rudiment.hibernate.Address" table="ADDRESS">
        <id name="address_id" type="java.lang.Integer">
            <column name="ADDRESS_ID" />
            <generator class="native" />
        </id>
        <property name="address_detail" type="java.lang.String">
            <column name="ADDRESS_DETAIL" />
        </property>
    </class>
</hibernate-mapping>

6.操纵持久化类的处理类 MemberHandler.java

package org.Rudiment.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class MemberHandler
{
     public static void insert() {
             Configuration conf = new Configuration();
             conf.configure();
             ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();
             SessionFactory sf = conf.buildSessionFactory(sr);
             Session session = sf.openSession();
            session.beginTransaction();
            Member m = new Member();
            Address ad1 = new Address("广州天河");
            session.persist(ad1);
            m.setName("IT客栈");
            m.setAge(15);
            m.getAddressSet().add(ad1);
            session.save(m);
            Address ad2 = new Address("上海虹口");
            session.persist(ad2);
            m.getAddressSet().add(ad2);
            session.getTransaction().commit();
            session.close();
        }
   
    public static void main(String[] args) {
            insert();
    }
}

注:

当运行MemberHandler的时候将发现,后台数据库多了一个 test_member、member_address 和 address 的数据表,表的内容如下:

mysql> show tables;
+---------------------+
| Tables_in_hibernate |
+---------------------+
| address             |
| member_address      |
| test_member         |
+---------------------+
3 rows in set (0.00 sec)

mysql> select * from test_member;
+----+------+--------+
| ID | AGE  | NAME   |
+----+------+--------+
|  1 |   15 | IT客栈 |
+----+------+--------+
1 row in set (0.00 sec)

mysql> select * from address;
+------------+----------------+
| ADDRESS_ID | ADDRESS_DETAIL |
+------------+----------------+
|          1 | 广州天河       |
|          2 | 上海虹口       |
+------------+----------------+
2 rows in set (0.00 sec)

mysql> select * from member_address;
+-----------+-----+
| member_id | elt |
+-----------+-----+
|         1 |   1 |
|         1 |   2 |
+-----------+-----+
2 rows in set (0.00 sec)

mysql> desc test_member;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| ID    | int(11)      | NO   | PRI | NULL    | auto_increment |
| AGE   | int(11)      | YES  |     | NULL    |                |
| NAME  | varchar(255) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

mysql> desc address;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| ADDRESS_ID     | int(11)      | NO   | PRI | NULL    | auto_increment |
| ADDRESS_DETAIL | varchar(255) | YES  |     | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+
2 rows in set (0.02 sec)

mysql> desc member_address;
+-----------+---------+------+-----+---------+-------+
| Field     | Type    | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| member_id | int(11) | NO   | PRI | NULL    |       |
| elt       | int(11) | NO   | PRI | NULL    |       |
+-----------+---------+------+-----+---------+-------+
2 rows in set (0.02 sec)

 

时间: 2024-10-23 13:33:22

Java中Hibernate单向(1-N)映射实例详解的相关文章

Android 中ViewPager重排序与更新实例详解

Android 中ViewPager重排序与更新实例详解 最近的项目中有栏目订阅功能,在更改栏目顺序以后需要更新ViewPager.类似于网易新闻的频道管理. 在重新排序之后调用了PagerAdapter的notifyDataSetChanged方法,发现ViewPager并没有更新,于是我开始跟踪源码,在调用PagerAdapter的notifyDataSetChanged方法后,会触发Viewpager的dataSetChanged方法. void dataSetChanged() { //

Android 中CheckBox的isChecked的使用实例详解

Android 中CheckBox的isChecked的使用实例详解 范例说明 所有的网络服务在User使用之前,都需要签署同意条款,在手机应用程序.手机游戏的设计经验中,常看见CheckBox在同意条款情境的运用,其选取的状态有两种即isChecked=true与isChecked=false. 以下范例将设计一个TextView放入条款文字,在下方配置一个CheckBox Widget作为选取项,通过Button.onClickListener按钮事件处理,取得User同意条款的状态. 当C

SQLserver中cube:多维数据集实例详解

1.cube:生成多维数据集,包含各维度可能组合的交叉表格,使用with 关键字连接 with cube 根据需要使用union all 拼接 判断 某一列的null值来自源数据还是 cube 使用GROUPING关键字 GROUPING([档案号]) = 1 : null值来自cube(代表所有的档案号) GROUPING([档案号]) = 0 : null值来自源数据 举例: SELECT * INTO ##GET FROM (SELECT * FROM ( SELECT CASE WHEN

Java中成员方法与成员变量访问权限详解_java

记得在一次面试的笔试题中,有的面试官会要求写出具体的像pullic这些访问限定符的作用域.其实,平常我都没去系统的考虑这些访问限定符的作用域,特别是包内包外的情况,OK,笔试不行了.  这是java基本的知识,也是公司看重的,那没办法啦,我的脑袋记不住东西,那我只能把这些东西写下来方便自己温故知新,不废话了,贴代码了. 代码如下: package com.jaovo; /** *_1_ 成员变量访问权限的求证 * public private protected default(默认的权限) *

JS中的hasOwnProperty()和isPrototypeOf()属性实例详解_javascript技巧

这两个属性都是Object.prototype所提供:Object.prototype.hasOwnProperty()和Object.prototype.isPropertyOf() 先讲解hasOwnProperty()方法和使用.在讲解isPropertyOf()方法和使用 看懂这些至少要懂原型链 一.Object.prototype.hasOwnProperty() 概述 hasOwnProperty()方法用来判断某个对象是否含有指定的自身属性 语法 obj.hasOwnPropert

Java中对List集合的常用操作详解_java

目录: 1.list中添加,获取,删除元素: 2.list中是否包含某个元素: 3.list中根据索引将元素数值改变(替换): 4.list中查看(判断)元素的索引: 5.根据元素索引位置进行的判断: 6.利用list中索引位置重新生成一个新的list(截取集合): 7.对比两个list中的所有元素: 8.判断list是否为空: 9.返回Iterator集合对象: 10.将集合转换为字符串: 11.将集合转换为数组: 12.集合类型转换: 备注:内容中代码具有关联性. 1.list中添加,获取,

Angular中$cacheFactory的作用和用法实例详解_AngularJS

先说下缓存: 一个缓存就是一个组件,它可以透明地储存数据,以便以后可以更快地服务于请求.多次重复地获取资源可能会导致数据重复,消耗时间.因此缓存适用于变化性不大的一些数据,缓存能够服务的请求越多,整体系统性能就能提升越多. $cacheFactory介绍: $cacheFactory是一个为Angular服务生产缓存对象的服务.要创建一个缓存对象,可以使用$cacheFactory通过一个ID和capacity.其中,ID是一个缓存对象的名称,capacity则是描述缓存键值对的最大数量. 1.

Java中volatile关键字的作用与用法详解_java

volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile 关键字作用是,使系统中所有线程对该关键字修饰的变量共享可见,可以禁止线程的工作内存对volatile修饰的变量进行缓存. volatile 2个使用场景: 1.可见性:Java提供了volatile关键字来保证可见性. 当一个共享变量被volatile修饰时,它会保证修

Android MotionEvent中getX()和getRawX()的区别实例详解

Android MotionEvent中getX()和getRawX()的区别实例详解 实例代码: public class Res extends Activity implements View.OnTouchListener { Button btn = null; int x = 0; int y = 0; int rawx = 0; int rawy = 0; @Override public void onCreate(Bundle savedInstanceState) { sup

jQuery中attr()与prop()函数用法实例详解(附用法区别)_jquery

本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. 1. attr(属性名) //获取属性的值(取得第一个匹配元素的属性值.通过这个方法可以方便地从第一个匹配元素中获取一个属性的值.如果元素没有相应属性,则返回 undefined ) 2.