Hibernate4.2.4入门(二)——一对多的映射关系

一、前言

前面我们已经学过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;
    }
}
User

新建实体类: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;
    }
}
Group

新建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();
    }
}

效果图为:

Hibernate4.2.4入门(二)——一对多的映射关系

Hibernate4.2.4入门(二)——一对多的映射关系

总结: