SpringDataJPA is a sub-project of SpringData that significantly reduces the amount of code required for JPA as a Data access solution by providing a JPA-based Repository. You just need to write an interface that integrates with SpringDataJPA internally defined interfaces to perform simple CRUD operations.

preface

This article guides you through implementing relational mapping of many-to-many associated tables with extra fields through Spring Boot, Spring Data JPA, and MySQL.

To prepare

  • JDK 1.8 or later
  • Maven 3 or later
  • MySQL Server 5.6

Technology stack

  • Spring Data JPA
  • Spring Boot
  • MySQL

The directory structure

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/2/28/161dbadd0154c56d~tplv-t2oaga2asx-image.image

Father pom. XML

<?xml version="1.0" encoding="UTF-8"? >
<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>cn.merryyou</groupId>
    <artifactId>jpa-example</artifactId>
    <version>1.0 the SNAPSHOT</version>
    <modules>
        <module>one-to-one-foreignkey</module>
        <module>one-to-one-primarykey</module>
        <module>one-to-many</module>
        <module>many-to-many</module>
        <module>many-to-many-extra-columns</module>
    </modules>
    <packaging>pom</packaging>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>platform-bom</artifactId>
                <version>Brussels-SR6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
Copy the code

Many-to-many association mapping

The directory structure

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/3/6/161f9b2fa253c767~tplv-t2oaga2asx-image.image

pom.xml
<?xml version="1.0" encoding="UTF-8"? >
<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">
    <parent>
        <artifactId>jpa-example</artifactId>
        <groupId>cn.merryyou</groupId>
        <version>1.0 the SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>many-to-many-extra-columns</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1 track</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
Copy the code
Many-to-many association

Book. id and publisher.id many-to-many association tables book_publisher also have the published_data field

https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/3/6/161f9b2fa2445eb2~tplv-t2oaga2asx-image.image

db.sql

CREATE DATABASE  IF NOT EXISTS `jpa_manytomany_extracolumns` / *! 40100 DEFAULT CHARACTER SET utf8 */;
USE `jpa_manytomany_extracolumns`;

--
-- Table structure for table `book`
--

DROP TABLE IF EXISTS `book`;
/ *! 40101 SET @saved_cs_client = @@character_set_client */;
/ *! 40101 SET character_set_client = utf8 */;
CREATE TABLE `book` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
/ *! 40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `publisher`
--

DROP TABLE IF EXISTS `publisher`;
/ *! 40101 SET @saved_cs_client = @@character_set_client */;
/ *! 40101 SET character_set_client = utf8 */;
CREATE TABLE `publisher` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`))ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

--
-- Table structure for table `book_publisher`
--

DROP TABLE IF EXISTS `book_publisher`;
/ *! 40101 SET @saved_cs_client = @@character_set_client */;
/ *! 40101 SET character_set_client = utf8 */;
CREATE TABLE `book_publisher` (
`book_id` int(10) unsigned NOT NULL.`publisher_id` int(10) unsigned NOT NULL.`published_date` datetime DEFAULT NULL,
PRIMARY KEY (`book_id`.`publisher_id`),
KEY `fk_bookpublisher_publisher_idx` (`publisher_id`),
CONSTRAINT `fk_bookpublisher_book` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`) ON DELETE CASCADE ON UPDATE CASCADE.CONSTRAINT `fk_bookpublisher_publisher` FOREIGN KEY (`publisher_id`) REFERENCES `publisher` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Copy the code
Entity class
Book
@Entity
public class Book{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;

    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<BookPublisher> bookPublishers;

    public Book(a) {}public Book(String name) {
        this.name = name;
        bookPublishers = new HashSet<>();
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<BookPublisher> getBookPublishers(a) {
        return bookPublishers;
    }

    public void setBookPublishers(Set<BookPublisher> bookPublishers) {
        this.bookPublishers = bookPublishers; }}Copy the code
Publisher
@Entity
public class Publisher {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    @OneToMany(mappedBy = "publisher")
    private Set<BookPublisher> bookPublishers;

    public Publisher(a){}public Publisher(String name){
        this.name = name;
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<BookPublisher> getBookPublishers(a) {
        return bookPublishers;
    }

    public void setBookPublishers(Set<BookPublisher> bookPublishers) {
        this.bookPublishers = bookPublishers; }}Copy the code
BookPublisher
@Entity
@Table(name = "book_publisher")
public class BookPublisher implements Serializable {

    @Id
    @ManyToOne
    @JoinColumn(name = "book_id")
    private Book book;

    @Id
    @ManyToOne
    @JoinColumn(name = "publisher_id")
    private Publisher publisher;

    @Column(name = "published_date")
    private Date publishedDate;

    public Book getBook(a) {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }


    public Publisher getPublisher(a) {
        return publisher;
    }

    public void setPublisher(Publisher publisher) {
        this.publisher = publisher;
    }

    public Date getPublishedDate(a) {
        return publishedDate;
    }

    public void setPublishedDate(Date publishedDate) {
        this.publishedDate = publishedDate; }}Copy the code
  • @table declares the Table of data that this object maps to the database by specifying the names of tables (TALbe), directories (Catalog), and schemas for entities. This annotation is not required; if not, the system uses the default (the short class name of the entity).

  • @id declares this property as the primary key. This attribute value can be created by itself, but Hibernate recommends that it be generated by Hibernate

  • @GeneratedValue specifies the primary key generation strategy.

    1. TABLE: Uses a TABLE to store id values
    2. IDENTITY: identitycolumn
    3. SEQUENCR :sequence
    4. AUTO: Use the preceding three parameters based on the database
  • @column declares the mapping of this property to a database field.

  • @onetomany One-to-many association relationship

  • @manytomany Many-to-many association relationships

  • @joinColumn Specifies the associated field

  • @ JoinTable reference

Spring Data JPA Repository
BookRepository
public interface BookRepository extends JpaRepository<Book.Integer> {}Copy the code
PublisherRepository
public interface PublisherRepository extends JpaRepository<Publisher.Integer> {}Copy the code

Spring Data JPA includes built-in repositories that implement common methods: Findone, FindAll, Save, etc.

application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost/jpa_manytomany_extracolumns
    username: root
    password: admin
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    show-sql: true
    properties:
      hibernate:
        enable_lazy_load_no_trans: true
Copy the code
BookRepositoryTest
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class BookRepositoryTest {

    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private PublisherRepository publisherRepository;


    @Test
    @Transactional
    public void manyToManyExtraColumnsTest(a) throws Exception{
        Book bookA = new Book("Book One");

        Publisher publisherA = new Publisher("Publisher One");

        BookPublisher bookPublisher = new BookPublisher();
        bookPublisher.setBook(bookA);
        bookPublisher.setPublisher(publisherA);
        bookPublisher.setPublishedDate(new Date());
        bookA.getBookPublishers().add(bookPublisher);

        publisherRepository.save(publisherA);
        bookRepository.save(bookA);

        // test
        System.out.println(bookA.getBookPublishers().size());

        // update
        bookA.getBookPublishers().remove(bookPublisher);
        bookRepository.save(bookA);

        // testSystem.out.println(bookA.getBookPublishers().size()); }}Copy the code

The code download

Download it from my Github, github.com/longfeizhen…


https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/2/28/161dbadd0162fdb1~tplv-t2oaga2asx-image.image

🙂🙂🙂 focus on wechat small program Java architect journey Bored on the commute? Still reading novels, news? Don’t know how to improve your skills? Here’s the Java architecture article you need. 1.5W + Java engineers are reading it. What are you waiting for?