数据库中表多对多的关系也是很常见的,如一个权限系统,设置的足够严密,就是 权限(菜单)与角色多对多
关系,角色与用户多对多
关系。
代码以及放到 github 上了:https://github.com/larger5/SpringBootJPAMM.git
省略了 Service 层
package com.cun.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue
private Integer id;
@Column(length = 100)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student() {
super();
}
}
package com.cun.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "t_teacher")
public class Teacher {
@Id
@GeneratedValue
private Integer id;
@Column(length = 100)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher() {
super();
}
}
package com.cun.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "t_st")
public class StudentTeacher {
@Id
@GeneratedValue
private Integer id;
@ManyToOne
@JoinColumn(name="student_id")
private Student student;
@ManyToOne
@JoinColumn(name="teacher_id")
private Teacher teacher;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
package com.cun.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.cun.entity.Student;
public interface StudentDao extends JpaRepository<Student, Integer>{
}
package com.cun.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.cun.entity.Teacher;
public interface TeacherDao extends JpaRepository<Teacher, Integer>{
}
package com.cun.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.cun.entity.StudentTeacher;
public interface StudentTeacherDao extends JpaRepository<StudentTeacher, Integer> {
/**
* 1.1、学生关联查询
* @param id
* @return
*/
@Query(value = "select * from t_st where student_id=?1", nativeQuery = true)
List getStudentTeacherByStudentId(Integer id);
/**
* 1.2、教师关联查询
* @param id
* @return
*/
@Query(value = "select * from t_st where teacher_id=?1", nativeQuery = true)
List getStudentTeacherByTeacherId(Integer id);
/**
* 2.1、通过教师 id 删除师生关系
* ① 在 dao 层中加上 @Modifying
* ② 注意添加 @Transactional,否则 TransactionRequiredException
* ③ @Transactional 建议还是在 Service 层中加上,不要在 Controller 层中
*/
@Modifying
@Query(value="delete from t_st where teacher_id=?1",nativeQuery=true)
void deleteConnectionByTeacherId(Integer teacherId);
/**
* 2.2、通过学生 id 删除师生关系
* ① 在 dao 层中加上 @Modifying,否则 SQLException
* ② 注意添加 @Transactional,否则 TransactionRequiredException
* ③ @Transactional 建议还是在 Service 层中加上,不要在 Controller 层中
*/
@Modifying
@Query(value="delete from t_st where student_id=?1",nativeQuery=true)
void deleteConnectionByStudentId(Integer studentId);
}
package com.cun.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cun.dao.StudentDao;
import com.cun.dao.StudentTeacherDao;
import com.cun.entity.Student;
import com.cun.entity.StudentTeacher;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@RestController
@RequestMapping("/student")
@EnableSwagger2
@Transactional // 自定义update、delete、insert 的 Dao 接口必备
public class StudentController {
@Autowired
private StudentDao studentDao;
@Autowired
private StudentTeacherDao studentTeacherDao;
/**
* 1、查
* ① 这个查的返回值应该是一个 List 集合
* ② 一个学生可以有多个教师
* ③ 使用关系表的 JPA 查询来完成
* @param id
* @return
*/
@GetMapping("/get/{id}")
public List getStudent(@PathVariable Integer id) {
// return studentDao.findOne(id); //不符合实际需求的
return studentTeacherDao.getStudentTeacherByStudentId(id);
}
/**
* 2、增
* @param student
* @return
*/
@PostMapping("insert")
public Student insertStudent(Student student) {
studentDao.save(student);
// 保存后的 student 有 id
return student;
}
/**
* 3、改
* @param student
* @return
*/
@PutMapping("/update")
public Student updateStudent(Student student) {
studentDao.save(student);
return student;
}
/**
* 4、删:
* ① 删除前要判断是否存在关联关系,不同于一对多/多对一
* ② 多对要先把关系删除掉,否则 ConstraintViolationException!
* ③ 再把要删除的删掉,不会手下留情了!
* ④ 注意添加 @Transactional,建议还是在 Service 层中加上,不要在 Controller 层中
* @param id
* @return
*/
@DeleteMapping("/delete/{id}")
public Student deleteStudent(@PathVariable Integer id) {
Map map = new HashMap();
Student student = studentDao.findOne(id);
map.put("data", student);
//先断绝来外
studentTeacherDao.deleteConnectionByStudentId(id);
//再铲除
studentDao.delete(id);
return student;
}
/**
* 5、全
* @return
*/
@GetMapping("/all")
public List getAllStudents() {
return studentDao.findAll();
}
}
package com.cun.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cun.dao.StudentTeacherDao;
import com.cun.dao.TeacherDao;
import com.cun.entity.StudentTeacher;
import com.cun.entity.Teacher;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@RestController
@RequestMapping("/teacher")
@EnableSwagger2
@Transactional // 自定义update、delete、insert 的 Dao 接口必备
public class TeacherController {
@Autowired
private TeacherDao teacherDao;
@Autowired
private StudentTeacherDao studentTeacherDao;
/**
* 1、查
* ① 这个查应该应该是一个 List 集合
* ② 一个教师可以有多个学生
* ③ 使用关系表的 JPA 查询来完成
* @param id
* @return
*/
@GetMapping("/get/{id}")
public List getTeacherById(@PathVariable Integer id) {
// return teacherDao.findOne(id); //不符合实际需求的
return studentTeacherDao.getStudentTeacherByTeacherId(id);
}
/**
* 2、删:
* ① 删除前要判断是否存在关联关系,不同于一对多/多对一
* ② 多对要先把关系删除掉,否则 ConstraintViolationException!
* ③ 再把要删除的删掉,不会手下留情了!
* ④ 注意添加 @Transactional,建议还是在 Service 层中加上,不要在 Controller 层中
* @param id
* @return
*/
@DeleteMapping("/delete/{id}")
public Map deleteTeacherById(@PathVariable Integer id) {
Map map = new HashMap();
Teacher teacher = teacherDao.findOne(id);
map.put("data", teacher);
//先断绝来外
studentTeacherDao.deleteConnectionByTeacherId(id);
//再铲除
teacherDao.delete(id);
return map;
}
/**
* 3、改
* @param teacher
* @return
*/
@PutMapping("/update")
public Teacher updateTeacher(Teacher teacher) {
teacherDao.save(teacher);
return teacher;
}
/**
* 4、增
* @param teacher
* @return
*/
@PostMapping("/insert")
public Teacher insertTeacher(Teacher teacher) {
teacherDao.save(teacher);
// save 后 teacher 有 id 了
return teacher;
}
/**
* 5、全
* @return
*/
@GetMapping("/all")
public List getAllTeachers() {
return teacherDao.findAll();
}
}
加入 JPA、MySQL、Web
server:
port: 80 #为了以后访问项目不用写端口号
context-path: / #为了以后访问项目不用写项目名
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8 #解决中文乱码的问题
username: root
password: 123
jpa:
hibernate:
ddl-auto: update #数据库同步代码
show-sql: true #dao操作时,显示sql语句
学生查询:输入 id=1
1、使用 @Query
更新删除时,同时要使用 @Modifying
、@Transaction