springdatajpa多表关系多对多单向关联

8.多表关系—>多对多查询

#####8.1多对多实体类

package com.xcl.domain;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "student_id")
    private Long  studentId;
    @Column(name = "student_name")
    private String  studentName;
    @Column(name = "student_age")
    private String  studentAge;
    @ManyToMany(cascade = {CascadeType.PERSIST})//级联类型保存
    @JoinTable(name="student_grade",
                joinColumns = {@JoinColumn(name = "student_id")},
                inverseJoinColumns = {@JoinColumn(name = "grade_id")})
    private Set<Grade>  GradeSet= new HashSet<Grade>(0);
	//需要补充getter and setter方法
}
package com.xcl.domain;
import javax.persistence.*;
@Entity
@Table(name = "Grade")
public class Grade {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //主键策略  mysql
    @Column(name ="grade_id")
    private Long gradeId;   //班级ID主键
    @Column(name = "grade_name")
    private String gradeName;
	//需要补充getter and setter方法
}

8.2符合规范的JPA接口
package com.xcl.dao;
import com.xcl.domain.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface StudentDao extends JpaRepository<Student,Long>,JpaSpecificationExecutor<Student> {
}
package com.xcl.dao;
import com.xcl.domain.Grade;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface GradeDao  extends JpaRepository<Grade,Long>,JpaSpecificationExecutor<Grade>{
}
8.3测试
package com.xcl;
import com.xcl.dao.GradeDao;
import com.xcl.dao.StudentDao;
import com.xcl.domain.Grade;
import com.xcl.domain.Student;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.HashSet;
import java.util.Set;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class Many2ManyTest {
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private GradeDao gradeDao;
    /**
     * 测试添加一条学生记录
     */
    @Test
    public void test01(){
        //添加学生
        Student student = new Student();
        student.setStudentName("麻花藤");
        //添加班级
        Grade grade1 = new Grade();
        grade1.setGradeName("作死一班");
        //添加班级
        Grade grade2 = new Grade();
        grade2.setGradeName("作死二班");
        //设置学生可以在哪些班级上课
        Set<Grade> gradeSet =new HashSet<Grade>();
        gradeSet.add(grade1);
        gradeSet.add(grade2);
        student.setGradeSet(gradeSet);
        //执行保存操作
        studentDao.save(student);   //执行效果,各自插入数据,且建立了中间表关联
    }
    /**
     * 测试删除一条学生记录
     */
    @Test
    public void test02(){
        studentDao.delete(1L);  //执行效果,setdent,及中间表删除了,但grade表数据依然存在
    }
}
### Spring Data JPA 注解使用方法 #### 实体类注解 实体类是映射到数据库的对象。为了将 Java 类声明为持久化实体,需使用 `@Entity` 和其他相关注解。 - **@Entity** 此注解用来标记一个普通的Java类作为实体,使之成为JPA管理的一部分[^5]。 ```java @Entity public class User { } ``` - **@Table** 当需要指定实体对应的具体数据库名称时可以使用该注解。如果未提供,则默认采用无下划线的小写形式的类名作为名。 ```java @Table(name = "users") ``` - **@Id** 用于标识唯一主键字段,在每个实体中至少存在一个这样的属性来示记录的身份[^3]。 ```java @Id private Long id; ``` - **@GeneratedValue** 配合 `@Id` 使用,指明主键生成策略,默认情况下会根据底层数据源自动选择合适的算法(如序列号、UUID等)。常见的配置方式有: - `GenerationType.AUTO`: 让框架自己决定最适合的方式; - `GenerationType.IDENTITY`: 利用数据库自身的自增列特性; - `GenerationType.SEQUENCE`: 基于特定的数据序列达式创建新值; - `GenerationType.TABLE`: 维护一张额外格存储版本信息并从中读取下一个可用编号。 ```java @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; ``` #### 关联关系注解 描述不同实体之间的联系也是开发过程中不可或缺的一环。以下是几种常用的关联类型及其相应的注解说明: - **一对一 (OneToOne)** 适用于两个对象之间仅能建立单向或双向一对一的关系场景。比如用户与其个人资料页之间的绑定就可以通过这种方式建模。 ```java @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "profile_id", referencedColumnName = "id") private Profile profile; ``` - **一对 / 对一 (OneToMany & ManyToOne)** 最常见的情况莫过于父级分类下的子项集合或是订单明细中的商品条目了。前者是从整体视角出发定义个个体隶属于同一个上级单位;后者则是强调各个成员各自归属哪个集体。 ```java // Parent side, OneToMany example @OneToMany(mappedBy = "parent", cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private Set<Child> children; // Child side, ManyToOne example @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Parent parent; ``` - **多对多 (ManyToMany)** 对于那些既不是单一也不是层次结构而是网状交错存在的事物间相互作用模式而言,“多对多”的概念就显得尤为重要了。例如学生选课系统里每位同学可以选择若干门课程而每门科目也可能被名学员修习。 ```java @ManyToMany @JoinTable( name = "student_courses", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "course_id")) private List<Course> courses; ``` #### 查询方法支持 除了上述基础功能外,Spring Data JPA 还提供了便捷的方法命名约定机制以及基于接口的仓库定制能力,使得开发者几乎不需要编写任何SQL语句就能完成大部分CRUD操作[^4]。 例如要查找所有姓张的人的信息,只需简单地在Repository接口内增加如下签名即可: ```java List<User> findByLastName(String lastName); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值