SpringData Jpa(三):多表关联的操作

多表操作

在这里插入图片描述
在实际开发中,数据库的表难免会有相互的关联关系,在操作表的时候就有可能会涉及到多张表的操作。 而在这种实现了ORM思想的框架中(如 JPA),可以通过操作实体类就实现对数据库表的操作。

配置实体之间的关联关系

  • 第一步:首先确定两张表之间的关系
  • 第二步:在实体类中描述出两个实体的关系
  • 第三步:配置出实体类和数据库表的关系映射(重点)

一对一关系

  • 通过唯一的外键关联

1.数据准备:article和article_data的一对一关系,并给article_data建立好外键
在这里插入图片描述
2.创建实体类,并在类中配置表间关系

  • 创建文章类
    • 注意: cascade = CascadeType.PERSIST 这里必须设置级联
@Entity
@Table(name = "article")
@Data
public class Article {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer aid;

    private String author;

    private Date createTime;

    private String title;


    /**
     * 声明类间关系
     * 声明主动放弃关系维护 mappedBy="当前类在对方类中的属性名"
     * 当保存Article的时候,同时保存ArticleData
     */
    @OneToOne(mappedBy = "article", cascade = CascadeType.PERSIST)
    private ArticleData articleData;

}
  • 创建文章详情类
    • 注意: unique = true 因为只有外键唯一才是一对一 不然就是多对一
@Entity
@Table(name = "article_data")
@Data
public class ArticleData {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String content;


    /**
     * 让这个实体维护关系
     * JoinColumn 表示声明外键
     * name                    当前表中的外键名
     * referencedColumnName    指向的对方表中的主键名
     */
    @OneToOne
    @JoinColumn(name = "articleId", referencedColumnName = "aid", unique = true)
    private Article article;
}

3.添加ArticleDao接口

public interface ArticleDataDao extends JpaRepository<ArticleData, Integer>, JpaSpecificationExecutor<ArticleData> { 
}

4.测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class One2OneTest {

    @Autowired
    private ArticleDao articleDao;

    //保存
    @Test
    public void testSave() {
        //创建文章对象
        Article article = new Article();
        article.setTitle("t_1");
        article.setAuthor("a_1");
        article.setCreateTime(new Date());

        //创建文章内容对象
        ArticleData articleData = new ArticleData();
        articleData.setContent("真是一篇好文章");


        //建立两个对象间的关系
        article.setArticleData(articleData);
        articleData.setArticle(article);

        //保存操作
        articleDao.save(article);
    }
}

一对多关系

  • 通过不唯一的外键关联

1.数据准备:article和comment的一对多关系,并给comment建立好外键
在这里插入图片描述
2.创建实体类,并在类中配置表间关系

  • 修改文章类,添加文章跟评论的映射
@Entity
@Table(name = "article")
@Data
public class Article {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer aid;

    private String author;

    private Date createTime;

    private String title;


    /**
     * 声明类间关系
     * 声明主动放弃关系维护 mappedBy="当前类在对方类中的属性名"
     * 当保存Article的时候,同时保存ArticleData
     */
    @OneToOne(mappedBy = "article", cascade = CascadeType.PERSIST)
    private ArticleData articleData;

	/**
	 * 建立文章对评论的一对多关系 
	 * 在一的一方声明放弃维护关系
	 * 一对多使用 List 或者 Set
	 */
	@OneToMany(mappedBy = "article")
    private Set<Comment> comments = new HashSet<>(0);

}
  • 创建文章评论类
@Entity
@Table(name = "comment")
@Data
public class Comment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer cid;

    private String comment;


    @ManyToOne()
    @JoinColumn(name = "aid", referencedColumnName = "aid")
    private Article article;
}

3.添加CommentDao接口

public interface CommentDao extends JpaRepository<Comment, Integer>, JpaSpecificationExecutor<Comment> { 

}

4.测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class One2ManyTest {

    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private CommentDao commentDao;

    //保存
    @Test
    public void testSave() {
        //创建文章对象
        Article article = new Article();
        article.setTitle("t_1");
        article.setAuthor("a_1");
        article.setCreateTime(new Date());

        //创建文章评论对象
        Comment comment1 = new Comment();
        comment1.setComment("真不错");
        Comment comment2 = new Comment();
        comment2.setComment("挺好的");

        //建立两个对象间的关系
        comment1.setArticle(article);
        comment2.setArticle(article);

        Set<Comment> comments = new HashSet<>();
        comments.add(comment1);
        comments.add(comment2);
        article.setComments(comments);


        //保存操作
        articleDao.save(article);
        commentDao.save(comment1);
        commentDao.save(comment2);

    }
}

多对多关系

扫描二维码关注公众号,回复: 9305526 查看本文章
  • 通过中间表关联

1.数据准备:article跟type之间的多对多关系,建立好中间表article_type 与article_type的两个外键
在这里插入图片描述

2.创建实体类,并在类中配置表间关系

  • 修改文章类,添加文章跟评论用户的多对多关系
@Entity
@Table(name = "article")
@Data
public class Article {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer aid;

    private String author;

    private Date createTime;

    private String title;


    /**
     * 声明类间关系
     * 声明主动放弃关系维护 mappedBy="当前类在对方类中的属性名"
     * 当保存Article的时候,同时保存ArticleData
     */
    @OneToOne(mappedBy = "article", cascade = CascadeType.PERSIST)
    private ArticleData articleData;

	/**
	 * 建立文章对评论的一对多关系 
	 * 在一的一方声明放弃维护关系
	 * 一对多使用 List 或者 Set
	 */
	@OneToMany(mappedBy = "article")
    private Set<Comment> comments = new HashSet<>(0);

	/**
	 * 建立从文章到类型的多对多关系
	 */ 
	@ManyToMany(mappedBy = "articles")
    private Set<Type> types = new HashSet<>(0);

}
  • 添加用户类,并在类中配置表间关系
@Entity
@Table(name = "type")
@Data
public class Type {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer tid;

    private String name;

    @ManyToMany
    @JoinTable(
            //代表中间表名称
            name = "article_type",
            //中间表的外键对应到当前表的主键名称
            joinColumns = {@JoinColumn(name = "tid", referencedColumnName = "tid")},
            //中间表的外键对应到对方表的主键名称
            inverseJoinColumns = {@JoinColumn(name = "aid", referencedColumnName = "aid")}
    )
    private Set<Article> articles = new HashSet<>(0);

}

3.添加TypeDao接口

public interface TypeDao extends JpaRepository<Type, Integer>, JpaSpecificationExecutor<Type> { 
}

4.测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class Many2ManyTest {

    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private TypeDao typeDao;

    //保存
    @Test
    public void testSave() {
        //创建文章对象
        Article article1 = new Article();
        article1.setTitle("t_11");
        article1.setAuthor("a_11");
        article1.setCreateTime(new Date());

        Article article2 = new Article();
        article2.setTitle("t_22");
        article2.setAuthor("a_22");
        article2.setCreateTime(new Date());


        //创建文章类型对象
        Type type1 = new Type();
        type1.setName("军事");
        Type type2 = new Type();
        type2.setName("民政");


        //建立两个对象间的关系
        Set<Type> types = new HashSet<>();
        types.add(type1);
        types.add(type2);
        article1.setTypes(types);
        article2.setTypes(types);

        Set<Article> articles = new HashSet<>();
        articles.add(article1);
        articles.add(article2);
        type1.setArticles(articles);
        type2.setArticles(articles);


        //保存操作
        articleDao.save(article1);
        articleDao.save(article2);
        typeDao.save(type1);
        typeDao.save(type2);
    }
}

小结

  • 为什么都有外键和中间表了 但还要使用注解关联起来
    • 在多对多的时候会自动给中间表增加关联的数据 不用手动添加
    • 在查询的时候 会连带着把关联的数据查出来 不用手动查找
  • 怎么选择哪方维护数据
    • 一对一:与其他表关联少的一方
    • 一对多:多的那方
    • 多对多:与其他表关联少的一方
发布了109 篇原创文章 · 获赞 47 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43934607/article/details/103248563