Spring 一对一

1 概述
在管理系统中,实体之间的关系从来都是复杂的。常见的有一对一,一对多,多对多等关系,这些关系组成了复杂的实体关系,得以完成现实中复杂的需求。

Spring Data JPA基于功能强大JPA规范,实现这些实体关系豪不费力。

2 实体关系
在这里插入图片描述

有两个实体,学校和地址,一个学校对应一个地址。它们的关系如上图。

在实体类中代码如下:

School.java

package com.wangshenghua.entity;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

@Entity
public class School {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

private String name;

@OneToOne(cascade = CascadeType.ALL) //级联操作
@JoinColumn(name = "address_id")  // 定义外键列
private Address address;
 
public School() {}

public School(String name, Address address) {
    this.name = name;
    this.address = address;
}
 
// Getter and Setter       

}
@OneToOne表示一对一关系,即一个学校对应一个地址。参数cascade 表示级联关系。级联关系有以下6类。

级联关系 说明
CascadeType.PERSIST 级联新增。 当School实体保存时, Address中实体也会保存。
CascadeType.REMOVE 级联删除操作。删除当前实体时,与它有映射关系的实体也会跟着被删除。
CascadeType.MERGE 级联更新(合并)操作。当School中的数据改变,会相应地更新Address中的数据。
CascadeType.DETACH 级联脱管/游离操作。
CascadeType.REFRESH 级联刷新操作。刷新 School 实体时,也会刷新 Address 实体。
CascadeType.ALL 拥有以上所有级联操作权限。
@JoinColumn表示指向一个外键,这里是 Address 实体的主键,即 School 实体中的address_id外键。

Address.java

package com.wangshenghua.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class Address {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

private String street;

private String zipCode;

@OneToOne(mappedBy = "address") 
private School School;
 
public Address() {}
 
// Getter and Setter       

}
参数mappedBy指向反向关系。一个学校对应一个地址,反过来,一个地址对应一个学校,mappedBy的值必为本类在另一方的属性名。

3 数据访问接口
以上两个实体的Spring Data JPA接口。

SchoolRepository.java

package com.wangshenghua.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.wangshenghua.entity.School;

public interface SchoolRepository extends JpaRepository<School, Integer> {

}
AddressRepository.java

package com.wangshenghua.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.wangshenghua.entity.Address;
public interface AddressRepository extends JpaRepository<Address, Integer> {
}
4 数据库连接配置
application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.237.131:3306/testdb?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=testdb
spring.datasource.password=testdb

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
数据库使用MySQL 5.1.73,在Spring boot工程的pom.xml依赖mysql-connector-java要换成低版本的,高版本的会报错。

mysql mysql-connector-java 5.1.38 5 驱动类 将驱动类和入口main函数写在一同一个类中,让 入口main函数所在类实例接口org.springframework.boot.CommandLineRunner可以让学员专注于JPA技术学习。

package com.wangshenghua.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import com.wangshenghua.dao.AddressRepository;
import com.wangshenghua.dao.SchoolRepository;
import com.wangshenghua.entity.Address;
import com.wangshenghua.entity.School;

@SpringBootApplication
@EnableJpaRepositories(basePackages = “com.wangshenghua.dao”)
@EntityScan(basePackages = “com.wangshenghua.entity”)
public class HibernateOneToOneMappingApplication implements CommandLineRunner{

@Autowired
private SchoolRepository schoolRepository; 
 
@Autowired
private AddressRepository addressRepository;
 
public static void main(String[] args) {
    SpringApplication.run(HibernateOneToOneMappingApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
    // 清除表
    schoolRepository.deleteAllInBatch();
    addressRepository.deleteAllInBatch();
     
     
    // 建立数据
    Address address = new Address();
    address.setStreet("郴州市南岭大道385号");
    address.setZipCode("423000");
     
    School school = new School("湘南IT",address);
     
    schoolRepository.save(school);
}

}
6 总结
JPA关系比较多,操作起来工作量也比大,学习时需要有耐心。Java体系庞大,若版本不在近一两年的框架搭配,可能会出现问题,排除这些问题不仅要基础知识扎实,还要细心。

本节课程源码已经上传到github,可以前往下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值