[Hibernate] - many to many

Hibernate的多对多实现:

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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1/testdb</property>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- Enable Hibernate‘s automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>

        <mapping resource="com/my/hbm/User.hbm.xml"/>
        <mapping resource="com/my/hbm/Bank.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

mapping配置:

Bank.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.my.bean.Bank" table="bank">
        <id name="bankID" column="bank_id" type="long">
            <generator class="native"></generator>
        </id>
        <set name="users" table="card">
            <key column="bank_id"></key>
            <many-to-many class="com.my.bean.User" column="user_id"></many-to-many>
        </set>
        <property name="bankName" column="bank_name" type="java.lang.String" length="100" not-null="true"></property>
    </class>
</hibernate-mapping>

User.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.my.bean.User" table="user">
        <id name="userID" column="user_id" type="long">
            <generator class="native"></generator>
        </id>
        <set name="banks" table="card">
            <key column="user_id"></key>
            <many-to-many class="com.my.bean.Bank" column="bank_id"></many-to-many>
        </set>
        <property name="userName" column="user_name" type="java.lang.String" length="100" not-null="true"></property>
    </class>
</hibernate-mapping>

POJO

package com.my.bean;

import java.util.Set;

public class Bank {
    private long bankID;
    private String bankName;
    private Set<User> users;

    public long getBankID() {
        return bankID;
    }
    public void setBankID(long bankID) {
        this.bankID = bankID;
    }
    public String getBankName() {
        return bankName;
    }
    public void setBankName(String bankName) {
        this.bankName = bankName;
    }
    public Set<User> getUsers() {
        return users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }
}
package com.my.bean;

import java.util.Set;

public class User {
    private long userID;
    private String userName;
    private Set<Bank> banks;

    public long getUserID() {
        return userID;
    }
    public void setUserID(long userID) {
        this.userID = userID;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public Set<Bank> getBanks() {
        return banks;
    }
    public void setBanks(Set<Bank> banks) {
        this.banks = banks;
    }
}

测试:

package com.my.init;

import java.util.HashSet;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.my.bean.Bank;
import com.my.bean.User;
import com.my.dao.util.HibernateUtil;

public class Test {

    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        try {
            // create user
            User userRobin = new User();
            userRobin.setUserName("Robin");
            userRobin.setBanks(new HashSet<Bank>());
            User userBen = new User();
            userBen.setUserName("Ben");
            userBen.setBanks(new HashSet<Bank>());

            // create bank
            Bank bankCBC = new Bank();
            bankCBC.setBankName("CBC");
            bankCBC.setUsers(new HashSet<User>());
            Bank bankBBC = new Bank();
            bankBBC.setBankName("BBC");
            bankBBC.setUsers(new HashSet<User>());

            // add relationship
            userRobin.getBanks().add(bankCBC);
            userRobin.getBanks().add(bankBBC);
            userBen.getBanks().add(bankCBC);
            userBen.getBanks().add(bankBBC);

            session.save(userRobin);
            session.save(userBen);
            session.save(bankCBC);
            session.save(bankBBC);

            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        }

        session.close();
    }

}


上面测试例子会自动生成一张表:card,这张是bank和user表的映射表。里头是bank_id和user_id两个组合字段。

如果想在这张映射表中加入额外的字段,那么hibernate似乎无法做到。因为这需要把多对多写成两个一对多的关系。事实上这样加额外字段到映射表,好像也是违反了DBMS的设计原则。

时间: 2024-11-25 09:40:23

[Hibernate] - many to many的相关文章

Hibernate - HHH000352: Unable to release batch statement

这是hibernate的一个bug,具体看https://hibernate.atlassian.net/browse/HHH-11732?attachmentViewMode=list When using stateless session with jdbc batch size we get an HHH000352: Unable to release batch statement.. error in session.close() after rollback: Code:Con

Hibernate简述及入门实例

一.Hibernate简述 总的概括,Hibernate是一个ORM的轻量级持久层框架,解决了对象和关系数据库中表的不匹配问题(阻抗不匹配)以及拥有开发代码不用去继承hibernate类或接口的优势(无侵入性).hibernate框架实现使得开发人员可以避免反复地编写javajdbc部分代码,应用面向对象的思维操作关系型数据库. 二.使用myeclipse创建hibernate实例两种方法(以hibernate3.5.2及mysql为例) a)手动编写hibernate.cfg.xml及*.hb

对象序列化和反序列--Hibernate的查询和新增极其相似

Hibernate几个关键字持久化,ORM(关系对象映射)(数据库中关系称作是一张表) 应用在项目中,刘一从写的查询代码,每次都挂掉,想要弄出测试数据,自己想着把查询出来的复杂数据弄到文件里自己要是去造那些复杂数据很麻烦public class Object1 { public static void main(String args[]){ HashMap<String, Object> obj=new HashMap<String,Object>(); obj.put(&quo

Hibernate的七种映射关系之七种关联映射(二)

继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.private Classes classes; 2.Student.hbm.xml里添加many-to-one标签:<many-to-one name="classes" column="classesid"/>.Classes.hbm.xml在例子(六)里的那

Hibernate的七种映射关系之七种关联映射(一)

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 一.Hibernate多对一关联映射:就是在"多"的一端加外键,指向"一"的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1."多"端实体加入引用"一"端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2."多"端配置文

mybatis与hibernate的区别

本文转载自:http://blog.csdn.net/wangpeng047/article/details/17038659 以前没怎么用过mybatis,只知道与hibernate一样是个orm数据库框架.随着使用熟练度的增加,发现它与hibernate区别是非常大的,结合至今为止的经验,总结出以下几点: 1. hibernate是全自动,而mybatis是半自动. hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql

hibernate载入持久化对象的两种方式——get、load

一.get与load对照 在hibernate中get和load方法是依据id取得持久化对象的两种方法.但在实际使用的过程中总会把两者混淆,不知道什么情况下使用get好,什么时候使用load方法效率更高.下边具体说一下get和load的不同,有些时候为了对照也会把find加进来. 1.从返回结果上对照: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回null 2.从检索运行机制上对照: get方法和fin

org.hibernate.NonUniqueObjectException:a different object with the same identifier value was alread

转自: http://blog.csdn.net/zzzz3621/article/details/9776539 看异常提示意思已经很明显了,是说主键不唯一,在事务的最后执行SQL时,session缓存里面有多个(>1)主键一样的对象. 了解过hibernate的都知道它有一个一级缓存,即session级别的缓存,在一个事务的执行过程中可以管理持久化对象,在事务最后执行SQL,可以减少数据库的操作. 报这个异常就得仔细看看你的代码,一定有地方引用的对象已经不同了. 下面就是一个典型的例子: [

谈谈你对Hibernate的理解

答: 1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象.建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化. 2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息.从Java程序的运行功能上来讲,保存对

Hibernate session缓存

一级缓存(执行代码时查看console台上的sql语句)  清空缓存 @Test public void demo03(){ //清空缓存 Session session=factory.openSession(); session.beginTransaction(); //1.查询 User user = (User)session.get(User.class, 1); System.out.println(user); //session.evitc(user) //将执行对象从一级缓存