SpringBoot-Spring Data Jpa 级联操作 多对一 遍历,数据插入
-
实体类
- 本操作是多(User)对一(Role)操作,以User为主体对象
- 无参构造器一定要保留
- 在实体类中不要重写toString方法,会带来很多不必要的麻烦(毕竟项目中都输传值,不会在控制台搞事情)
- 对应实体类的表主键是自增的,否则要手动set ID
- User(主体实体类)
- 注意@Entity·@Id @GeneratedValue @ManyToOne 和 @JoinColumn联用
- @ManyToOne 和 @JoinColumn联用 标示,多对一关系,User 用外键 role_id 关联 Role
package com.chen.jap.model;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Entity
@Table(name = "user")//如果对象属性和数据库表名不一致,用来标示
public class User implements Serializable {
private static final long serialVersionUID = 4122384962907036649L;
@Id // 表明id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自动生成,检测最大值自增
@Column(name = "id", length = 100)//如果对象属性和数据库字段不一致,用来标示
private Long id;
private String username;
private String password;
private Integer age;
private String sex;
@ManyToOne
@JoinColumn(name = "role_id")//指定当前实体外键
private Role role;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
-
Role(副实体类)
-
注意@Entity·@Id @GeneratedValue @OneToMany 和其中的属性cascade
-
-
package com.chen.jap.model; import javax.persistence.*; import java.io.Serializable; import java.util.List; @Entity @Table(name = "role") public class Role implements Serializable { private static final long serialVersionUID = 4122384962907036647L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id",length = 100) private Integer id; private String name; @OneToMany(cascade = CascadeType.ALL,mappedBy = "role") private List<User> users; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } }
-
测试代码 级联查询
- 这里用的测试是 junit4 测试
-
@Repository public interface UserDAO extends JpaRepository<User,Long> { //接口内,只写自定义代码就好,一般的CRUD在JpaRepository都已被继承 }
-
@Test public void findAll() { List<User> all = this.dao.findAll(); Iterator<User> it = all.iterator(); while (it.hasNext()) { User user = it.next(); System.out.println(user.toString()); System.out.println(user.getRole().toString()); } }
-
运行结果
-
错误示范
- 注意这里是在JpaRepository泛型中给的是Role,也就是说,以Role为主体
-
@Repository public interface RoleDAO extends JpaRepository<Role,Integer> { }
-
@Test public void findAll2() { List<Role> all = this.roleDAO.findAll(); Iterator<Role> it = all.iterator(); while (it.hasNext()) { Role role = it.next(); Iterator<User> iterator = role.getUsers().iterator(); while (iterator.hasNext()) System.out.println(iterator.next()); } }
-
运行结果
- 我们配置的对象关系是以User为主体单项关系, 这里这样操作只能获取Role信息,User是没有数据的
-
测试代码 级联插入
- 如果只把User装进Role,运行后只插入了Role数据
- 如果只把Role装进了User,插入两条,但是关联的外键字段是空的,也就是说关联失败
-
@Test public void save() { User user = new User(); user.setUsername("testMax"); user.setPassword("9696"); user.setSex("女"); user.setAge(99); Role role = new Role(); role.setName("testMax"); ArrayList<User> users = new ArrayList<>(); users.add(user); //对象互装环节 role.setUsers(users); user.setRole(role); Role save = this.roleDAO.save(role); System.out.println(save.toString()); }
-
运行结果
- 以上注意了,这里是在DAO接口中泛型给的Role,也就是说以Role为主体
- 如果以User为主体,插入失败,外键约束,Session状态
Chenyb 随笔记录,只为方便自己学习
2019-04-05