ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
    Hibernate对于数据库的操作,全部利用面向对象的思维来理解和实现的。一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它。     今天就来说说多对一的关联映射。     数据库中有多对一的关系,Hibernate自然也有对象的多对一的关联关系。比如用户和用户组,一个用户只属于一个组,一个组有多名用户。我们就可以说用户和用户组的关系就是多对一的关系。用对象的uml图表示一下: ![](https://box.kancloud.cn/2016-02-18_56c53c1039ffa.jpg)     在Hibernate中如何来实现呢?首先定义这两个实体类: ~~~ package com.bjpowernode.hibernate; /** * 用户组 * @author Longxuan * */ public class Group { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } package com.bjpowernode.hibernate; /** * 用户类 * @author Longxuan * */ public class User { private int id; private String name; private Group group; public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ~~~ hibernate.cfg.xml配置文件: ~~~ <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name="foo"> <property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property><!-- 设置是否显示生成sql语句 --> <property name="hibernate.format_sql">false</property><!-- 设置是否格式化sql语句--> <mapping resource="com/bjpowernode/hibernate/Tables.hbm.xml" /> </session-factory> </hibernate-configuration> ~~~ hibernate.properties配置文件: ~~~ ## MySQL hibernate.dialect org.hibernate.dialect.MySQLDialect #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect hibernate.connection.driver_class com.mysql.jdbc.Driver hibernate.connection.url jdbc:mysql://localhost:3306/hibernate_many2one hibernate.connection.username root hibernate.connection.password root ~~~     这是最基础的准备工作,多对一映射在对数据进行更改时,会有一些限制。当没有该用户组时,添加用户,就会出错,当该用户组有用户时,删除该用户组也会报错。     我们当然可以按一般的方法来做。添加的时候,先手动添加组,再添加用户。删除时,先删除所有的用户,再删除用户组。但是Hibernate为我们提供了一种便捷的方式——many-to-one。在映射文件hbm.xml中配置后,就可以不用再想那些限制了。Hibernate会自动添加上所引用的数据。     给出映射文件: ~~~ <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.bjpowernode.hibernate.User" table="t_user"> <id name="id"> <generator class="native" /> </id> <property name="name"></property> <many-to-one name="group" column="groupid" cascade="save-update"></many-to-one> </class> <class name="com.bjpowernode.hibernate.Group" table="t_group"> <id name="id"> <generator class="native" /> </id> <property name="name"></property> </class> </hibernate-mapping> ~~~      配置了many-to-one会自动在t_user表中创建外键groupid,与t_group的id映射。 ![](https://box.kancloud.cn/2016-02-18_56c53c104999b.jpg)   many-to-one标签用到了cascade,指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。其属性值如下:  - all:在所有的情况下都执行级联操作; - none:在所有情况下都不执行级联操作; - save-update:在保存和更新的时候执行级联操作;、 - delete:在删除的时候执行级联操作。   测试类Many2OneTest: ~~~ package com.bjpowernode.hibernate; import junit.framework.TestCase; import org.hibernate.Session; public class Many2OneTest extends TestCase { /** * 测试添加用户 */ public void testSave3(){ Session session = null; try{ session = HibernateUtils.getSession(); session.beginTransaction(); Group group = new Group(); group.setName("提高班"); User user1 = new User(); user1.setName("张三"); user1.setGroup(group); User user2 = new User(); user2.setName("李四"); user2.setGroup(group); //普通方法 :必须先保存group,再保存user //配置了many-to-one 则不用再手动save group了。 //session.save(group); session.save(user1); session.save(user2); session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } } ~~~     结果图: ![](https://box.kancloud.cn/2016-02-18_56c53c105ecd7.jpg) 执行测试前:![](https://box.kancloud.cn/2016-02-18_56c53c10749bf.jpg) , 执行测试后: ![](https://box.kancloud.cn/2016-02-18_56c53c108a9bd.jpg)     用many-to-one进行配置后,hibernate会自动去添加外键,而我们做的任何操作都不需要去考虑它的结构,也不用手动去维护这个关系,关系由Hibernate自动维护。这就是Hibernate的魅力所在。