当前位置: 首页 > news >正文

沉默是金seo推广沧州公司电话

沉默是金,seo推广沧州公司电话,做网站套模板,高效完成网站建设的步骤SpringDataJpa一对多、多对一关系关联以及一对多多对一双向关联 前言 案例Github地址(可以用git clone 到本地) https://github.com/chenxiban/SpringBootJpa-One-To-Many.git 今天为大家分享:SpringDataJpa一对多、多对一关系关联以及一对多多对一双向关联。 前…

SpringDataJpa一对多、多对一关系关联以及一对多多对一双向关联


前言

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

今天为大家分享:SpringDataJpa一对多、多对一关系关联以及一对多多对一双向关联。

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


一对多实体关联关系

一对多是以一的一方为主,当我们对班级进行操作时会相应的级联到学生表,比如查询班级,自动会得到该班级下
的所有学生。

1.搭建项目,配置项目环境

2.配置pom

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ysd</groupId><artifactId>spring-boot-jap-one-to-many</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>spring-boot-jap-one-to-many</name><url>http://maven.apache.org</url><!-- Spring Boot 启动父依赖 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.1.RELEASE</version></parent><!-- 项目全局属性 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><mybatis-spring-boot>1.2.0</mybatis-spring-boot><mysql-connector>5.1.39</mysql-connector></properties><dependencies><!-- Spring Boot Web 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Test 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- Spring Boot devtools 热部署 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency><!-- Spring Boot JPA 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- MySQL 连接驱动依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql-connector}</version></dependency><!-- Junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies><!-- SpringBoot 项目发布 打jar包 依赖 --><build><plugins><!-- SpringBoot 项目发布 打jar包 依赖 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><!-- Maven test junit 报告中文UTF-8编码 插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.6</version><configuration><forkMode>once</forkMode><argLine>-Dfile.encoding=UTF-8</argLine></configuration></plugin></plugins></build>
</project>

3.配置yml属性文件(sql文件在static文件夹下)

spring: datasource: url: jdbc:mysql://localhost:3306/springbootjpaonetomany?useUnicode=true&characterEncoding=utf8username: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverjpa:database-platform: org.hibernate.dialect.MySQL5InnoDBDialect  #不加这句则默认为myisam引擎##运行时输出jpa执行的sql语句show-sql: true## spring-boot-starter-data-jpa自动映射创建表动作 配置: 有表更新,无表创建hibernate:ddl-auto: update#集中解决各种编码问题banner:charset: UTF-8http:encoding:charset: UTF-8enabled: trueforce: truemessages:encoding: UTF-8#     spring mvc 视图解析器mvc:view:prefix: /suffix: .html# 时间格式化jackson:date-format: yyyy-MM-dd HH:mm:ss# 时区设置time-zone: GMT+8

4.编写实体类

在com.cyj.springboot.entity下,编写class(班级)、student(学生)、代码如下:

package com.cyj.springboot.entity;import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;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.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;import com.fasterxml.jackson.annotation.JsonIgnore;@Entity
@Table(name = "clazztb")
public class Clazz implements Serializable {@Id // 实体类的主键@GeneratedValue // 自动增长列@Column(columnDefinition = "int unsigned NOT NULL comment '备注:班级自动增长主键'  ")private Integer clazzId;@Column(length = 10, unique = true)private String clazzName;@OrderBy@Column(columnDefinition = "int unsigned DEFAULT 0 comment '备注:班级总人数'  ")private Integer clazzNumber;//	@JsonIgnore@OneToMany(mappedBy = "clazz", fetch = FetchType.LAZY, cascade = CascadeType.ALL)private List<Student> list = new ArrayList<>();// ----------------------------- 以下是构造方法 ------------------------// ----------------------------- 以下是Getter和setter方法 -----------------public Integer getClazzId() {return clazzId;}public void setClazzId(Integer clazzId) {this.clazzId = clazzId;}public String getClazzName() {return clazzName;}public void setClazzName(String clazzName) {this.clazzName = clazzName;}public Integer getClazzNumber() {return clazzNumber;}public void setClazzNumber(Integer clazzNumber) {this.clazzNumber = clazzNumber;}public List<Student> getList() {return list;}public void setList(List<Student> list) {this.list = list;}// ----------------------------- 以下是重写的toString方法 ------------------------/** @Override public String toString() { return "Clazz [clazzId=" + clazzId +* ", clazzName=" + clazzName + ", clazzNumber=" + clazzNumber + "]"; }* * * public String showClazz() { return "Clazz [clazzId=" + clazzId +* ", clazzName=" + clazzName + ", clazzNumber=" + clazzNumber + "]"; }* * public String showClazzAndStudent() { return "Clazz [clazzId=" + clazzId +* ", clazzName=" + clazzName + ", clazzNumber=" + clazzNumber + ", list=" +* list + "]"; }*/}

学生实体

package com.cyj.springboot.entity;import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonUnwrapped;@Entity
@Table(name = "studenttb")
public class Student implements Serializable {@Id // 实体类的主键@GeneratedValue // 自动增长列@OrderBy // 数据加载顺序@Column(columnDefinition = "int unsigned NOT NULL comment '备注:学生自动增长主键'  ")private Integer studentId;@Column(length = 20) // 字符长度20private String studentName;@Column(columnDefinition = "char(1) comment '备注:学生姓名' ")private String studentSex;@Column(columnDefinition = "int unsigned DEFAULT 0 comment '备注:学生年龄'  ")private Integer studentAge;private Date studentBirthday;
//	@CreationTimestamp@UpdateTimestamp	//插入,修改时自动维护时间戳@Column(columnDefinition = "TIMESTAMP", nullable = false, updatable = false, insertable = false)private Timestamp updateTime;@Transient // 临时参数,不映射到数据库表字段private String studentSpare;@JsonIgnore
//	@JsonUnwrapped@ManyToOne(targetEntity = Clazz.class)@JoinColumn(name = "student_clazz_id") // 副表中的外键字段名称private Clazz clazz;// ----------------------------- 以下是构造方法 ------------------------// ----------------------------- 以下是Getter和setter方法 ------------------------public Integer getStudentId() {return studentId;}public void setStudentId(Integer studentId) {this.studentId = studentId;}public String getStudentName() {return studentName;}public void setStudentName(String studentName) {this.studentName = studentName;}public String getStudentSex() {return studentSex;}public void setStudentSex(String studentSex) {this.studentSex = studentSex;}public Integer getStudentAge() {return studentAge;}public void setStudentAge(Integer studentAge) {this.studentAge = studentAge;}public Date getStudentBirthday() {return studentBirthday;}public void setStudentBirthday(Date studentBirthday) {this.studentBirthday = studentBirthday;}public Timestamp getUpdateTime() {return updateTime;}public void setUpdateTime(Timestamp updateTime) {this.updateTime = updateTime;}public String getStudentSpare() {return clazz.getClazzName();}public void setStudentSpare(String studentSpare) {this.studentSpare = studentSpare;}public Clazz getClazz() {return clazz;}public void setClazz(Clazz clazz) {this.clazz = clazz;}/** @Override public String toString() { return "Student [studentId=" + studentId* + ", studentName=" + studentName + ", studentSex=" + studentSex +* ", studentAge=" + studentAge + ", studentBirthday=" + studentBirthday +* ", updateTime=" + updateTime + ", studentSpare=" + studentSpare + ", clazz="* + clazz + "]"; }*/// ----------------------------- 以下是重写的toString方法 ------------------------/** @Override public String toString() { return "Student [studentId=" + studentId* + ", studentName=" + studentName + ", studentSex=" + studentSex +* ", studentAge=" + studentAge + ", studentBirthday=" + studentBirthday +* ", updateTime=" + updateTime + ", studentSpare=" + studentSpare + "]"; }* * public String showStudent() { return "Student [studentId=" + studentId +* ", studentName=" + studentName + ", studentSex=" + studentSex +* ", studentAge=" + studentAge + ", studentBirthday=" + studentBirthday +* ", updateTime=" + updateTime + ", studentSpare=" + studentSpare + "]"; }* * public String showStudentAndClazz() { return "Student [studentId=" +* studentId + ", studentName=" + studentName + ", studentSex=" + studentSex +* ", studentAge=" + studentAge + ", studentBirthday=" + studentBirthday +* ", updateTime=" + updateTime + ", studentSpare=" + studentSpare + ", clazz="* + clazz + "]"; }*/}

此时多的一方学生类无影响,对应studenttb表正常写出所有列,包括外键列,需注意外键列对应属性名必须叫做
clazzId。

@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL):

@OneToMany表示该列为一对多关系列;

  • fetch表示该实体的加载方式,有两种:LAZY和EAGER,懒加载和立即加载;
  • cascade表示与此实体一对一关联的实体的联级样式类型。联级样式上当对实体进行操作时的策略。
    说明:在定义关系时经常会涉及是否定义Cascade(级联处理)属性,担心造成负面影响。
    • 不定义,则对关系表不会产生任何影响
    • CascadeType.PERSIST (级联新建)
    • CascadeType.REMOVE (级联删除)
    • CascadeType.REFRESH (级联刷新)
    • CascadeType.MERGE (级联更新)
    • CascadeType.ALL ,表示选择全部四项
  • targetEntity 表示默认关联的实体类型,默认为当前标注的实体类;
    mappedBy属性用于双向关联实体时使用,在一的一方进行声明,表示自己不是一对多的关系维护端,由对
    方来维护。取值应该为多的一方的外键列对应的属性名。

5.编写dao接口

在com.cyj.springboot.dao,编写ClazzRepository、StudentRepository接口,代码如下:

package com.cyj.springboot.dao;import java.util.List;import org.springframework.data.jpa.repository.JpaRepository;import com.cyj.springboot.entity.Clazz;public interface ClazzRepository extends JpaRepository<Clazz, Integer> {// Like --- 等价于 SQL 中的 "like",比如 findByNameLike(String name);public List<Clazz> findByClazzNameLike(String name);}

学生

package com.cyj.springboot.dao;import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.cyj.springboot.entity.Student;public interface StudentRepository extends JpaRepository<Student, Integer> {// Like --- 等价于 SQL 中的 "like",比如 findByNameLike(String name);public List<Student> findByStudentNameLike(String name);}

6.编写业务逻辑层

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

package com.cyj.springboot.service;import java.util.List;import com.cyj.springboot.entity.Clazz;public interface ClazzService {public Clazz save(Clazz clazz);public Clazz queryById(Integer id);public List<Clazz> queryByNameLike(String name);}

学生

package com.cyj.springboot.service;import java.util.List;import com.cyj.springboot.entity.Student;public interface StudentService {public Student queryById(Integer id);public List<Student> queryByNameLike(String name);}

7.编写业务逻辑层

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

package com.cyj.springboot.ServiceImpl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.cyj.springboot.dao.ClazzRepository;
import com.cyj.springboot.entity.Clazz;
import com.cyj.springboot.entity.Student;
import com.cyj.springboot.service.ClazzService;@Service
public class ClazzServiceImpl implements ClazzService {@Autowiredprivate ClazzRepository repository;@Overridepublic Clazz save(Clazz clazz) {return repository.save(clazz);}@Overridepublic Clazz queryById(Integer id) {return repository.findOne(id);}@Overridepublic List<Clazz> queryByNameLike(String name) {return repository.findByClazzNameLike("%" + name + "%");}}

学生

package com.cyj.springboot.ServiceImpl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.cyj.springboot.dao.StudentRepository;
import com.cyj.springboot.entity.Student;
import com.cyj.springboot.service.StudentService;@Service
public class StudentServiceImpl implements StudentService {@Autowiredprivate StudentRepository repository;@Overridepublic Student queryById(Integer id) {return repository.findOne(id);}@Overridepublic List<Student> queryByNameLike(String name) {return repository.findByStudentNameLike("%" + name + "%");}}

8.编写controller层

在com.cyj.springboot.controller下,编写班级控制层、学生控制层,代码如下:

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.Clazz;
import com.cyj.springboot.entity.Student;
import com.cyj.springboot.service.ClazzService;/*** SpringMVC控制器* * @Description: 子模块* @ClassName: CityRestController.java* @author ChenYongJia* @Date 2017-10-4 下午8:04:34* @Email 867647213@qq.com*/
@RestController
@RequestMapping("/clazz")
public class ClazzController {@Autowiredprivate ClazzService service;/*** http://localhost:8080/clazz/queryById?id=1* * @param id* @return Student*/@RequestMapping("/queryById")public Clazz queryById(Integer id) {Clazz clazz = service.queryById(id);System.out.println("queryById clazz=>" + clazz);// .showClazzAndStudent());return clazz;}/*** http://localhost:8080/clazz/queryId?id=1* * @param id* @return Student*/@RequestMapping("/queryId")public Object queryId(Integer id) {Clazz clazz = service.queryById(id);System.out.println("queryById clazz=>" + clazz);// .showClazzAndStudent());return clazz;}}

学生

package com.cyj.springboot.controller;import java.util.List;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.Student;
import com.cyj.springboot.service.StudentService;/*** SpringMVC控制器* * @Description: 子模块* @ClassName: CityRestController.java* @author ChenYongJia* @Date 2017-10-4 下午8:04:34* @Email 867647213@qq.com*/
@RestController
@RequestMapping("/student")
public class StudentController {@Autowiredprivate StudentService service;/*** http://localhost:8080/student/queryById?id=1* * @param id* @return Student*/@RequestMapping("/queryById")public Student queryById(Integer id) {Student student = service.queryById(id);System.out.println("queryById student=>" + student);// .showStudentAndClazz());return student;}/*** http://localhost:8080/student/queryId?id=1* * @param id* @return Student*/@RequestMapping("/queryId")public String queryId(Integer id) {Student student = service.queryById(id);System.out.println("queryById student=>" + student);// .showStudentAndClazz());return "查询成功";}/*** http://localhost:8080/student/queryByNameLike?name=张三* * @param id* @return Student*/@RequestMapping("/queryByNameLike")public Object queryByNameLike(String name) {List<Student> list = service.queryByNameLike(name);System.out.println("queryByNameLike list=>" + list);for (Student s : list) {System.out.println("Student =>" + s);// .showStudentAndClazz());}return list;}}

9.编写项目主类

在com.cyj.springboot下编写项目主类,代码如下:

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 组件}
}

启动项目,查看运行结果,测试路径可根据controller层的提示进行测试


多对一关系

多对一是以多的一方为主,当我们对学生进行操作时会相应的级联到班级表,比如查询学生,自动会得到该学生所
在的班级。

@Entity @Table(name="studenttb") 
public class Student implements Serializable{
//多的一方 //...其他属性省略 @ManyToOne(targetEntity = Clazz.class)//通过实体反射说明该外键列来自于哪张表 private Clazz clazz;//因为不只保存所属班级主键,而是所属班级所有信息
}

此时一的一方班级类无影响,对应clazztb表正常写出所有列。


一对多多对一双向关联:

很显然,当一对多的时候,操作学生并不能级联到班级;同样的,当多对一的时候,操作班级也不能级联到学生,
那么想要双向关联要怎么做呢?很简单,把上面两者结合即可,即:

\
多的一方学生因为要显示班级信息,多个学生属于同一个班级,所以学生实体类当中要有一个属性是班级对象,当
查询学生时显示其所属班级,因为该类当中已经有了班级主键作为外键列,所以就有了2.2多对一中的 private Clazz clazz 的写法来代替并包含了外键列;同样的,一个班级对象中也要显示该班级下所有的学生,而班级表并
不需要学生表主键来做外键,为了满足保存所有学生的情况,我们在班级实体类加入泛型为学生的集合来做属性。

此时两者互相关联,那么外键如何处理呢?当我们添加一个学生,如果该班级不存在,按照业务设计要么失败要么
自动级联添加,反之添加班级时也会添加…,此时两方都在维护外键,就会导致冗余和冲突,所以我们需要指定一
方来维护即可。所以我们按照谁使用谁处理的原则,交给多的一方来处理。具体写法为,在一的一方也就是

@OneToMany 中添加 mappedBy="clazz" 来进行指定。

所以实现双向关联即为一对多+多对一组合,且在@OneToMany中添加mappedBy="clazz"即可。


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


最后

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

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


http://www.lbrq.cn/news/2768509.html

相关文章:

  • 海南省建设设厅官方网站网站优化外包多少钱
  • 做网站必须在工信部备案吗附近的成人电脑培训班
  • 怎样把域名和做的网站连接不上白杨seo教程
  • 搭建个网站深圳网站seo地址
  • 国际会议网站建设北京疫情最新消息情况
  • 做网站快速排名百度灰色关键词代发
  • 陕西省建设招投标网站前端培训班一般多少钱
  • 现在做跨境电商还能赚钱吗一键关键词优化
  • 温州做外贸网站设计苏州网站维护
  • 手机网站制作视频教程企业培训课程开发
  • 如何做好网站建设免费建站免费推广的网站
  • 建站工具 营销成都网站seo外包
  • 江门网站优化快速排名爱站关键词挖掘查询工具
  • 郑州做网站优化运营商武汉企业网站推广
  • 外贸网站建设基础百度关键词优化服务
  • 如何建设一个工业品采购网站百度云网盘资源
  • 深圳网站平面设计百度搜索风云榜总榜
  • 网站手机客户端在线制作百度排名怎么做
  • 开发小程序的费用明细长沙排名优化公司
  • 池州专业网站建设公司上海优化网站seo公司
  • 网站建设公司排名深圳上海网络关键词优化
  • 网站开发的方法市场营销手段13种手段
  • 靠谱的软件下载网站私域营销
  • 怎么自己做网站赚钱吗深圳龙岗区布吉街道
  • 网站版面特点360线上推广
  • 网站备案 2016如何网站关键词优化
  • 北京 工业网站建设公司价格百度一下官方网
  • 福建省建设厅审查网站推广电话
  • 公司网站制作应该注意些什么windows优化大师的功能
  • 关于网站建设的技巧河北百度seo软件
  • 当宠物机器人装上「第六感」:Deepoc 具身智能如何重构宠物机器人照看逻辑
  • GaussDB 中 alter default privileges 的使用示例
  • 用户认证技术
  • 跨平台RTSP播放器深度对比:开源方案与商业SDK的取舍之道
  • 冒泡排序——简单理解和使用
  • 1. Docker的介绍和安装