Spring Data JPA中有一对一,一对多,多对多等关系映射,本次主要学习一对一关系映射。
一对一关系映射在生活中十分常见。例如一个大学生只有一张一卡通,一张一卡通只属于一个大学生。再如人与身份z的关系也是一对一。
在Spring Data JPA中,可用两种方式描述一对一映射关系,一种是通过外键的方式,即一个实体通过外键关联到另一个实体,另一种是通过关联表来保存两个实体一对一的关系映射。
下面学习使用Spring Data JPA实现人与身份z的一对一关系映射。
1-创建基于Spring Data JPA的SpringBoot Web应用,并在MySQL中创建名为springbootjpa的数据库。
2-在pom.xml文件中添加相关依赖。
4.0.0 org.example ch6_11.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent2.1.4.RELEASE org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-thymeleaforg.springframework.boot spring-boot-starter-data-jpamysql mysql-connector-java5.1.45 org.springframework.boot spring-boot-starter-jdbcorg.springframework.boot spring-boot-starter-testtest
3-在配置文件application.properties中配置数据源。
server.port=8080 #数据源信息配置 spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=utf8&useSSL=false #数据库用户名 spring.datasource.username = root #数据库密码 spring.datasource.password = 123456 #数据库驱动 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #指定数据库类型 spring.jpa.database = MYSQL #指定是否在日志中显示SQL语句 spring.jpa.show-sql = true #指定自动创建,更新数据库表等配置 spring.jpa.hibernate.ddl-auto = update #让控制器输出JSON字符串格式更美观 spring.jackson.serialization.indent-output = true #上传文件时候,默认上传文件大小是1MB,max-file-size设置单个文件上传大小 spring.servlet.multipart.max-file-size=50MB #默认总文件大小为10MB,max-request-size设置总上传文件的大小 spring.servlet.multipart.max-request-size=500MB
4-在src/main/java目录下创建com.entity包,在该包中创建名为Person和IdCard的持久化类。
Person类:
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import javax.persistence.*; import java.io.Serializable; @Entity @Table(name = "person_table") @JsonIgnoreProperties(value = {"hibernateLazyInitializer"}) public class Person implements Serializable { private static final long serialVersionUID = 1L ; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id ; private String pname ; private String psex ; private int page ; @OneToOne( optional = true , //身份z号可以为空,小孩子可以没有身份z号 fetch = FetchType.LAZY, //加载一个实体,不会立即从数据库中加载 targetEntity = IdCard.class, //与该实体类关联的目标实体类 cascade = CascadeType.ALL //同时选择级联新建、删除、刷新、更新 ) @JoinColumn( name = "id_Card_id", //指定Person表的id_Card_id列作为外键与IdCard表对应的id列进行关联 referencedColumnName = "id", //指定参考的主键 unique = true //指定id_Card_id列的值不可重复 ) @JsonIgnore private IdCard idCard ; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } public String getPsex() { return psex; } public void setPsex(String psex) { this.psex = psex; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } }
IdCard类:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import javax.persistence.*; import java.io.Serializable; import java.util.Calendar; @Entity @Table(name = "idcard_table") @JsonIgnoreProperties(value = {"hibernateLazyInitializer"}) public class IdCard implements Serializable { private static final long serialVersionUID = 1L ; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id ; //主键自动递增 private String code ; @Temporal(value = TemporalType.DATE) //指定日期格式 private Calendar birthday ; private String address ; @OneToOne( optional = false, //有身份z号的人必须存在,person不能为空 fetch = FetchType.LAZY,//加载一个实体,不会立即从数据库加载 mappedBy = "idCard",//与Person类的idCard属性一致 cascade = CascadeType.ALL //同时进行级联新建、删除、刷新、更新 ) private Person person ; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Calendar getBirthday() { return birthday; } public void setBirthday(Calendar birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
上述实体类中,@OneToOne注解有5个属性:targetEntity,cascade,fetch,optional,mappedBy.
targetEntity属性:定义关系类的类别。
cascade属性:定义类与类别之间的级联关系。定义的级联关系将被容器视作为对当前类对象及其关联的对象采取相同的 *** 作。CascadeType.ALL 表示同时进行级联新建、删除、刷新、更新。
fetch属性:分为两种,FetchType.LAZY代表懒加载,即定义的属性不会立即从数据库中加载,FetchType.EAGER为急加载,定义的属性会立即从数据库中加载。
optional属性:为true时,表示对应类的属性可以为空,反之,不能为空。
mappedBy属性:一定是定义在关系的被维护端,指向关系的维护端。
5-在src/main/java目录下创建数据com.repository包,在该包中创建两个接口并继承JpaRepository接口,实现数据访问层。
import com.entity.IdCard; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface IdCardRepository extends JpaRepository{ //根据人员id查询身份信息 public IdCard findByPerson_id(Integer id) ; //根据地址和身份z号码查询身份信息 public List findByAddressAndCode(String address, String code) ; }
import com.entity.Person; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface PersonRepository extends JpaRepository{ //根据身份ID查询人员信息 public Person findByIdCard_id(Integer id) ; //根据人名和性别查询人员信息 public List findByPnameAndPsex(String pname, String psex) ; }
6-在src/main/java目录下创建com.service包,该包为业务层,在该包中创建业务层的接口和接口的实现类。
import com.entity.IdCard; import com.entity.Person; import java.util.List; public interface PersonAndIdCardService { public void saveAll() ; public ListfindAllPerson() ; public List findAllIdCard() ; public IdCard findByPerson_id(Integer id) ; public List findByAddressAndCode(String address, String code) ; public Person findByIdCard_id(Integer id) ; public List findByPnameAndPsex(String pname, String psex) ; public IdCard getOneIdCard(Integer id) ; public Person getOnePerson(Integer id) ; }
import com.entity.IdCard; import com.entity.Person; import com.repository.IdCardRepository; import com.repository.PersonRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Calendar; import java.util.List; @Service public class PersonAndIdCardServiceImpl implements PersonAndIdCardService { @Autowired private IdCardRepository idCardRepository ; @Autowired private PersonRepository personRepository ; @Override public void saveAll() { //先保存身份z,身份z实体是被维护端 IdCard idCard = new IdCard() ; idCard.setCode("123456789"); idCard.setAddress("南昌"); Calendar calendar = Calendar.getInstance() ; calendar.set(2021, 11, 11) ; idCard.setBirthday(calendar); IdCard idCard1 = new IdCard() ; idCard1.setCode("1111111111"); idCard1.setAddress("南京"); Calendar calendar1 = Calendar.getInstance() ; calendar1.set(2021, 11, 12) ; idCard1.setBirthday(calendar1); IdCard idCard2 = new IdCard() ; idCard2.setCode("222222222"); idCard2.setAddress("杭州"); Calendar calendar2 = Calendar.getInstance() ; calendar2.set(2021, 11, 13) ; idCard2.setBirthday(calendar2); ListidCards = new ArrayList<>() ; idCards.add(idCard) ; idCards.add(idCard1) ; idCards.add(idCard2) ; idCardRepository.saveAll(idCards) ; //保存人员 Person p1 = new Person() ; p1.setPname("王国栋"); p1.setPsex("男"); p1.setPage(24); p1.setIdCard(idCard); Person p2 = new Person() ; p2.setPname("何卓忆"); p2.setPsex("女"); p2.setPage(20); p2.setIdCard(idCard1); Person p3 = new Person() ; p3.setPname("唐乃乔"); p3.setPsex("男"); p3.setPage(24); p3.setIdCard(idCard2); List persons = new ArrayList<>() ; persons.add(p1) ; persons.add(p2) ; persons.add(p3) ; personRepository.saveAll(persons) ; } @Override public List findAllPerson() { return personRepository.findAll(); } @Override public List findAllIdCard() { return idCardRepository.findAll(); } @Override public IdCard findByPerson_id(Integer id) { return idCardRepository.findByPerson_id(id); } @Override public List findByAddressAndCode(String address, String code) { return idCardRepository.findByAddressAndCode(address,code); } @Override public Person findByIdCard_id(Integer id) { return personRepository.findByIdCard_id(id); } @Override public List findByPnameAndPsex(String pname, String psex) { return personRepository.findByPnameAndPsex(pname, psex); } @Override public IdCard getOneIdCard(Integer id) { return idCardRepository.getOne(id); } @Override public Person getOnePerson(Integer id) { return personRepository.getOne(id); } }
7-在src/main/java目录下创建com.controller包,在该包中创建控制器类。
import com.entity.IdCard; import com.entity.Person; import com.service.PersonAndIdCardService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class TestOneToOneController { @Autowired private PersonAndIdCardService personAndIdCardService ; @RequestMapping("/save1") public String save(){ personAndIdCardService.saveAll(); return "人员和身份保存成功!" ; } @RequestMapping("/findAllPerson") public ListfindAllPerson(){ return personAndIdCardService.findAllPerson() ; } @RequestMapping("/findAllIdCard") public List findAllIdCard(){ return personAndIdCardService.findAllIdCard() ; } //根据人员ID查询身份信息 @RequestMapping("/findByPerson_id") public IdCard findByPerson_id(Integer id){ return personAndIdCardService.findByPerson_id(id) ; } @RequestMapping("/findByAddressAndCode") public List findByAddressAndCode(String address, String code){ return personAndIdCardService.findByAddressAndCode(address, code) ; } //根据身份zID查询人员信息 @RequestMapping("/findByIdCard_id") public Person findByIdCard_id(Integer id){ return personAndIdCardService.findByIdCard_id(id) ; } @RequestMapping("/findByPnameAndPsex") public List findByPnameAndPsex(String pname, String psex){ return personAndIdCardService.findByPnameAndPsex(pname, psex) ; } @RequestMapping("/getOneIdCard") public IdCard getOneIdCard(Integer id){ return personAndIdCardService.getOneIdCard(id) ; } @RequestMapping("/getOnePerson") public Person getOnePerson(Integer id){ return personAndIdCardService.getOnePerson(id) ; } }
8-在src/main/java/com目录下创建启动类,并运行。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args) ; } }
9-访问http://localhost:8080/save
完成保存数据,查看数据库数据如下:
10-测试相关查询
(1)查询身份zid为1的人员信息
(2)查询人员id为1的身份信息
(3)查询所有的人员信息
(4)查询所有的身份信息
剩下的查询自行测试,本次不再演示。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)