文档章节

JPA/hibernate 的主键生成策略

921977939qqcom
 921977939qqcom
发布于 2017/01/31 16:07
字数 691
阅读 4
收藏 0
@GeneratedValue(strategy = GenerationType.TABLE)

先讨论一下使用这个主键注解的效果

 

例子中有两个实体教师和学生,是多对多关系,双向引用

两个实体的主键注解都是

@GeneratedValue(strategy = GenerationType.TABLE)

 

教师:

package com.jege.jpa.many2many;

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

/**
 * @author JE哥
 * @email 1272434821@qq.com
 * @description:双向:关系维护端:可以操作中间表
 */
@Entity
@Table(name = "t_teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
    private String tname;

    // @ManyToMany注释表示Teacher是多对多关系的一端。
    // @JoinTable描述了多对多关系的数据表关系。name属性指定中间表名称,joinColumns定义中间表与Teacher表的外键关系。
    // 中间表Teacher_Student的Teacher_ID列是Teacher表的主键列对应的外键列,inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系。
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinTable(name = "t_teacher_student",
            joinColumns = {@JoinColumn(name = "teacher_id")},
            inverseJoinColumns = {@JoinColumn(name = "student_id")})
    private Set<Student> students = new HashSet<Student>();

    public Teacher() {

    }

    public Teacher(String tname) {
        this.tname = tname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTname() {
        return tname;
    }

    public void setTname(String tname) {
        this.tname = tname;
    }

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "Teacher [id=" + id + ", tname=" + tname + "]";
    }

}

学生:

package com.jege.jpa.many2many;

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

/**
 * @author JE哥
 * @email 1272434821@qq.com
 * @description:双向:关系被维护端:不能操作中间表
 */
@Entity
@Table(name = "t_student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
    private String sname;

    @ManyToMany(mappedBy = "students")
    private Set<Teacher> teachers = new HashSet<Teacher>();

    public Student() {

    }

    public Student(String sname) {
        this.sname = sname;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Set<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", sname=" + sname + "]";
    }

}

 

测试方法:

    // insert 3条,单表插入,中间表无反应
    // 因为Student是关系被维护端:不能操作中间表
    @Test
    public void persist2() throws Exception {
        Teacher teacher = new Teacher("教师1");

        Student student1 = new Student("学生1");
        Student student2 = new Student("学生2");

        student1.getTeachers().add(teacher);// 插入中间表
        student2.getTeachers().add(teacher);

        entityManager.getTransaction().begin();
        entityManager.persist(teacher);
        entityManager.persist(student1);
        entityManager.persist(student2);
        entityManager.getTransaction().commit();
    }

 

共生成了四个表

hibernate_sequences是hibernate为我们生成的

可以看到主键教师的主键是1,到了学生就变为了2,3

再看看hibernate_sequences表,一个字段next_val变成了4

说明hibernate会为我们自动生成一个表,保存下一个主键应该生成的id,

这样子可以多个表使用不重复的id主键

 

再看一下

@TableGenerator

 

在学生表配置:

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tablegen1")
    @TableGenerator(name = "tablegen1", table = "myidtable", pkColumnName = "pkcolumn1", valueColumnName = "valuecolumn1", pkColumnValue = "pkcolumnvalue1", allocationSize = 1)
    private Long id;

 

在教师表配置:

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tablegen2")
    @TableGenerator(name = "tablegen2", table = "myidtable", pkColumnName = "pkcolumn1", valueColumnName = "valuecolumn1", pkColumnValue = "pkcolumnvalue2", allocationSize = 1)
    private Long id;

 

结果:

这样子可以分配哪些表在一起不用重复主键

 

经过测试发现

@TableGenerator

只能重新设置,一个实体不能用另一个实体的tablegenerator的

 

 

© 著作权归作者所有

921977939qqcom
粉丝 0
博文 5
码字总数 2084
作品 0
中山
私信 提问

暂无文章

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
6
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部