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.项目测试
启动项目,分别访问教师和课程信息,如下图所示:
好了到这里也该结束了,各位要自己多动手才能学到真正的东西。加油各位
最后
-
更多参考精彩博文请看这里:《陈永佳的博客》
-
喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/97631.html