标签:
环境: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<>();
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public User() {
}
public User(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
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; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } }
需要注意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<>();
// public String getRole() {
// return role;
// }
//
// public void setRole(String role) {
// this.role = role;
// }
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public User() {
}
public User(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
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;
// }
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
这样就可以了。
测试:
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");
// roleDao.save(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 两种例子
标签:
原文地址:http://www.cnblogs.com/csonezp/p/5593568.html