一、前言
前面我们已经学过hibernate的基础,学会增删改查简单的操作,然而我们数据库中存在着1对多,多对1,多对多的关系,hibernate又是基于ORM基础上的开源框架,可以让我们不用去编写SQL语句,它会自动生成,mybatis也是基于ORM基础上的开源框架,只不过需要我们编写sql语句,算是一个半自动的orm吧,今天讲解的主要是1对多的映射关系。
1.1、创建项目
这里使用到的是组和用户的关系,1个组可以有多个用户。Group和User(这里笔者说个题外话,注意注意:映射文件中table的名字一定不能是mysql的关键字,笔者就是使用了Group,一直报sql语法错误,后来才发现原来Group是关键字)
新建实体类:User.java
package com.hibernate.one_manys; public class User { private int uid; private String uname; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public User(String uname) { this.uname=uname; } }
新建实体类:Group.java,其中添加User的集合,表示一个组中存在多个用户,使用集合表示
package com.hibernate.one_manys; import java.util.HashSet; import java.util.Set; public class Group { private int gid; private String gtitle; private Set<User> users = new HashSet<User>(); public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } public int getGid() { return gid; } public void setGid(int gid) { this.gid = gid; } public String getGtitle() { return gtitle; } public void setGtitle(String gtitle) { this.gtitle = gtitle; } }
新建User的配置文件:User.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="com.hibernate.one_manys.User" table="USER"> <id name="uid" type="int"> <column name="UID"></column> <generator class="native"></generator> </id> <property name="uname" column="UNAME"></property> </class> </hibernate-mapping>
新建Group的配置文件:Group.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> <!-- 注意点:Group是mysql中的关键字,如果使用会报语句错误 --> <!-- native:根据底层数据库的能力选择identity, sequence 或者hilo中的一个。 --> <class name="com.hibernate.one_manys.Group" table="Groups"> <id name="gid" type="int"> <column name="GID"/> <generator class="native"/> </id> <property name="gtitle" type="java.lang.String"> <column name="GTITLE"/> </property> <!-- cascade:级联操作 all : 所有情况下均进行关联操作。 none:所有情况下均不进行关联操作。这是默认值。 save-update:在执行save/update/saveOrUpdate时进行关联操作。 delete:在执行delete时进行关联操作 --> <set name="users" table="User" cascade="delete"> <!-- column:指明了在User表里有一个gid的列名,是指向Group表的外键 --> <key column="gid"/> <!-- 一对多的映射 --> <one-to-many class="com.hibernate.one_manys.User"/> </set> </class> </hibernate-mapping>
注意:这里使用到cascade级联操作,顾名思义,就是你执行增删改查的时候会触发另一张表,简单说来就是,当你主表执行删除时,从表也会随之删除。
接下来编写测试类:
package com.hibernate.one_manys; 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; /** * 简单的1对多的的数据关系,使用到的表有:Groups(注意点:Group是数据库中的关键字),User,其中Groups是一,User是多 * 使用到的类:Group,User;配置文件:Group.xml,User.xml * 步骤: * 1、新建实体类Group和User * 2、新建映射文件Group.hbm.xml和User.hbm.xml * 3、在配置文件hibernate.cfg.xml配置文件中声明映射文件 * 4、新建测试类测试功能模块 * 注意点: * 1、在映射文件中定义映射的表不能是关键字,其中Group是关键字,所以一直报语法错误 * */ public class Test_1 { private static SessionFactory sessionfactory; private static Session session; public static void main(String[] args){ //配置 Configuration config = new Configuration().configure(); //注册服务 ServiceRegistry service = new ServiceRegistryBuilder().applySettings(config.getProperties()) .buildServiceRegistry(); //实例化sessionfactory工厂 sessionfactory = config.buildSessionFactory(service); //打开一个session session = sessionfactory.openSession(); //添加 add(); //查询 sel(); //修改 //update(); //删除 del(); } //添加语句 public static void add(){ Transaction transaction = session.beginTransaction(); Group g = new Group(); g.setGtitle("学生会"); User u = new User("张三"); User u1 = new User("李四"); g.getUsers().add(u); g.getUsers().add(u1); //注意点:需要保存组的对象 session.save(g); session.save(u); session.save(u1); transaction.commit(); } //查询语句 public static void sel(){ Group g = (Group) session.get(Group.class, 1); System.out.println(g.getGtitle()+","+g.getUsers().size()); for(User u: g.getUsers()){ System.out.println(u.getUname()); } } //修改语句 public static void update(){ Group g = (Group)session.get(Group.class,1); g.setGtitle("技术会"); for(User u : g.getUsers()){ if(u.getUname().equals("张三")){ u.setUname("陈凯辉"); g.getUsers().add(u); } } Transaction transaction = session.beginTransaction(); session.save(g); transaction.commit(); } //删除语句 //注意级联事件 public static void del(){ Group g = (Group)session.get(Group.class, 1); Transaction transaction = session.beginTransaction(); session.delete(g); transaction.commit(); } }
效果图为:
总结: