jpa创建数据库表
一对多关系
1、创建实体类user以及department,一个department里面有多个user,代码如下
package com.example.springbootjpatest.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.ToString;
import lombok.Value;
import javax.management.relation.Role;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import java.util.List;
/**
* @author xyn
* @version 1.0
* @date 2021/8/5 15:48
*/
@Entity
@Data
@ToString
public class User {
@Id
private Integer id;
private String name;
private Integer age;
private String address;
private Integer sex;
private Boolean isActive;
/**
* @jsonIngnoreProperties
* 此注解防止进入死循环,如若未加这个循环,便会进入无限循环,直到堆内存溢出
*/
@ManyToOne
@JsonIgnoreProperties("users")
private Department department;
}
package com.example.springbootjpatest.entity;
import lombok.Data;
import lombok.Value;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import java.util.List;
/**
* @author xyn
* @version 1.0
* @date 2021/8/5 15:51
*/
@Entity
@Data
public class Department {
@Id
private Integer id;
private String name;
/**
* 添加mapperBy指向多的字段属性,防止产生中间表。如果不指向该属性,则会产生中间表
* department_user,分别对应user表以及department的外键关系
*/
@OneToMany(mappedBy = "department")
private List<User> users;
}
2、创建完对象之后,启动项目,jpa就会自动帮你生成表结构,
多对多关系
在前面用户的基础,加一个role表,user跟role是多对多的关系,即一个用户有多个角色,一个角色也有多个用户,此时需要创建一个中间表去维护。
role实体类如下:
package com.example.springbootjpatest.entity;
import lombok.Data;
import org.springframework.boot.origin.OriginTrackedValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import java.util.List;
/**
* @author xyn
* @version 1.0
* @date 2021/8/6 9:20
*/
@Entity
@Data
public class Role {
@Id
private Integer id;
private String roleName;
/**
* 角色备注
*/
private String roleDescription;
/**
* 与用户是多对多的关系
* mapperBy指向user中的字段roles
*/
@ManyToMany(mappedBy = "roles")
private List<User> users;
}
在原来user的基础上,加多一个roles,代码如下
package com.example.springbootjpatest.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.ToString;
import lombok.Value;
import javax.persistence.*;
import java.util.List;
/**
* @author xyn
* @version 1.0
* @date 2021/8/5 15:48
*/
@Entity
@Data
@ToString
public class User {
@Id
private Integer id;
private String name;
private Integer age;
private String address;
private Integer sex;
private Boolean isActive;
/**
* @jsonIngnoreProperties
* 此注解防止进入死循环,如若未加这个循环,便会进入无限循环,直到堆内存溢出
*/
@ManyToOne
@JsonIgnoreProperties("users")
private Department department;
/**
* 加上 @ManyToMany的代码
* @joinTable表明创建中间表,
* joinColumns表明自己字段,里面包含一个@joinColumn表明自己的关联主键
* inverseJoinColumns表明其他表的外键,通过@joinColumn加入
*/
@ManyToMany
@JoinTable(
name = "user_role",
joinColumns = {
@JoinColumn(name = "user_id",referencedColumnName = "id")
},
inverseJoinColumns = {
@JoinColumn(name = "role_id",referencedColumnName = "id")
}
)
@JsonIgnoreProperties(value = { "users" })
private List<Role> roles;
}
至此,表的结果创建完毕,此时启动项目,数据库表自动创建
role表:
中间表user_role:
一对一关系
一对一关系比较简单,所以放在最后来说明
首先还是我们的user类,我们在user类里面加一个City并标上@onetoone注解,表示一对一关系。创建实体类City,注明属性
package com.example.springbootjpatest.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
* @author xyn
* @version 1.0
* @date 2021/8/6 10:55
*/
@Entity
@Data
public class City {
@Id
private Integer id;
/**
* 城市名字
*/
private String name;
}
User类变化为:
package com.example.springbootjpatest.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.ToString;
import lombok.Value;
import javax.persistence.*;
import java.util.List;
/**
* @author xyn
* @version 1.0
* @date 2021/8/5 15:48
*/
@Entity
@Data
@ToString
public class User {
@Id
private Integer id;
private String name;
private Integer age;
private String address;
private Integer sex;
private Boolean isActive;
/**
* @jsonIngnoreProperties
* 此注解防止进入死循环,如若未加这个循环,便会进入无限循环,直到堆内存溢出
*/
@ManyToOne
@JsonIgnoreProperties("users")
private Department department;
/**
* 加上 @ManyToMany的代码
* @joinTable表明创建中间表,
* joinColumns表明自己字段,里面包含一个@joinColumn表明自己的关联主键
* inverseJoinColumns表明其他表的外键,通过@joinColumn加入
*/
@ManyToMany
@JoinTable(
name = "user_role",
joinColumns = {
@JoinColumn(name = "user_id",referencedColumnName = "id")
},
inverseJoinColumns = {
@JoinColumn(name = "role_id",referencedColumnName = "id")
}
)
@JsonIgnoreProperties(value = { "users" })
private List<Role> roles;
/**
* 添加城市,表示一对一关系
*/
@OneToOne
@JoinColumn(name = "city_id")
private City city;
}
启动项目,生成表为:
city表:
进行增删改查操作
前面已经将表创建出来了,那现在就要进行相应的表的操作了
这里便是jpa不同于mybatis的地方(前面创建表也不同,通过实体创建表),因为差不多相同的原理,所以这里拿一个进行讲解
增加
@PostMapping("/save/user")
private String saveUser(@RequestBody User user) {
userDao.save(user);
return "success";
}
此时我在postman进行请求:
请求时传入role表的id值,以及department表的id值,jpa便会自动帮你维护第三张表以及多对多的关系,此时表的数据为:
帮你自动关联上去
前提是role中有这个id,否则会报错,插入异常
查询
针对刚刚增加的用户进行查询,查询代码如下:
@GetMapping("/testJpa")
private List<Department> test() {
List<Department> all = departmentDao.findAll();
return all;
}
我是根据部门查的,也是为了展示jpa的强大之处,可以自动帮你查询出你要关联的对象,自动封装好给你返回
修改
修改也是通过save方法,根据用户的主键自动帮你更新数据,维护中间表
postman请求如下:
我们将用户与角色关联去掉,此时,数据库第三张表(user_role)自动更新
缺点:当字段为空的时候不能够向mybatis一样保留数据库原来的值
删除
为了方便展示jpa的强大之处,先将用户角色关联上
此时通过如下代码进行用户的删除
@DeleteMapping("/delete/user")
private String deleteUser(){
userDao.deleteById(1);
return "success";
}
删除成功,同时,user_role中的用户角色也删除掉了
对比mybatis
在增删改查方面,jpa有很多优于mybatis的地点,特别是对于一对多,多对多关系的时候,不用自己去维护中间关联表,jpa会自动根据你的对象帮你自动管理这个中间表,查询的时候也会自动帮你封装成对象里面一对多的对象关系。
引用网上的说法就是:Spring Data JPA与MyBatis对比,起始也就是hibernate与MyBatis对比。所以,我们直接来比较后两者。hibernate是一个自动化更强、更高级的框架,毕竟在java代码层面上,省去了绝大部分sql编写,取而代之的是用面向对象的方式操作关系型数据库的数据。而MyBatis则是一个能够灵活编写sql语句,并将sql的入参和查询结果映射成POJOs的一个持久层框架。所以,从表面上看,hibernate能方便、自动化更强,而MyBatis 在Sql语句编写方面则更灵活自由。