• 吴裕雄天生自然Spring Boot使用Spring Data JPA实现Author与Article的一对多关系映射


        在Spring Data JPA中,使用@OneToMany和@ManyToOne来表示一对多的双向关联。例如,一端(Author)使用@OneToMany,多端(Article)使用@ManyToOne。
        在JPA规范中,一对多的双向关系由多端(如Article)来维护。就是说多端为关系的维护端,负责关系的增删改查。一端则为关系的被维护端,不能维护关系。
        一端(Author)使用@OneToMany注解的mappedBy="author"属性表明一端(Author)是关系的被维护端。多端(Article)使用@ManyToOne和@JoinColumn来注解属性author,@ManyToOne表明Article是多端,@JoinColumn设置在article表的关联字段(外键)上。
    使用Spring Data JPA实现Author与Article的一对多关系映射
    
    1)创建持久化实体类
    2)创建数据访问层
    3)创建业务层
    4)创建控制器类
    5)运行
    <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.onetomany</groupId>
        <artifactId>SpringBootOneToMany</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <!-- 声明项目配置依赖编码格式为 utf-8 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <fastjson.version>1.2.24</fastjson.version>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- 添加MySQL依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
                <version>8.0.13</version><!--$NO-MVN-MAN-VER$ -->
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>
    server.port=8089
    
    server.servlet.context-path=/ch6_2
    spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?serverTimezone=UTC&autoReconnect=true
    spring.datasource.username=root
    spring.datasource.password=admin
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.jpa.database=MYSQL
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=update
    spring.jackson.serialization.indent-output=true 
    1)创建持久化实体类
    
    在com.ch.ch6_2.entity包中,创建名为Author和Article的持久化实体类。
    
    
    @Entity
    @Table(name = "author_table")
    @JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
    public class Author implements Serializable{
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
        //作者名
        private String aname;
        //文章列表,作者与文章是一对多的关系
        @OneToMany(
                mappedBy = "author",
                cascade=CascadeType.ALL,
                targetEntity = Article.class, 
                fetch=FetchType.LAZY
                )
        private List<Article> articleList;
        //省略set和get方法
    }
    package com.ch.ch6_2.entity;
    
    import java.io.Serializable;
    import java.util.List;
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    
    @Entity
    @Table(name = "author_table")
    @JsonIgnoreProperties(value = { "hibernateLazyInitializer" })
    public class Author implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
        // 作者名
        private String aname;
        // 文章列表,作者与文章是一对多的关系
        @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, targetEntity = Article.class, fetch = FetchType.LAZY)
        private List<Article> articleList;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getAname() {
            return aname;
        }
    
        public void setAname(String aname) {
            this.aname = aname;
        }
    
        public List<Article> getArticleList() {
            return articleList;
        }
    
        public void setArticleList(List<Article> articleList) {
            this.articleList = articleList;
        }
    }
    package com.ch.ch6_2.entity;
    
    import java.io.Serializable;
    
    import javax.persistence.Basic;
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.Lob;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    import javax.validation.constraints.NotEmpty;
    import javax.validation.constraints.Size;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    
    @Entity
    @Table(name = "article_table")
    @JsonIgnoreProperties(value = { "hibernateLazyInitializer" })
    public class Article implements Serializable {
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int id;
    
        // 标题
        @NotEmpty(message = "标题不能为空")
        @Size(min = 2, max = 50)
        @Column(nullable = false, length = 50)
        private String title;
    
        // 文章内容
        @Lob // 大对象,映射 为MySQL的Long文本类型
        @Basic(fetch = FetchType.LAZY)
        @NotEmpty(message = "内容不能为空")
        @Size(min = 2)
        @Column(nullable = false)
        private String content;
    
        // 所属作者,文章与作者是多对一的关系
        @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, optional = false)
        // 可选属性optional=false,表示author不能为空。删除文章,不影响用户
        @JoinColumn(name = "id_author_id") // 设置在article表中的关联字段(外键)
        @JsonIgnore
        private Author author;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public Author getAuthor() {
            return author;
        }
    
        public void setAuthor(Author author) {
            this.author = author;
        }
    }
    2)创建数据访问层
    
    在com.ch.ch6_2.repository包中,创建名为AuthorRepository和ArticleRepository的接口。
    package com.ch.ch6_2.repository;
    
    //import java.util.List;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.Query;
    
    import com.ch.ch6_2.entity.Author;
    
    public interface AuthorRepository extends JpaRepository<Author, Integer> {
        /**
         * 根据文章标题包含的内容,查询作者(关联查询) 相当于JPQL语句:select a from Author a inner join
         * a.articleList t where t.title like %?1%
         */
        public Author findByArticleList_titleContaining(String title);
    
        /**
         * 根据文章标题包含的内容,查询作者(关联查询)
         */
        @Query("select a from Author a  inner join  a.articleList t where t.title like %?1%")
        public Author findAuthorByArticleListtitleContaining(String title);
    }
    package com.ch.ch6_2.repository;
    
    import java.util.List;
    import org.springframework.data.jpa.repository.JpaRepository;
    import com.ch.ch6_2.entity.Article;
    
    public interface ArticleRepository extends JpaRepository<Article, Integer> {
        /**
         * 根据作者id查询文章信息(关联查询,根据author属性的id) 相当于JPQL语句:select a from Article a where
         * a.author.id = ?1
         */
        public List<Article> findByAuthor_id(Integer id);
    
        /**
         * 根据作者名查询文章信息(关联查询,根据author属性的aname) 相当于JPQL语句:select a from Article a where
         * a.author.aname = ?1
         */
        public List<Article> findByAuthor_aname(String aname);
    }
    3)创建业务层
    
    在com.ch.ch6_2.service包中,创建名为AuthorAndArticleService的接口和接口实现类AuthorAndArticleServiceImpl。
    package com.ch.ch6_2.service;
    
    import java.util.List;
    
    import com.ch.ch6_2.entity.Article;
    import com.ch.ch6_2.entity.Author;
    
    public interface AuthorAndArticleService {
        public void saveAll();
    
        public List<Article> findByAuthor_id(Integer id);
    
        public List<Article> findByAuthor_aname(String aname);
    
        public Author findByArticleList_titleContaining(String title);
    
        public Author findAuthorByArticleListtitleContaining(String title);
    }
    package com.ch.ch6_2.service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.ch.ch6_2.entity.Article;
    import com.ch.ch6_2.entity.Author;
    import com.ch.ch6_2.repository.ArticleRepository;
    import com.ch.ch6_2.repository.AuthorRepository;
    
    @Service
    public class AuthorAndArticleServiceImpl implements AuthorAndArticleService {
        @Autowired
        private AuthorRepository authorRepository;
        @Autowired
        private ArticleRepository articleRepository;
    
        @Override
        public void saveAll() {
            // 保存作者(先保存一的一端)
            Author a1 = new Author();
            a1.setAname("陈恒1");
            Author a2 = new Author();
            a2.setAname("陈恒2");
            ArrayList<Author> allAuthor = new ArrayList<Author>();
            allAuthor.add(a1);
            allAuthor.add(a2);
            authorRepository.saveAll(allAuthor);
            // 保存文章
            Article at1 = new Article();
            at1.setTitle("JPA的一对多111");
            at1.setContent("其实一对多映射关系很常见111。");
            // 设置关系
            at1.setAuthor(a1);
            Article at2 = new Article();
            at2.setTitle("JPA的一对多222");
            at2.setContent("其实一对多映射关系很常见222。");
            // 设置关系
            at2.setAuthor(a1);// 文章2与文章1作者相同
            Article at3 = new Article();
            at3.setTitle("JPA的一对多333");
            at3.setContent("其实一对多映射关系很常见333。");
            // 设置关系
            at3.setAuthor(a2);
            Article at4 = new Article();
            at4.setTitle("JPA的一对多444");
            at4.setContent("其实一对多映射关系很常见444。");
            // 设置关系
            at4.setAuthor(a2);// 文章3与文章4作者相同
            ArrayList<Article> allAt = new ArrayList<Article>();
            allAt.add(at1);
            allAt.add(at2);
            allAt.add(at3);
            allAt.add(at4);
            articleRepository.saveAll(allAt);
        }
    
        @Override
        public List<Article> findByAuthor_id(Integer id) {
            return articleRepository.findByAuthor_id(id);
        }
    
        @Override
        public List<Article> findByAuthor_aname(String aname) {
            return articleRepository.findByAuthor_aname(aname);
        }
    
        @Override
        public Author findByArticleList_titleContaining(String title) {
            return authorRepository.findByArticleList_titleContaining(title);
        }
    
        @Override
        public Author findAuthorByArticleListtitleContaining(String title) {
            return authorRepository.findAuthorByArticleListtitleContaining(title);
        }
    }
    4)创建控制器类
    
    在com.ch.ch6_2.controller包中,创建名为TestOneToManyController的控制器类。
    package com.ch.ch6_2.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.ch.ch6_2.entity.Article;
    import com.ch.ch6_2.entity.Author;
    import com.ch.ch6_2.service.AuthorAndArticleService;
    
    @RestController
    public class TestOneToManyController {
        @Autowired
        private AuthorAndArticleService authorAndArticleService;
    
        @RequestMapping("/saveOneToMany")
        public String save() {
            authorAndArticleService.saveAll();
            return "作者和文章保存成功!";
        }
    
        @RequestMapping("/findArticleByAuthor_id")
        public List<Article> findByAuthor_id(Integer id) {
            return authorAndArticleService.findByAuthor_id(id);
        }
    
        @RequestMapping("/findArticleByAuthor_aname")
        public List<Article> findByAuthor_aname(String aname) {
            return authorAndArticleService.findByAuthor_aname(aname);
        }
    
        @RequestMapping("/findByArticleList_titleContaining")
        public Author findByArticleList_titleContaining(String title) {
            return authorAndArticleService.findByArticleList_titleContaining(title);
        }
    
        @RequestMapping("/findAuthorByArticleListtitleContaining")
        public Author findAuthorByArticleListtitleContaining(String title) {
            return authorAndArticleService.findAuthorByArticleListtitleContaining(title);
        }
    }
    首先,运行Ch62Application主类。然后,访问“http://localhost:8089/ch6_2/saveOneToMany/”。
    package com.ch.ch6_2;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class Ch62Application {
        public static void main(String[] args) {
            SpringApplication.run(Ch62Application.class, args);
        }
    }

     

  • 相关阅读:
    Postman高级应用——流程控制、调试、公共函数、外部数据文件
    python模块之openpyxl
    appium实例1:启动淘宝app
    appium1.6在mac上环境搭建启动ios模拟器上Safari浏览器 转自:上海-悠悠
    appium 环境准备
    python_正则表达式
    接口测试指导方案 转:紫漪
    性能监控工具的配置及使用
    Python_斐波那契数列
    Js new一个函数和直接调用函数的区别
  • 原文地址:https://www.cnblogs.com/tszr/p/15338006.html
Copyright © 2020-2023  润新知