stuEntities = new HashSet<>();
```
## 多对多
> 实体类设置
在多对多的测试中, 考虑的是一个用户拥有多个角色、一个角色拥有多个用户,并且做了一个用户
角色
```java
@Id
@Column(name = "role_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long roleId;
private String roleName;
private String remark;
private Long createUserId;
private Timestamp createTime;
/**
* 中间表名
*
* 当前对象在中间表的外键
* 对方在中间表的外键
*/
@JoinTable(name = "sys_user_role",
joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "role_id")},
inverseJoinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "user_id")})
// @ManyToMany(targetEntity = SysUserEntity.class, cascade = CascadeType.ALL)
@ManyToMany(mappedBy = "roleEntities", cascade = CascadeType.ALL)
private Set userEntitySet = new HashSet<>();
```
用户
```java
@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long userId;
private String username;
private String password;
private String salt;
private String email;
private String mobile;
private Byte status;
private Long createUserId;
// 自动填充时间
@CreatedDate
private Timestamp createTime;
/**
* 中间表名
*
* 当前对象在中间表的外键
* 对方在中间表的外键
*/
@JoinTable(name = "sys_user_role",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "role_id")})
@ManyToMany(targetEntity = SysRoleEntity.class, cascade = CascadeType.ALL)
private Set roleEntities = new HashSet<>();
```
中间表
```java
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private long id;
private Long roleId;
private Long userId;
```
> 测试
```java
@GetMapping("/manyTomany")
public R manyTomany() {
SysUserEntity userEntity = new SysUserEntity();
userEntity.setUsername("测试2").setEmail("1721310909@qq.com");
SysUserEntity userEntity2 = new SysUserEntity();
userEntity2.setUsername("测试3").setEmail("1721310909@qq.com");
SysRoleEntity roleEntity2 = new SysRoleEntity();
roleEntity2.setRoleName("管理1").setRemark("测试");
SysRoleEntity roleEntity = new SysRoleEntity();
roleEntity.setRoleName("管理2").setRemark("测试");
// 设置关系
userEntity.getRoleEntities().add(roleEntity);
userEntity.getRoleEntities().add(roleEntity2);
roleEntity.getUserEntitySet().add(userEntity2);
roleEntity.getUserEntitySet().add(userEntity);
userRepository.save(userEntity);
roleRepository.save(roleEntity);
return R.ok();
}
```
测试级联操作
```java
@ApiOperation("级联删除操作")
@GetMapping("/manyTomany4")
public R manyTomany4() {
//1、 查出 角色
SysRoleEntity one = roleRepository.getOne(9L);
//2、 删除角色
roleRepository.delete(one);
return R.ok();
}
```
## 常用的注解
### 标注在类上
> @DynamicInsert
再插入数据的时候动态生成的sql中只包含要插入字段的部分, 其他的内容不会一起产生。
> @DynamicUpdate
再更新数据的时候动态生成的sql中只包含要更新字段的部分, 其他的内容不会一起产生。
### 标注在字段上面
> Column
```java
/**
数据库表上的字段名字
*/
String name() default "";
/**
标明这个是唯一标识
*/
boolean unique() default false;
/**
标明这个是可以为空的
*/
boolean nullable() default true;
/**
在动态的插入sql中会产生个片段
*/
boolean insertable() default true;
/**
在动态的更新sql中会产生个片段
*/
boolean updatable() default true;
/**
* (Optional) The SQL fragment that is used when
* generating the DDL for the column.
创建表的时候会创建这个字段的sql
*/
String columnDefinition() default "";
/**
包含列的表的名称。
*/
String table() default "";
/**
这个字段的长度
*/
int length() default 255;
/**
字段的精度
*/
int precision() default 0;
```
### 标注在方法上面
> @PrePersist
再插入实体之前可以做的一个回调事件, 比如可以添加创建时间、指定字段的默认值等。
> @PreUpdate
再插入更新之前可以做的一个回调事件, 比如: 可以实现修改时间。
```java
@PrePersist
public void prePersist() {
this.createdAt = this.updatedAt = new Timestamp(System.currentTimeMillis());
}
@PreUpdate
public void preUpdate() {
this.updatedAt = new Timestamp(System.currentTimeMillis());
}
```
**@PrePersist- 在新实体持久化之前(添加到EntityManager)
@PostPersist- 在数据库中存储新实体(在commit或期间flush)
@PostLoad - 从数据库中检索实体后。
@PreUpdate- 当一个实体被识别为被修改时EntityManager
@PostUpdate- 更新数据库中的实体(在commit或期间flush)
@PreRemove - 在EntityManager中标记要删除的实体时
@PostRemove- 从数据库中删除实体(在commit或期间flush)**
## 码云仓库
```bash
https://gitee.com/yu_tian_shui/spring-data-jpa-study
```
[码云仓库](https://gitee.com/yu_tian_shui/spring-data-jpa-study)