码迷,mamicode.com
首页 > 编程语言 > 详细

Java - @OneToMany的使用

时间:2018-04-09 13:22:26      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:date()   cer   外键   word   sql   ppi   text   root   nfa   

  @OneToMany注解可以用在一对多的数据结构来操作数据库,这里以班级<->学生为例来测试这个注解。

  首先来看看项目结构:

技术分享图片

  xml文件配置,与前面一篇‘一对一‘的随笔差不多,有两个Java类:ClassRoom、Student。所以,应该将两个表写到xml文件中的映射标签中:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

        <!-- 设置数据库的连接 -->
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate?useSSL=false&useUnicode=true&characterEncoding=UTF-8</property>

        <property name="hibernate.connection.username">root</property>

        <property name="hibernate.connection.password">123456</property>

        <!-- 数据库的方言:根据底层的数据库生成不同的SQL -->
        <property  name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 配置显示SQL -->
        <property name="hibernate.show_sql">true</property>

        <!-- 配置格式化SQL -->
        <property name="hibernate.format_sql">true</property>

        <property name="hibernate.hbm2ddl.auto">update</property>

        <property name="hibernate.current_session_context_class">thread</property>

        <mapping class="o2m.Student"/>
        <mapping class="o2m.ClassRoom"/>

    </session-factory>

</hibernate-configuration>

  ClassRoom类:

package o2m;

import javax.persistence.*;
import java.util.Set;

@Entity
public class ClassRoom {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column
    private Integer cid;
    @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
    @JoinColumn(name = "cid")
    private Set<Student> stus;  // 学生集合
    @Column
    private Integer nums;       // 一个班的总人数

    public ClassRoom() {

    }

    public ClassRoom(Set<Student> stus, Integer nums) {
        this.stus = stus;
        this.nums = nums;
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public Set<Student> getStus() {
        return stus;
    }

    public void setStus(Set<Student> stus) {
        this.stus = stus;
    }

    public Integer getNums() {
        return nums;
    }

    public void setNums(Integer nums) {
        this.nums = nums;
    }
}

  @OneToMany注解写在少的类中的对应多的头上。

  Student类:

package o2m;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.Date;

@Entity
public class Student {

    @Id
    @GeneratedValue(generator="sid")
    @GenericGenerator(name="sid", strategy = "assigned")
    @Column(length = 6)
    private String sid;         // 学号
    @Column
    private String name;        // 姓名
    @Column
    private String sex;         // 性别
    @Column
    private String school;      // 学校
    @Column
    private String address;     // 地址
    @Column
    private Date registertime;  // 注册学籍时间

    public Student() {

    }


    public Student(String sid, String name, String sex, String school, String address, Date registertime) {
        this.sid = sid;
        this.name = name;
        this.sex = sex;
        this.school = school;
        this.address = address;
        this.registertime = registertime;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Date getRegistertime() {
        return registertime;
    }

    public void setRegistertime(Date registertime) {
        this.registertime = registertime;
    }
}

  还有一个@ManyToOne注解,@ManyToOne应加在多的类中的对应少的头上,但这里我没有用,因为目前需求只要单向外键关联的。

  这样就有两张表了:

技术分享图片

  然后插入数据测试:

package main;

import o2m.ClassRoom;
import o2m.Student;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import controller.StudentController;

import java.util.*;

public class Main {

    public static void main(String[] args) {

        Configuration configuration = new Configuration().configure();
        ServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory sessionFactory = configuration.buildSessionFactory(registry);
        Session session = sessionFactory.getCurrentSession();

        Transaction transaction = session.beginTransaction();

        List<String> name = new LinkedList<>();
        List<String> sex = new LinkedList<>();
        List<String> address = new LinkedList<>();

        name.add("漩涡鸣人");
        name.add("宇智波佐助");
        name.add("春野樱");
        name.add("旗木卡卡西");
        name.add("自来也");
        name.add("纲手");
        name.add("大蛇丸");
        name.add("宇智波鼬");
        name.add("九尾");
        name.add("八尾");

        sex.add("男");
        sex.add("男");
        sex.add("女");
        sex.add("男");
        sex.add("男");
        sex.add("女");
        sex.add("男");
        sex.add("男");
        sex.add("男");
        sex.add("男");

        address.add("木叶村501号");
        address.add("木叶村504号");
        address.add("木叶村902号");
        address.add("木叶村401号");
        address.add("木叶村107号");
        address.add("木叶村219号");
        address.add("木叶村901号");
        address.add("木叶村116号");
        address.add("木叶村511号");
        address.add("木叶村801号");

        Set<Student> s1 = new HashSet<>();

        for (int i = 0; i < name.size(); i++) {
            Student studenet = new Student(
                    "S0000" + i,
                    name.get(i),
                    sex.get(i),
                    "木叶村",
                    address.get(i),
                    new Date()
            );
            s1.add(studenet);
            session.save(studenet);
        }

        ClassRoom c1 = new ClassRoom(s1, s1.size());

        session.save(c1);
        transaction.commit();
        session.close();
    }

}

  这里注意session.close(),应该放在提交(commit)的后面,不然Student中cid就为null,如果不写也可以,但我想一般api都加上关闭更符合标准一点。

  ps:请不用在意我使用List,我知道它的底层是链表,肯定效率不如数组,这里只是想用用它而已。。。

  最后看一看插入数据后的效果:

  ClassRoom表:

技术分享图片

  对应为:1班共10人。

  Student表:

技术分享图片

  显然,cid是外键classroom的主键,即这些学生都是1班的。

  实际上也有好多问题我不明白,比如,我将CRUD功能单独封装起来调用,就不能有这样的效果了。。。可能我的session会话没使用正确、@OneToMany的具体作用我也不清楚...感觉按理来说Student中没有ClassRoom对象成员,我的操作中也没有手动设置,那么外键cid不应该会有值(这样说也不对,因为本来cid就是外键,既然ClassRoom表创建并给cid赋值了,那它理应有值,与Student无关,但我就是遇到有情况,ClassRoom类中cid有值,但Student表中就为null,比如前面提到的session.close()放在了commit前面就会有这种情况),那么只有可能是@OneToMany做了这件事,正因为有这个注解,Student表中对应的外键就能自动关联...感觉应该是这样。

Java - @OneToMany的使用

标签:date()   cer   外键   word   sql   ppi   text   root   nfa   

原文地址:https://www.cnblogs.com/darkchii/p/8758960.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!