环境:Spring Data Jpa,hibernate或者其他jpa实现也是一样的;Spring Boot

场景:User和Role,一个User要对应多个Role。

第一种方式,没有中间关系表,直接在role表中添加一个user_id字段

User:

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by zhangpeng on 16-6-15.
 */
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    // The user email
    @NotNull
    private String email;
    // The user name
    @NotNull
    private String name;

    private String password;

    @OneToMany(mappedBy = "user", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    private Set<Role> roles = new HashSet<>();

   //add getter and setter
}

Role:

import javax.persistence.*;

/**
 * Created by zhangpeng on 16-6-17.
 */
@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
    String roleName;
    @ManyToOne
    @JoinColumn(name = "user_id")
    User user;
   //add getter and setter
}

需要注意User类中mappedBy = "user",这个user就是Role中所持有的User对象的名字。Role中@JoinColumn(name = "user_id") 是指定role表中user标识符的字段名。cascade = {CascadeType.ALL}是用来设定级联操作的,这里开启了所有的级联操作。fetch = FetchType.EAGER是用来设置加载类型的。默认是懒加载,如果是懒加载,那就意味着User里的roles在你查询出来这个user时不同时查询出来,而是等访问user里的roles对象时才进行加载。我这里设置的是查询user时就把roles加载过来。

第二种,个人感觉更好一点的,user和role都不持有对方的引用,而是生成中间表:

User:

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by zhangpeng on 16-6-15.
 */
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    // The user email
    @NotNull
    private String email;
    // The user name
    @NotNull
    private String name;

    private String password;

//    private String role;

    @OneToMany( cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    private Set<Role> roles = new HashSet<>();

//add getter and setter
}

Role:

import javax.persistence.*;

/**
 * Created by zhangpeng on 16-6-17.
 */
@Entity
@Table(name = "roles")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
    String roleName;
//    @ManyToOne
//    @JoinColumn(name = "user_id")
//    User user;

//    public User getUser() {
//        return user;
//    }
//
//    public void setUser(User user) {
//        this.user = user;
//    }

   //add getter and setter
}

这样就可以了。

测试:

import com.guduo.fenghui.dao.RoleDao;
import com.guduo.fenghui.dao.UserDao;
import com.guduo.fenghui.entity.Role;
import com.guduo.fenghui.entity.User;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class Test {

    @Autowired
    UserDao userDao;

    @Autowired
    RoleDao roleDao;

    @Test
    public void test() {
        User user = new User();
        user.setEmail("csonezp@gmail.com");
        user.setName("zhangpeng");
        user.setPassword("123456");
        for (int i = 0; i <= 2; i++) {
            Role role = new Role();
            role.setRoleName(i + "j");
//如果选择的是第一种方式,那要加上这一句。因为第一种方式配置的有mappedby,控制权是在role这边
//            role.setUser(user);
            user.getRoles().add(role);

        }
        userDao.save(user);

        user = userDao.findByName("zhangpeng");

        Assert.assertEquals(user.getRoles().size(), 3);
        user.getRoles().get(0).setRoleName("asdasd");
        userDao.save(user);

        user = userDao.findByName("zhangpeng");

        Assert.assertEquals("asdasd", user.getRoles().get(0).getRoleName());

        userDao.delete(user.getId());
    }

}

这一段测试代码中,体现了级联插入,级联查询,级联更新,级联删除。

JPA(Hibernate) @OneToMany 两种例子的更多相关文章

  1. Hibernate中两种获取Session的方式

    转自:https://www.jb51.net/article/130309.htm Session:是应用程序与数据库之间的一个会话,是hibernate运作的中心,持久层操作的基础.对象的生命周期 ...

  2. Spring整合Hibernate的两种方式

    在使用spring注解整合hibernate时出现"org.hibernate.MappingException: Unknown entity: com.ssh.entry.Product ...

  3. Hibernate 的两种配置

    前言:不管是注解配置还是xml,都是告诉hibernate你想创建什么样的数据表,几张数据表中的关系是什么,仅此而已,剩下的不过就是hibernate的优化了. 所以从创建数据表的ddl语句和数据表的 ...

  4. Spring Data Jpa(Hibernate) OneToMany

    这个其实非常简单.假设有topic 和 subscriber两个实体类,不考虑关联关系,则连个类的代码如下: /** * Created by csonezp on 2017/8/31. */ @En ...

  5. jpa/hibernate @onetomany 使用left join 添加多条件,可以使用过滤器filters (with-clause not allowed on fetched associations; use filters异常信息)

    package com.ipinyou.mip.dataAsset.campaignManagement.entity; import com.ipinyou.mip.utils.NumberUtil ...

  6. Hibernate中两种删除用户的方式

    第一种,是比较传统的,先根据主键列进行查询到用户,在进行删除用户 //删除数据 public void deleteStudent(String sno) { init() ; Student qu ...

  7. hibernate级联查询映射的两种方式

    Hibernate主要支持两种查询方式:HQL查询和Criteria查询.前者应用较为广发,后者也只是调用封装好的接口. 现在有一个问题,就是实现多表连接查询,且查询结果集不与任何一个实体类对应,怎么 ...

  8. Hibernate(八)--session的两种获取方式

    openSession getCurrentSession Hibernate有两种方式获得session,分别是: openSession和getCurrentSession他们的区别在于1. 获取 ...

  9. 【JPA】两种不同的实现jpa的配置方法

    两种不同的实现jpa的配置方法 第一种: com.mchange.v2.c3p0.ComboPooledDataSource datasource.connection.driver_class=co ...

随机推荐

  1. Gulp构建前端自动化项目

    类似于Grunt,gulp是另一个同样功能很强大的前端项目自动化利器. 下面是项目的效果:

  2. 从指定的URL下载文件

    通过使用URLDownLoadToFile函数,我们能从指定的URL下载文件,保存到本地,并且下载的文件类型可以是可执行文件 实例如下,http://www.xuexic.com 的根目录下存在一个l ...

  3. js高级编程中命名空间的两种用法

    第一种:// 声明一个全局对象Namespace,用来注册命名空间Namespace = new Object();// 全局对象仅仅存在register函数,参数为名称空间全路径,如"Gr ...

  4. 。net新人报道

    入行一年多  关注博客园也有半年的时间了 今天开始写第一篇东西  以后有什么笔记也会慢慢写上来的

  5. Android HandlerThread 的使用及其Demo (转)

    转自http://www.cnblogs.com/hnrainll/p/3597246.html 介绍 首先我们来看看为什么我们要使用HandlerThread?在我们的应用程序当中为了实现同时完成多 ...

  6. (原创)jQuery Media Plugin-jQuery的网页媒体播放器插件的使用心得

    jQuery Media Plugin是一款基于jQuery的网页媒体播放器插件,它支持大部分的网络多媒体播放器和多媒体格式,比如:Flash, Windows Media Player, Real ...

  7. 2017 年值得一瞥的 JavaScript 相关技术趋势

    跨年前两天,Dan Abramov在Twitter上提了一个问题: JS社区毫不犹豫的抛出了它们对于新技术的预期与期待,本文内容也是总结自Twitter的回复,按照流行度降序排列.有一个尚未确定的小点 ...

  8. oracle 多条语句同时执行(比如返回两个dataset)

    public DataSet GetQualityStatistics(DateTime start_date,DateTime end_date,string modality,string hos ...

  9. Angular.JS + Require.JS + angular-async-loader 来实现异步加载 angular 模块

    传统的 angular 应用不支持异步加载模块,必须在 module 启动的时候,所有模块必须预加载进来. 通过使用 angular-async-loader 库,我们可以使用 requirejs 等 ...

  10. android WeakReference(弱引用 防止内存泄漏)与SoftReference(软引用 实现缓存机制(cache))

    在Android开发中,基本上很少有用到软引用或弱引用,这两个东东若用的很好,对自己开发的代码质量的提高有很大的帮助.若用的不好,会坑了自己.所以,在还没有真正的去了解它们之前,还是慎用比较好. 下面 ...