SpringDataJpa一对一实体关系

SpringDataJpa一对一实体关系


前言

案例Github地址(可以用git clone 到本地) https://github.com/chenxiban/SpringDataJpa-One-To-One.git

今天为大家分享:SpringDataJpa一对一实体关系。

前面讲了SpringDataJpa自定义查询语句(JPQL),请查看博主的SpringDataJpa系列文章。欢迎关注!


一对一实体关系

在项目开发过程中,我们也会经常遇到两表之间是一对一的映射关系(比如:客户和身份证,课程和老师)。Spring Data Jpa 框架为我们提供了非常简单的处理操作(在实体类中添加相关的注解),接下来我们以springbootjpaonetoone数据库中的课程表和老师表为例进行演示,pom.xml文件,及属性配置文件application.properties与一对多关联关系一样,这里省略不写,具体如下:

1.新建实体类

在com.cyj.springboot.entity下,编写实体如下:

package com.cyj.springboot.entity;

import java.io.Serializable;
import java.math.BigDecimal;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "coursetb")
public class Course implements Serializable {

	@Id // 实体类主键
	@OrderBy // 数据加载排序字段
	@GeneratedValue // 自动增长列
	@Column(columnDefinition = "int unsigned NOT NULL comment '备注:课程自动增长主键'  ") // 自定义字段类型
	private Integer courseId;

	@Column(length = 20) // 字符长度20
	private String courseName;
//	@Column(columnDefinition="decimal(5,2)  ")	//自定义字段类型:5位有效数字,小数点后保留2位
	@Column(precision = 5, scale = 2) // 5位有效数字,小数点后保留2位
	private BigDecimal coursePrice;
	@Transient // 临时参数,不映射到数据库表字段
	private String courseParam;
	@JsonIgnore
	// mappedBy配置映射关系:映射到当前Teacher对象的哪个字段course
	// //外键所在的表为副表,在主表上设置级联规则cascade,即设置了cascade属性的表没有外键;没有设置cascade属性的表会建外键
//	@OneToOne(optional = false, mappedBy = "course", cascade = CascadeType.ALL, fetch = FetchType.EAGER)		//optional是否可以为空
	@OneToOne(fetch = FetchType.EAGER) // 默认值optional = true表示是否可以为空
	@JoinColumn(name = "course_teacher_id", unique = true)  副表中的外键字段名称 // unique=true确保了一对一关系
	private Teacher teacher;

	// ----------------------------- 以下是构造方法 ------------------------

	// ----------------------------- 以下是Getter和setter方法 ------------------------
	public Integer getCourseId() {
		return courseId;
	}

	public void setCourseId(Integer courseId) {
		this.courseId = courseId;
	}

	public String getCourseName() {
		return courseName;
	}

	public void setCourseName(String courseName) {
		this.courseName = courseName;
	}

	public BigDecimal getCoursePrice() {
		return coursePrice;
	}

	public void setCoursePrice(BigDecimal coursePrice) {
		this.coursePrice = coursePrice;
	}

	public String getCourseParam() {
		return courseParam;
	}

	public void setCourseParam(String courseParam) {
		this.courseParam = courseParam;
	}

	/**
	 * 把课程所属教师名称设置到临时参中
	 */
	public void setCourseParam() {
		this.courseParam = teacher.getTeacherName();// 把课程所属教师名称设置到临时参中
	}

	public Teacher getTeacher() {
		return teacher;
	}

	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}

	// ----------------------------- 以下是重写的toString方法 ------------------------

	@Override
	public String toString() {
		return "Course [courseId=" + courseId + ", courseName=" + courseName + ", coursePrice=" + coursePrice
				+ ", courseParam=" + courseParam + "]";
	}

	public String showCourseAndTeacher() {
		return "Course [courseId=" + courseId + ", courseName=" + courseName + ", coursePrice=" + coursePrice
				+ ", courseParam=" + courseParam + ", teacher=" + teacher + "]";
	}

}

教师实体

package com.cyj.springboot.entity;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "teachertb")
public class Teacher implements Serializable {

	@Id // 实体类的主键
	@GeneratedValue // 自动增长列
	@OrderBy // 数据加载顺序
	@Column(columnDefinition = "int unsigned NOT NULL comment '备注:教师自动增长主键'  ")
	private Integer teacherId;
	@Column(length = 20) // 字符长度20
	private String teacherName;
	@Column(columnDefinition = "char(1) comment '备注:教师姓名' ")
	private String teacherSex;
	@Column(columnDefinition = "int unsigned DEFAULT 0 comment '备注:教师年龄'  ")
	private Integer teacherAge;

	private Date teacherBirthday;
//	@CreationTimestamp@UpdateTimestamp	//插入,修改时自动维护时间戳
	@Column(columnDefinition = "TIMESTAMP", nullable = false, updatable = false, insertable = false)
	private Timestamp teacherTime;
	@Transient // 临时参数,不映射到数据库表字段
	private String teacherParam;

	@JsonIgnore
	// mappedBy配置映射关系:映射到当前Teacher对象的哪个字段course
	// //外键所在的表为副表,在主表上设置级联规则cascade,即设置了cascade属性的表没有外键;没有设置cascade属性的表会建外键
//	@OneToOne(optional = false,mappedBy="teacher", fetch = FetchType.LAZY)		// 默认值optional = true表示是否可以为空
	@OneToOne(optional = false, mappedBy = "teacher", cascade = CascadeType.ALL, fetch = FetchType.EAGER) // 不建外键
																											// //optional是否可以为空
//	@OneToOne(fetch = FetchType.EAGER)		// 默认值optional = true表示是否可以为空
	@JoinColumn(name = "teacher_course_id", unique = true)  副表中的外键字段名称 // unique=true确保了一对一关系
	private Course course;

	// ----------------------------- 以下是构造方法 ------------------------

	// ----------------------------- 以下是Getter和setter方法 ------------------------
	public Integer getTeacherId() {
		return teacherId;
	}

	public void setTeacherId(Integer teacherId) {
		this.teacherId = teacherId;
	}

	public String getTeacherName() {
		return teacherName;
	}

	public void setTeacherName(String teacherName) {
		this.teacherName = teacherName;
	}

	public String getTeacherSex() {
		return teacherSex;
	}

	public void setTeacherSex(String teacherSex) {
		this.teacherSex = teacherSex;
	}

	public Integer getTeacherAge() {
		return teacherAge;
	}

	public void setTeacherAge(Integer teacherAge) {
		this.teacherAge = teacherAge;
	}

	public Date getTeacherBirthday() {
		return teacherBirthday;
	}

	public void setTeacherBirthday(Date teacherBirthday) {
		this.teacherBirthday = teacherBirthday;
	}

	public Timestamp getTeacherTime() {
		return teacherTime;
	}

	public void setTeacherTime(Timestamp teacherTime) {
		this.teacherTime = teacherTime;
	}

	public String getTeacherParam() {
		return teacherParam;
	}

	public void setTeacherParam(String teacherParam) {
		this.teacherParam = teacherParam;
	}

	/**
	 * 把教师所教课程名称设置到临时参数中
	 */
	public void setTeacherParam() {
		this.teacherParam = course.getCourseName();// 把教师所教课程名称设置到临时参数中
	}

	public Course getCourse() {
		return course;
	}

	public void setCourse(Course course) {
		this.course = course;
	}

	// ----------------------------- 以下是重写的toString方法 ------------------------

	@Override
	public String toString() {
		return "Teacher [teacherId=" + teacherId + ", teacherName=" + teacherName + ", teacherSex=" + teacherSex
				+ ", teacherAge=" + teacherAge + ", teacherBirthday=" + teacherBirthday + ", teacherTime=" + teacherTime
				+ ", teacherParam=" + teacherParam + "]";
	}

	public String showTeacherAndCourse() {
		return "Teacher [teacherId=" + teacherId + ", teacherName=" + teacherName + ", teacherSex=" + teacherSex
				+ ", teacherAge=" + teacherAge + ", teacherBirthday=" + teacherBirthday + ", teacherTime=" + teacherTime
				+ ", teacherParam=" + teacherParam + ", course=" + course + "]";
	}

}

(注:一对一关系的实体,其实外键建在哪个表中都可以。通过 @OneToOne 注解中有没有设置cascade属性来
确定主表和从表,设置了cascade属性的表没有外键即为主表,没有设置cascade属性的表会建外键即为从表,本
例中coursetb是主表。)

2.新建 dao类

com.cyj.springboot.dao,代碼如下:

package com.cyj.springboot.dao;

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

import com.cyj.springboot.entity.Course;

public interface CourseRepository extends JpaRepository<Course, Integer> {

}

教师Dao

在com.cyj.springboot.dao下,代码如下:

package com.cyj.springboot.dao;

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

import com.cyj.springboot.entity.Teacher;

public interface TeacherRepository extends JpaRepository<Teacher, Integer> {

}
3.新建service接口

com.cyj.springboot.dao,编写业务逻辑接口,代碼如下:

package com.cyj.springboot.service;

import com.cyj.springboot.entity.Course;

public interface CourseService {

	public Course queryById(Integer id);

}

教师接口

package com.cyj.springboot.service;

import com.cyj.springboot.entity.Teacher;

public interface TeacherService {

	public Teacher queryById(Integer id);

}

在com.cyj.springboot.ServiceImpl下,编写业务逻辑实现层,代码如下:

package com.cyj.springboot.ServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cyj.springboot.dao.CourseRepository;
import com.cyj.springboot.entity.Course;
import com.cyj.springboot.service.CourseService;

@Service
public class CourseServiceImpl implements CourseService {

	@Autowired
	private CourseRepository repository;

	@Override
	public Course queryById(Integer id) {
		return repository.findOne(id);
	}

}

教师接口实现

package com.cyj.springboot.ServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cyj.springboot.dao.TeacherRepository;
import com.cyj.springboot.entity.Teacher;
import com.cyj.springboot.service.TeacherService;

@Service
public class TeacherServiceImpl implements TeacherService{
	
	@Autowired
	private TeacherRepository repository;

	@Override
	public Teacher queryById(Integer id) {
		return repository.findOne(id);
	}

}
4.编写controller层

在com.cyj.springboot.controller编写CourseController控制器,如下:

package com.cyj.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cyj.springboot.entity.Course;
import com.cyj.springboot.service.CourseService;

/**
 * SpringMVC控制器
 * 
 * @Description: 子模块
 * @author ChenYongJia
 * @Date 2017-10-4 下午8:04:34
 * @Email 867647213@qq.com
 */

@RestController
@RequestMapping("/course")
public class CourseController {

	@Autowired
	private CourseService service;

	/**
	 * http://localhost:8080/course/queryById?id=1
	 * 
	 * @param id
	 * @return User
	 */
	@RequestMapping("/queryById")
	public Course queryById(Integer id) {
		Course course = service.queryById(id);
		course.setCourseParam();
		System.out.println("queryById user=>" + course.showCourseAndTeacher());
		return course;
	}

}

教师控制器

package com.cyj.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cyj.springboot.entity.Teacher;
import com.cyj.springboot.service.TeacherService;

/**
 * SpringMVC控制器
 * @Description:   子模块
 * @author         ChenYongJia 
 * @Date           2017-10-4 下午8:04:34  
 * @Email          867647213@qq.com
 */
@RestController
@RequestMapping("/teacher")
public class TeacherController {
	
	@Autowired	
	private TeacherService service;
	
	/**
	 * http://localhost:8080/teacher/queryById?id=1
	 * @param id
	 * @return User
	 */
	@RequestMapping("/queryById")
	public Teacher queryById(Integer id) {
		Teacher teacher = service.queryById(id);
		teacher.setTeacherParam();
		System.out.println("queryById teacher=>"+teacher.showTeacherAndCourse());
		return teacher;
	}
	
}
5.编写项目主类
package com.cyj.springboot;

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;

/**
 * Spring Boot 应用启动类
 * 
 * @Description: 主模块
 * @ClassName: Application.java
 * @author ChenYongJia
 * @Date 2017-10-4 下午8:03:41
 * @Email 867647213@qq.com
 */
@EnableJpaRepositories(basePackages = "com.cyj.springboot.dao") // Spring Jpa 启用注解
@EntityScan(basePackages = "com.cyj.springboot.entity") // 扫描Jpa实体对象
@SpringBootApplication // Spring Boot 应用的标识
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);// 程序启动入口 启动嵌入式的 Tomcat 并初始化 Spring 环境及其各 Spring 组件
	}
}
6.数据库设计如下(.sql文件在static文件下)

在这里插入图片描述

7.项目测试

启动项目,分别访问教师和课程信息,如下图所示:

在这里插入图片描述

在这里插入图片描述


好了到这里也该结束了,各位要自己多动手才能学到真正的东西。加油各位


最后

  • 更多参考精彩博文请看这里:《陈永佳的博客》

  • 喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈永佳

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值