JPA introduction summary

Posted by b0gner17 on Thu, 20 Jan 2022 03:23:31 +0100

1. Overview of Hibernate

Hibernate is a Open source of Object relational mapping Frame, it's right JDBC A very lightweight object encapsulation is carried out. It establishes the mapping relationship between POJO and database tables. It is a fully automatic orm framework. Hibernate can automatically generate and execute SQL statements, so that Java programmers can use object programming thinking to manipulate the database at will. Hibernate can be used in any situation where JDBC is used, not only in Java client programs, but also in Servlet/JSP Web applications. The most revolutionary thing is that hibernate can be used in EJB applications JavaEE Replace CMP in architecture, complete Data persistence The important task of.

1. Introduction to JAP

1. Development preparation

	/*Create customer table*/
    CREATE TABLE cst_customer (
      cust_id BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT 'Customer number(Primary key)',
      cust_name VARCHAR(32) NOT NULL COMMENT 'Customer name(corporate name)',
      cust_source VARCHAR(32) DEFAULT NULL COMMENT 'Customer information source',
      cust_industry VARCHAR(32) DEFAULT NULL COMMENT 'Customer industry',
      cust_level VARCHAR(32) DEFAULT NULL COMMENT 'Customer level',
      cust_address VARCHAR(128) DEFAULT NULL COMMENT 'Customer contact address',
      cust_phone VARCHAR(64) DEFAULT NULL COMMENT 'Customer contact number',
      PRIMARY KEY (`cust_id`)
    ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2. Add dependency

 <!--Add dependency-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.hibernate.version>5.0.7.Final</project.hibernate.version>
    </properties>

    <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- hibernate yes jpa Support package for -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>

        <!-- c3p0 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>${project.hibernate.version}</version>
        </dependency>

        <!-- log journal -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- Mysql and MariaDB -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
         <!--add to lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

    </dependencies>

3. Prepare pojo

//Flag entity class
@Entity
//Mapping table
@Table(name = "cst_customer")
//Add get()set method
@Data
public class Customer implements Serializable {
     @Id  //Mark an attribute as a primary key
     @GeneratedValue(strategy = GenerationType.IDENTITY) //Primary key generation side column
     @Column(name = "cust_id")  //Attribute names and table fields are mapped
    private Long    custId;
    @Column(name = "cust_name")
    private String  custName;
    @Column(name = "cust_source")
    private String  custSource;
    @Column(name = "cust_Industry")
    private String  custIndustry;
    @Column(name = "cust_level")
    private String  custIevel;
    @Column(name = "cust_address")
    private String  custAddress;
    @Column(name = "cust_phone")
    private String  custPhone;
}

4. Prepare configuration file

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">

    <!-- Persistence unit
    name: Persistence unit name
    transaction-type: Transaction type
            RESOURCE_LOCAL:  Local transaction
            JTA:  Java Transaction API :  Cross database transactions
    -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!-- Designated provider -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!-- Configuration attribute: four elements of linked database, optional configuration, such as display sql sentence -->
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.93.222:3306/day19?useUnicode=true&amp;characterEncoding=UTF-8"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>

            <!-- display sql sentence -->
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>

</persistence>

5 test

Core steps

	 * Steps:
	 * 	1,Load configuration file to create entity class manager factory
	 * 	2,Create entity class manager through factory
	 * 	3,Get transaction object
	 * 	4,Open transaction
	 * 	5,CRUD: Save customer entity
	 * 	6,Commit transaction
	 * 	7,Release resources

Test code

 @Test
    public void show(){

        Customer customer = new Customer();
        customer.setCustName("Xingjian, be good");
        customer.setCustIevel("Eternal brick");
        //Steps:
	 //1. Load configuration file to create entity class manager factory
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa");

        //2. Create entity class manager through factory
        EntityManager entityManager = factory.createEntityManager();
        //3. Get transaction object
        EntityTransaction tx = entityManager.getTransaction();
        //4. Open transaction
        tx.begin();
     //5. CRUD: save customer entity
        entityManager.persist(customer);
    //6. Commit transaction
        tx.commit();
    //7. Release resources
        entityManager.close();
        factory.close();
    }

6.JPA summary

  1. Create project and add dependency

  2. Create entity classes and create databases

  3. Mapping JPA

    • @Entity class mapping
    • @The mapping parameter name of Table(name = "cst_customer") indicates the table name
    • @Id / / mark an attribute as a primary key
    • @GeneratedValue(strategy = GenerationType.IDENTITY) / / generate the side column of the primary key
    • @Column(name = "cust_id") / / map the attribute name to the table field. The parameter name represents the database field
  4. Configure the core file of JPA

    • File name: persistence xml
    • Table of contents: META-INF
  5. Test save a user

    • Loading configuration file to create entity class management co warehouse
    • Create entity class manager through factory
    • Get transaction object
    • Open transaction object
    • Start transaction
    • CRUD: save user
    • Commit transaction
    • Release resources

3. Introduction to the core API of JPA

1. Persistence importance: General

Function: used to load configuration files and create entity class manager factory
 Main methods:
	createEntityManagerFactory("Persistence unit name")

2. EntityManagerFactory importance: relatively important

Role: used to create entity class manager
 Common methods:
	createEntityManager()
	close()
Details:
	1,This class is a heavyweight class: it maintains all fields CRUD of sql Statement, L2 cache
	2,This class is thread safe. Thread safe concurrency will not occur in a multithreaded environment
 use:
	One web The project should have only one such object

3. EntityManager importance: very important

Function: the interaction with the database is completed by him, and the transaction object is also obtained by him
 Common methods:
	getTransaction()
	persist()
	close
	find
	getReference
	....
Details:
	1,Since the factory has maintained more information, this class maintains less information, so it is a lightweight object
	2,He is thread unsafe
 use:
	A thread has only one object, one request

4. Importance of EntityTransaction: just use it

Role: control transactions
 Common methods:
	begin
	commit
	rollback

4. Tool class for extracting JPA: JpaUtil

public class JpaUtil {

    private static EntityManagerFactory myJpa;

    /*
    * Static loading
    * */
    static {
        myJpa = Persistence.createEntityManagerFactory("myJpa");
    }

    /*
    * Entity class manager
    * */
    public static EntityManager getEntityManager(){
     return myJpa.createEntityManager();
    }

    /*
    * close resource
    * */

    public static void close(EntityManager entityManager){
        if (entityManager!=null){
            entityManager.close();
        }
    }
}


5. CRUD of JPA

1. Add data

    /*
    * Add package
    * */

    @Test
    public void show(){

        Customer customer = new Customer();
        customer.setCustName("Xingjian, be good");
        customer.setCustIevel("VIP");
        EntityManager entityManager = JpaUtil.getEntityManager();
//        //3. Get transaction object
        EntityTransaction tx = entityManager.getTransaction();
        //4. Open transaction
        tx.begin();
     //5. CRUD: save customer entity
        entityManager.persist(customer);
    //6. Commit transaction
        tx.commit();
    //7. Release resources
        JpaUtil.close(entityManager);


    }


2. Delete data

    /*
    * Delete data
    * */
@Test
    public void delete(){
//Get entity class manager
        EntityManager entityManager = JpaUtil.getEntityManager();
//        Get transaction object
        EntityTransaction tx = entityManager.getTransaction();
//Open transaction
        tx.begin();

    Customer customer1 = entityManager.find(Customer.class, 1L);

    entityManager.remove(customer1);
//        Commit transaction
    tx.commit();
//
    JpaUtil.close(entityManager);


    }

3. Update data

    /*
    * Update data
    * */

    @Test
    public void update(){
//        Gets the manager of the entity class
        EntityManager entityManager = JpaUtil.getEntityManager();

//        Get transaction object
        EntityTransaction tx= entityManager.getTransaction();
//        Open transaction
        tx.begin();
//Query before updating
        Customer customer = entityManager.find(Customer.class, 2L);
        customer.setCustName("Here we are, brother");

        entityManager.persist(customer);

//        Commit transaction
        tx.commit();
       JpaUtil.close(entityManager);

    }


4. Query data

     /*
     * Query all data
     * */
    @Test
    public void findList(){
        EntityManager entityManager = JpaUtil.getEntityManager();
        Query query = entityManager.createQuery("from Customer");
        List<Customer> resultList = query.getResultList();
        resultList.forEach(o-> System.out.println("o = " + o));

    }


    /*
    * Query data by id
    * */
    @Test
    public void findById(){

//        Gets the manager of the entity class
        EntityManager entityManager = JpaUtil.getEntityManager();
//Query information according to id
        Customer customer = entityManager.find(Customer.class, 2L);
        System.out.println("customer = " + customer);


    }


6.JPQL query

1.JPQL queries all data

    @Test
    public void show(){

        EntityManager entityManager = JpaUtil.getEntityManager();

        String  sql="from Customer";
        Query query = entityManager.createQuery(sql);

        List resultList = query.getResultList();

        resultList.forEach(o -> System.out.println("o = " + o));

    }

2.JPQL paging query

JPA paging analysis:

mysql: limit ? Query the previous n items

​ limit ? ,?

First parameter: start index = (current page - 1) * page size

Second parameter: page size

    /*
    * paging
    * */
    @Test
    public void show1(){

        EntityManager entityManager = JpaUtil.getEntityManager();
        Query query = entityManager.createQuery("from Customer ");
//        Set paging condition: page size
        query.setFirstResult(1);  //(2-1)*2
        query.setMaxResults(2);

        List resultList = query.getResultList();
        resultList.forEach(p-> System.out.println("p = " + p));


    }

3.JPQL condition query

    /*
    * Multi condition query
    * */
    @Test
    public void show5(){
        EntityManager entityManager = JpaUtil.getEntityManager();
//Create query criteria
        Query query = entityManager.createQuery("from Customer where custName like ? and custIevel= ? ");

        query.setParameter(1,"Xingjian%");
        query.setParameter(2,"VIP");

        List resultList = query.getResultList();
        resultList.forEach(o-> System.out.println("o = " + o));

    }


/*
* Fuzzy query
* */
@Test
    public void show4(){
        EntityManager entityManager = JpaUtil.getEntityManager();
//Create query criteria
        Query query = entityManager.createQuery("from Customer where custName like ?");
//        Assign values to placeholders
    query.setParameter(1,"Xingjian%");

    List resultList = query.getResultList();

    resultList.forEach(p-> System.out.println("p = " + p));

}


    /*
    * Precise query
    * */
    @Test
    public void show3(){
        EntityManager entityManager = JpaUtil.getEntityManager();
//Create query criteria
        Query query = entityManager.createQuery("from Customer where custName= ?");

        query.setParameter(1,"Here we are, brother");

        List resultList = query.getResultList();
        resultList.forEach(p-> System.out.println("p = " + p));


    }

4.JPQL query: sorting, statistical query

    /*
    * sort
    * */
    @Test
    public void show6(){
        EntityManager entityManager = JpaUtil.getEntityManager();
        Query query = entityManager.createQuery("from Customer where custName like ? order by custId desc");

        query.setParameter(1,"Xingjian%");

        List resultList = query.getResultList();
        resultList.forEach(o-> System.out.println("o = " + o));
    }

    /**
     * Statistics query: one row, one column: one number
     */
    @Test
    public void test5() {
        EntityManager em = JpaUtil.getEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //Statistics
        /**
         * select count(*) Approximately equal to count (1) mysql5 After 7
         * select count(id)
         * select count(1)
         */
        Query query = em.createQuery("select avg(custId) from Customer where custName like ?");
        //Assign values to placeholders
        query.setParameter(1, "Xingjian%");

        //Get result set
        List<Double> list = query.getResultList();
        //iteration
        for (Double l : list) {
            System.out.println("============================="+l);
        }
    }



2. Getting started with springdatejpa

1. Introduction to JPA

1. Import dependency

    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
        <hibernate.version>5.0.7.Final</hibernate.version>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <c3p0.version>0.9.1.2</c3p0.version>
        <mysql.version>5.1.18</mysql.version>
    </properties>

    <dependencies>
        <!-- junit unit testing  -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- spring beg -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- spring end -->

        <!-- hibernate beg -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.1.Final</version>
        </dependency>
        <!-- hibernate end -->

        <!-- c3p0 beg -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>${c3p0.version}</version>
        </dependency>
        <!-- c3p0 end -->

        <!-- log end -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- log end -->


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!-- SpringDataJpa Core package -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.9.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- el beg use spring data jpa Must be introduced -->
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>javax.el-api</artifactId>
            <version>2.2.4</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.web</groupId>
            <artifactId>javax.el</artifactId>
            <version>2.2.4</version>
        </dependency>
        <!-- el end -->

<!--add to lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>

    </dependencies>

2. Preparation of documents

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
      http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">


    <!-- SpringDataJpa to configure -->
    <!-- 1,EntityManagerFactory hand spring Administration-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!-- 1,Scan packages for entity classes -->
        <property name="packagesToScan" value="com.xjggb.pojo"></property>
        <!-- 2,Reference data source -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- 3,to configure jpa Provider of -->
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
        </property>
        <!-- 4,jpa Provider's adapter-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="false" />
                <property name="database" value="MYSQL" />
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
                <property name="showSql" value="true" />
            </bean>
        </property>
        <!-- 5,JPA dialect:have access to jpa Advanced features of -->
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"></bean>
        </property>
        <!-- 6,Give Way hibenrate Maintenance table structure -->
        <property name="jpaProperties">
            <props>
                <!--
                create: Every time, delete the table first and then create the table
                update: If there are changes and the attributes and fields are inconsistent, update the table; If there is no table, the table is created
                none: It's the same as no configuration. Do nothing
                 -->
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>
    <!-- 2,Configure data sources -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://192.168.93.222:3306/day19"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
    <!-- 3,Platform transaction manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>


    <!-- 4,SpringDataJpa Configuration of
    base-package: Base package: dao Package where the interface is located
    entity-manager-factory-ref:  Reference entity class manager factory
    transaction-manager-ref: Platform transaction manager
    -->
    <jpa:repositories base-package="com.xjggb.mapper" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"></jpa:repositories>
    <!-- 5,Turn on scanning of components-->
    <context:component-scan base-package="com.xjggb"></context:component-scan>

</beans>

be careful

 <!-- 6,Give Way hibenrate Maintenance table structure -->
        <property name="jpaProperties">
            <props>
                <!--
                create: Each time, delete the table before creating it
                update: If there are changes and the attributes and fields are inconsistent, update the table; If there is no table, the table is created
                none: It's the same as no configuration. Do nothing
                 -->
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>

3. Write entity class

package com.xjggb.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name="cst_customer")
@Data
public class Customer implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="cust_id")
    private Long custId;

    @Column(name="cust_name")
    private String custName;

    @Column(name="cust_source")
    private String custSource;

    @Column(name="cust_industry")
    private String custIndustry;

    @Column(name="cust_level")
    private String custLevel;

    @Column(name="cust_address")
    private String custAddress;

    @Column(name="cust_phone")
    private String custPhone;

}


4. Write Mapper interface

public interface CustomerMapper extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
}

5. Test

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest {

    @Autowired
    private CustomerMapper customerMapper;

    /*
    * Query an object
    * */
    @Test
    public void show(){

        Customer one = customerMapper.findOne(2L);

        System.out.println("one = " + one);
    }
    
}

2.JPA -CRUD

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest2 {

    @Autowired
    private CustomerMapper customerMapper;





    /*
    * Add object
    * */
    @Test
    public void show(){
        Customer customer = new Customer();
        customer.setCustName("sweet stewed snow pear");
        customer.setCustLevel("Strong mouth King");
        customerMapper.save(customer);

    }

    /*
    * Delete data
    * */
    @Test
    public void show1(){
   customerMapper.delete(4L);
    }


    /*
    * Update data
    * */
@Test
    public void show3(){
     //Query before updating
        Customer one = customerMapper.findOne(2L);
        one.setCustName("My name is Xingjian Guaiba");
        System.out.println("one = " + one);
        customerMapper.save(one);


    }

    /*
    * Query all data
    * */

    @Test
    public void show4(){
     //Query all data
        List<Customer> all = customerMapper.findAll();
        all.forEach(p-> System.out.println("p = " + p));

    }
}


Summary
  1. Create maven project
  2. Write the spring configuration file ApplicationContext XML file
  3. Write annotations for configuration class jpa
  4. Write mapper interface to inherit two interfaces 1 Jparepository < entity class, primary key type > 2 Jpaspecificationexecutor < entity class >
  5. Test CRUD

3. Interface method definition query

1. Two ways to query a

    /*
    * Two ways to query a
    * */

    @Test
    @Transactional
    public void show(){

//        Customer one = customerMapper.findOne(3L);// Load now
        Customer one = customerMapper.getOne(3L);
        System.out.println("one = " + one);  //
    }


2. Paging query + Sorting Query

   /*
    * Paging query
    * */
    @Test
    public void show2(){
        /*
        * Paging query
        * Parameter I current page 
        * Parameter 2 page size
        * Parameter 3 sorting object [optional]
        * */
        PageRequest pageRequest = new PageRequest(2,2);

//Execute paging query
        Page<Customer> all = customerMapper.findAll(pageRequest);
        System.out.println("Get total records " + all.getTotalElements());
        System.out.println("PageCount " + all.getTotalPages());

        List<Customer> content = all.getContent();
        for (Customer customer : content) {
            System.out.println("customer = " + customer);
        }


    }



    /*
    * Paging query + Sorting Query
    * */
    @Test
    public void show2(){

//        Collation flashback
        Sort orders = new Sort(Sort.Direction.DESC,"custId");

        /*
        * Paging query
        * Parameter I current page
        * Parameter 2 page size
        * Parameter 3 sort object
        * */
        PageRequest pageRequest = new PageRequest(2,2,orders);

//Execute paging query
        Page<Customer> all = customerMapper.findAll(pageRequest);
        System.out.println("Get total records " + all.getTotalElements());
        System.out.println("PageCount " + all.getTotalPages());

        List<Customer> content = all.getContent();
        for (Customer customer : content) {
            System.out.println("customer = " + customer);
        }


    }



3. Query statistics and judge whether the object exists

    /*
    * Statistics all\
    * This is equivalent to the select count(*) from table
    * */

    @Test
    public void show4(){

        long count = customerMapper.count();
        System.out.println("count = " + count);
    }



    /*
    * Determine whether an object exists
    * The presence is true and the absence is false
    * Equivalent to select * from table where id =?
    * */
    @Test
    public void show3(){
        boolean exists = customerMapper.exists(4L);
        System.out.println("equals = " + exists);
    }


4.JPQL query operation

1. Mode 1 query operation

Master @ Query annotation

JPQL query rules:

	1)stay dao Write methods in the interface
	2)Use on method@Query(value="JPQL sentence")
	3)The return value is determined by yourself. If it is a single object, you write a single object. If there are multiple objects, you use List

mapper code

  /*
    * Precise query
    * */
    @Query(value="from Customer  where  custName= ?")
    Customer findJPQL1(String l);

    /*
    *Fuzzy query
    * */
    @Query(value="from Customer where custName like ?")
    List<Customer> findListJPQL(String s);

    /*
    * Multi condition query
     * By default: all of the method parameters are consistent with the index of the placeholder. If the data types are inconsistent, an error will be reported
     * We can change the index manually: just add the index of the method parameter after the placeholder
    * */
    @Query(value="from Customer where custId =?2 or custName like ?1")
    List<Customer> findJPQL3(String o ,Long id);




test

package com.xjggb.test;

import com.xjggb.mapper.CustomerMapper;
import com.xjggb.pojo.Customer;
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.List;

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest4 {

    @Autowired
    private CustomerMapper customerMapper;


    /*
     * Precise query
     * */
    @Test
    public void show2(){
        Customer customer = customerMapper.findJPQL1("sweet stewed snow pear");
        System.out.println("customer = " + customer);
    }


    /*
     * Fuzzy query
     * */
    @Test
    public void show(){
        List<Customer> listJPQL = customerMapper.findListJPQL("Xingjian%");
        listJPQL.forEach(u-> System.out.println("u = " + u));

        System.out.println();
    }


    /*
     *Multi condition query
     * */
    @Test
    public void show3(){
        List<Customer> jpql3 = customerMapper.findJPQL3("Xingjian%", 3L);
        jpql3.forEach(o-> System.out.println("o = " + o));
        System.out.println();
    }

}



2. Method 2: query and update

Objective: to master how to use JPQL to update objects

dao interface requirements:

1) jpql statement of update written in the value attribute of Query

2) You need to add a comment on the method of dao interface: @ Modifying

Test requirements:

1) Transaction required

2) In the testing phase, if spring testing is used, it will be rolled back automatically after successful execution. If you see the effect, you need to add comments: @ Rollback(false)

mapper code

    /*
    * update operation
    * */
    @Modifying //Mark as update operation
    @Query(value="update Customer set custName=?2 where custId=?1")
    void updateJPQL(Long id ,String nmae);

Test code

    /*
    * update operation
    * */

    @Test
    //Since we are now using the spring test, after the test is successful, spring rolls back to us
    //In the test phase, if you want to see the results, you need to add another annotation. Note that this annotation does not need to be added in non test code
    //TransactionRequiredException: Executing an update/delete query transaction exception

    @Transactional
    @Rollback(false)
    public void show4(){
    customerMapper.updateJPQL(2L,"Lao Wang next door");

    }


3. Method 3: sql query

sql query rules

	1)stay dao Write methods in the interface
	2)Use on method@Query(value="SQL sentence",nativeQuery=true)nativeQuery=true open sql Statement query
	3)The return value is determined by yourself. If it is a single object, you write a single object. If there are multiple objects, you use List

mapper code

    /**
     * sql query
     * nativeQuery=true  Open sql query
     */
    @Query(value="select * from cst_customer where cust_name like ?2 or cust_id = ?1",nativeQuery=true)
    public List<Customer> findSQL(Long id, String name);


Test code

    /*
    * sql query
    * */
    @Test
    public void show5(){
        List<Customer> sql = customerMapper.findSQL(3L, "Xingjian%");
        sql.forEach(o-> System.out.println("o = " + o));
    }


4. Method 4: query according to method name rules

Method name rule of Dao interface:

	1)with findBy start
	2)Followed by the attribute condition of the query: the initial letter of the attribute name is capitalized
	3)The attribute name is followed by the query rule: fuzzy[ Like],Accurate [irregular represents accurate query]
	4)Multiple conditions to  And , Or Splicing
	5)Repeat the above steps, starting from 2

mapper interface

//    Precise query
    Customer findByCustName(String name);

//    Fuzzy query
    List<Customer> findByCustNameLike(String name);

//    Multi condition query
    List<Customer> findByCustNameOrCustId(String name , Long id);

test

    /*
    * Multi condition query
    * */
    @Test
    public void show8(){

        List<Customer> p = customerMapper.findByCustNameOrCustId("sweet stewed snow pear", 8L);
        p.forEach(o-> System.out.println("o = " + o));
    }



    /*
    * Precise query
    * */
    @Test
    public void show7(){
        Customer o = customerMapper.findByCustName("sweet stewed snow pear");
        System.out.println("o = " + o);
    }

    /*
    * Fuzzy query
    * */
    @Test
    public void show6(){

        List<Customer> byCustNameLike = customerMapper.findByCustNameLike("Xingjian%");
        byCustNameLike.forEach(o->System.out.println("byCustNameLike = " + o));
    }


Keywords for rule:

KeywordMethod name exampleJPQL
AndfindByLastnameAndFirstname... where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname... where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstnameIs, findByFirstnameEquals... where x.firstname = ?1
BetweenfindByStartDateBetween... where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan... where x.age < ?1
LessThanEqualfindByAgeLessThanEqual... where x.age ⇐ ?1
GreaterThanfindByAgeGreaterThan... where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual... where x.age >= ?1
AfterfindByStartDateAfter... where x.startDate > ?1
BeforefindByStartDateBefore... where x.startDate < ?1
IsNullfindByAgeIsNull... where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull... where x.age not null
LikefindByFirstnameLike... where x.firstname like ?1
NotLikefindByFirstnameNotLike... where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith... where x.firstname like ?1 (parameter bound with appended %)
EndingWithfindByFirstnameEndingWith... where x.firstname like ?1 (parameter bound with prepended %)
ContainingfindByFirstnameContaining... where x.firstname like ?1 (parameter bound wrapped in %)
OrderByfindByAgeOrderByLastnameDesc... where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot... where x.lastname <> ?1
InfindByAgeIn(Collection ages)... where x.age in ?1
NotInfindByAgeNotIn(Collection age)... where x.age not in ?1
TRUEfindByActiveTrue()... where x.active = true
FALSEfindByActiveFalse()... where x.active = false
IgnoreCasefindByFirstnameIgnoreCase... where UPPER(x.firstame) = UPPER(?1)

3. Introduction to specification dynamic query

Introduction to jpaspecification executor interface: complete complex query and dynamic query

JpaSpecificationExecutor<T> {
	T findOne(Specification<T> spec);
	List<T> findAll(Specification<T> spec);
	Page<T> findAll(Specification<T> spec, Pageable pageable);
	List<T> findAll(Specification<T> spec, Sort sort);
	long count(Specification<T> spec);
}

Specification: it is an interface. All dynamic splicing conditions are completed in the method of this interface

public interface Specification<T> {
	Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
}

It has only one method: toPredicate, which has three parameters

The first: Root: to get the properties of the object

The second: CriteriaQuery: the top-level interface of query. It can complete custom query, which is generally not used

The third: CriteriaBuilder: dynamically build query conditions and use it

1.Specification query: accurate, fuzzy and multi condition query

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest5 {

    @Autowired
    private CustomerMapper customerMapper;
    /*
    * Multi condition query
    * */

    @Test
    public void show(){
        Specification<Customer> spec = new Specification<Customer>() {
            @Override
            public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cd) {

//                Get comparison properties
                Path<String> custName = root.get("custName");
                Path<Object> custLevel = root.get("custLevel");

//                Build query criteria
                Predicate like = cd.like(custName, "Xingjian%");
                Predicate equal = cd.equal(custLevel, "VIP");

//                Merge query criteria
                Predicate or = cd.or(like, equal);
                return or;
            }
        };


        List<Customer> all = customerMapper.findAll(spec);
        all.forEach(o-> System.out.println("o = " + o));
    }
}


2.Specification query: paging and sorting query

    /*
    * Paging sort
    * */

    @Test
    public void show2(){
//        Equivalent to where
        Specification<Customer> spec =null;


//        sort
        Sort orders = new Sort(Sort.Direction.DESC,"custId");

//        paging
        PageRequest pageRequest = new PageRequest(0, 2, orders);


        Page<Customer> all = customerMapper.findAll(spec, pageRequest);

        System.out.println("Get total records " + all.getTotalElements());
        System.out.println("Get pages" + all.getTotalPages());
        all.getContent().forEach(o-> System.out.println("o = " + o));


    }

4. One to many mapping

1. One to many one-way saving

1. Step 1

One to many using the carry in method

Customer table   :  One customer can have multiple contacts
 Contact list :  One contact can only belong to one company

2. Step 2

Find the main foreign key

Multi party [slave table]: foreign keys are in multiple parties

Primary table of one party: the value of the foreign key comes from the primary key of one party

3. Step 3:

Describe their relationships in entity classes

Class to class relationships: Inheritance and inclusion

We use inclusion

Customer contains multiple contacts: List / Set

The contact contains a contact Customer

Customer entity class code

package com.xjggb.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name="cst_customer")
@Data
public class Customer implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="cust_id")
    private Long custId;

    @Column(name="cust_name")
    private String custName;

    @Column(name="cust_source")
    private String custSource;

    @Column(name="cust_industry")
    private String custIndustry;

    @Column(name="cust_level")
    private String custLevel;

    @Column(name="cust_address")
    private String custAddress;

    @Column(name="cust_phone")
    private String custPhone;

    //Currently on one side
    /**
     * new :
     * 		1,If new finds the current method, the collection will also be instantiated
     * 		2,In order to solve the possible null pointer exception, new, we can specify the size of the new when new
     *
     * Not new:
     * 		Containers are used to hold contact entities
     * 		customer.getLinkman().add(new Linkman())
     * 		Null pointer exception may occur
     *
     */

//  Configure one to many relationship annotations
    //Configure one to many
     @OneToMany(targetEntity = Linkman.class)
//     Configure foreign key annotations

     @JoinColumn(
//             Foreign key name
             name = "lkm_cust_id",
//             Source of foreign key value: from the primary key of the primary table
             referencedColumnName = "cust_id"
     )
    private Set<Linkman> linkmen=new HashSet<>(0);


}


Linkman contact entity class

package com.xjggb.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "cst_linkman")
@Data
public class Linkman implements Serializable {

    @Id
    @Column(name="lkm_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long lkmId;

    @Column(name="lkm_name")
    private String lkmName;

    @Column(name="lkm_gender")
    private String lkmGender;

    @Column(name="lkm_phone")
    private String lkmPhone;

    @Column(name="lkm_mobile")
    private String lkmMobile;

    @Column(name="lkm_email")
    private String lkmEmail;

    @Column(name="lkm_position")
    private String lkmPosition;

    @Column(name="lkm_memo")
    private String lkmMemo;




    //At present, there are many parties
//    Relationship annotation many to one
    @ManyToOne(targetEntity = Customer.class)
//    Foreign key annotation
    @JoinColumn(
//             Foreign key name
            name = "lkm_cust_id",
//             Source of foreign key value: from the primary key of the main table
            referencedColumnName = "cust_id"
    )

    private Customer customer;

}


4. Step 4

package com.xjggb.test;

import com.xjggb.mapper.CustomerMapper;
import com.xjggb.mapper.LinkmanMapper;
import com.xjggb.pojo.Customer;
import com.xjggb.pojo.Linkman;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest6 {

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private LinkmanMapper linkmanMapper;

	/**
	 * One way save:
	 * 		One to many saving principle: save the data of the master table first, and then save the data of the slave table
	 */
    @Test
    @Transactional
@Rollback(false)
    public void show(){

        Customer customer = new Customer();
        customer.setCustName("Xingjian, be good");

        Linkman linkman = new Linkman();
        linkman.setLkmName("I'm Xingjian");
        linkman.setLkmPosition("CEO");
//To have a value for a foreign key, you must configure the relationship:
        //1. Let the customer maintain the relationship: the customer maintains the foreign key through the update statement
       // customer.getLinkmen().add(linkman);

        //2. Let the contact maintain foreign keys: the contact can maintain foreign keys through the insert statement [let the contact maintain foreign keys efficiently without the update statement]
       linkman.setCustomer(customer);

        //Save: save the data of the master table first, and then save the data of the slave table

//        Save the data of the master table and save the number of slave tables
        customerMapper.save(customer);

       linkmanMapper.save(linkman);


    }


}


2. One pair of two-way bao storage

analysis

If it is a two-way save, there will be two insert And one update

Reason: the extra one update Statement, which is caused by the maintenance of foreign keys by customers

solve:
	I don't want to see the extra one update Statement of
	Let customers do not maintain foreign keys
	delete@JoinColumn annotation

1. Customer entity

package com.xjggb.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;



/**
 * Entity class
 * @author Johnny.Chen
 *
 */

@Entity
@Table(name="cst_customer")
public class Customer implements Serializable{

    @Id
    @Column(name="cust_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long custId;

    @Column(name="cust_name")
    private String custName;

    @Column(name="cust_source")
    private String custSource;

    @Column(name="cust_level")
    private String custLevel;

    @Column(name="cust_industry")
    private String custIndustry;

    @Column(name="cust_phone")
    private String custPhone;

    @Column(name="cust_address")
    private String custAddress;


    //Currently on one side
    /**
     * new :
     * 		1,If new finds the current method, the collection will also be instantiated
     * 		2,In order to solve the possible null pointer exception, new, we can specify the size of the new when new
     *
     * Not new:
     * 		Containers are used to hold contact entities
     * 		customer.getLinkman().add(new Linkman())
     * 		Null pointer exception may occur
     *
     */
    //Configure one to many relationship annotations
    //Customer maintenance foreign key
	/*//1,Relationship annotation: one to many
	@OneToMany(targetEntity=Linkman.class)
	//2,Foreign key annotation
	@JoinColumn(
			//Foreign key name
			name="lkm_cust_id",
			//Source of foreign key value: from the primary key of the primary table
			referencedColumnName="cust_id"
	)*/

    //The customer does not maintain foreign keys
    @OneToMany(mappedBy="customer")//mappedBy: the name of the attribute with @ JoinColumn annotation on the other side of the configuration
    private Set<Linkman> linkmans = new HashSet<>(0);

    /**
     * obtain
     * @return custId
     */
    public Long getCustId() {
        return custId;
    }

    /**
     * set up
     * @param custId
     */
    public void setCustId(Long custId) {
        this.custId = custId;
    }

    /**
     * obtain
     * @return custName
     */
    public String getCustName() {
        return custName;
    }

    /**
     * set up
     * @param custName
     */
    public void setCustName(String custName) {
        this.custName = custName;
    }

    /**
     * obtain
     * @return custSource
     */
    public String getCustSource() {
        return custSource;
    }

    /**
     * set up
     * @param custSource
     */
    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    /**
     * obtain
     * @return custLevel
     */
    public String getCustLevel() {
        return custLevel;
    }

    /**
     * set up
     * @param custLevel
     */
    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    /**
     * obtain
     * @return custIndustry
     */
    public String getCustIndustry() {
        return custIndustry;
    }

    /**
     * set up
     * @param custIndustry
     */
    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }

    /**
     * obtain
     * @return custPhone
     */
    public String getCustPhone() {
        return custPhone;
    }

    /**
     * set up
     * @param custPhone
     */
    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }

    /**
     * obtain
     * @return custAddress
     */
    public String getCustAddress() {
        return custAddress;
    }

    /**
     * set up
     * @param custAddress
     */
    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }

    /**
     * obtain
     * @return linkmans
     */
    public Set<Linkman> getLinkmans() {
        return linkmans;
    }

    /**
     * set up
     * @param linkmans
     */
    public void setLinkmans(Set<Linkman> linkmans) {
        this.linkmans = linkmans;
    }

}


2. Contact entity class

package com.xjggb.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;


/**
 * contacts
 * @author Johnny.Chen
 *
 */

@Entity
@Table(name="cst_linkman")
public class Linkman implements Serializable{

    @Id
    @Column(name="lkm_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long lkmId;

    @Column(name="lkm_name")
    private String lkmName;

    @Column(name="lkm_gender")
    private String lkmGender;

    @Column(name="lkm_phone")
    private String lkmPhone;

    @Column(name="lkm_mobile")
    private String lkmMobile;

    @Column(name="lkm_email")
    private String lkmEmail;

    @Column(name="lkm_position")
    private String lkmPosition;

    @Column(name="lkm_memo")
    private String lkmMemo;


    //At present, there are many parties
    //1. Relationship annotation: many to one
    @ManyToOne(targetEntity=Customer.class)
    //2. Foreign key annotation
    @JoinColumn(
            //Foreign key name
            name="lkm_cust_id",
            //Source of foreign key value: from the primary key of the primary table
            referencedColumnName="cust_id"
    )
    private Customer customer;

    /**
     * obtain
     * @return lkmId
     */
    public Long getLkmId() {
        return lkmId;
    }

    /**
     * set up
     * @param lkmId
     */
    public void setLkmId(Long lkmId) {
        this.lkmId = lkmId;
    }

    /**
     * obtain
     * @return lkmName
     */
    public String getLkmName() {
        return lkmName;
    }

    /**
     * set up
     * @param lkmName
     */
    public void setLkmName(String lkmName) {
        this.lkmName = lkmName;
    }

    /**
     * obtain
     * @return lkmGender
     */
    public String getLkmGender() {
        return lkmGender;
    }

    /**
     * set up
     * @param lkmGender
     */
    public void setLkmGender(String lkmGender) {
        this.lkmGender = lkmGender;
    }

    /**
     * obtain
     * @return lkmPhone
     */
    public String getLkmPhone() {
        return lkmPhone;
    }

    /**
     * set up
     * @param lkmPhone
     */
    public void setLkmPhone(String lkmPhone) {
        this.lkmPhone = lkmPhone;
    }

    /**
     * obtain
     * @return lkmMobile
     */
    public String getLkmMobile() {
        return lkmMobile;
    }

    /**
     * set up
     * @param lkmMobile
     */
    public void setLkmMobile(String lkmMobile) {
        this.lkmMobile = lkmMobile;
    }

    /**
     * obtain
     * @return lkmEmail
     */
    public String getLkmEmail() {
        return lkmEmail;
    }

    /**
     * set up
     * @param lkmEmail
     */
    public void setLkmEmail(String lkmEmail) {
        this.lkmEmail = lkmEmail;
    }

    /**
     * obtain
     * @return lkmPosition
     */
    public String getLkmPosition() {
        return lkmPosition;
    }

    /**
     * set up
     * @param lkmPosition
     */
    public void setLkmPosition(String lkmPosition) {
        this.lkmPosition = lkmPosition;
    }

    /**
     * obtain
     * @return lkmMemo
     */
    public String getLkmMemo() {
        return lkmMemo;
    }

    /**
     * set up
     * @param lkmMemo
     */
    public void setLkmMemo(String lkmMemo) {
        this.lkmMemo = lkmMemo;
    }

    /**
     * obtain
     * @return customer
     */
    public Customer getCustomer() {
        return customer;
    }

    /**
     * set up
     * @param customer
     */
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

}


3. Test

package com.xjggb.test;

import com.xjggb.mapper.CustomerMapper;
import com.xjggb.mapper.LinkmanMapper;
import com.xjggb.pojo.Customer;
import com.xjggb.pojo.Linkman;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest6 {

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private LinkmanMapper linkmanMapper;


    /*
    * Bidirectional binding
    * */


    /**
     * Bidirectional save:
     * 		One to many saving principle: save the data of the master table first, and then save the data of the slave table
     *
     * You know me, and I know you
     */
    @Test
    //To resolve the exception: join the transaction first
    @Transactional
    //Because during the test phase, spring rolls back
    @Rollback(false)
    public void test() {
        Customer c = new Customer();
        c.setCustName("Akagi tempered glass company");

        Linkman l = new Linkman();
        l.setLkmName("Qingzi");
        l.setLkmPosition("CEO");

        //To have a value for a foreign key, you must configure the relationship: bidirectional
     c.getLinkmans().add(l);
        l.setCustomer(c);

        //Save: save the data of the master table first, and then save the data of the slave table
        customerMapper.save(c);
        linkmanMapper.save(l);
    }


}


3. One to many deletion

1) No data reference from the table: delete casually

2) There are slave table data
a. Under the default [maintain foreign keys by both parties], it will set the foreign key field to null, and then delete the main table data. If there is a non NULL constraint on the foreign key field in the table structure of the database, an error will be reported by default.
b. If it is configured to give up the right to maintain the association relationship, it cannot be deleted (it has nothing to do with whether the foreign key field is allowed to be null), because it will not update the foreign key field of the slave table at all.
c. If you also want to delete, use cascading to delete references

  • Configure where you operate [we delete the customer, so configure it on the customer side and cascade it in the relationship annotation]
  • Use with caution

1. Entity class configuration

package com.xjggb.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;



/**
 * Entity class
 * @author Johnny.Chen
 *
 */

@Entity
@Table(name="cst_customer")
public class Customer implements Serializable{

    @Id
    @Column(name="cust_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long custId;

    @Column(name="cust_name")
    private String custName;

    @Column(name="cust_source")
    private String custSource;

    @Column(name="cust_level")
    private String custLevel;

    @Column(name="cust_industry")
    private String custIndustry;

    @Column(name="cust_phone")
    private String custPhone;

    @Column(name="cust_address")
    private String custAddress;


    //Currently on one side
    /**
     * new :
     * 		1,If new finds the current method, the collection will also be instantiated
     * 		2,In order to solve the possible null pointer exception, new, we can specify the size of the new when new
     *
     * Not new:
     * 		Containers are used to hold contact entities
     * 		customer.getLinkman().add(new Linkman())
     * 		Null pointer exception may occur
     *
     */
    //Configure one to many relationship annotations
    //Customer maintenance foreign key
	/*//1,Relationship annotation: one to many
	@OneToMany(targetEntity=Linkman.class)
	//2,Foreign key annotation
	@JoinColumn(
			//Foreign key name
			name="lkm_cust_id",
			//Source of foreign key value: from the primary key of the primary table
			referencedColumnName="cust_id"
	)*/

    //The customer does not maintain foreign keys
    @OneToMany(
            mappedBy="customer",//mappedBy: the name of the attribute with @ JoinColumn annotation on the other side of the configuration
            cascade = CascadeType.ALL//Cascade save update delete
    )
    private Set<Linkman> linkmans = new HashSet<>(0);

    /**
     * obtain
     * @return custId
     */
    public Long getCustId() {
        return custId;
    }

    /**
     * set up
     * @param custId
     */
    public void setCustId(Long custId) {
        this.custId = custId;
    }

    /**
     * obtain
     * @return custName
     */
    public String getCustName() {
        return custName;
    }

    /**
     * set up
     * @param custName
     */
    public void setCustName(String custName) {
        this.custName = custName;
    }

    /**
     * obtain
     * @return custSource
     */
    public String getCustSource() {
        return custSource;
    }

    /**
     * set up
     * @param custSource
     */
    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    /**
     * obtain
     * @return custLevel
     */
    public String getCustLevel() {
        return custLevel;
    }

    /**
     * set up
     * @param custLevel
     */
    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    /**
     * obtain
     * @return custIndustry
     */
    public String getCustIndustry() {
        return custIndustry;
    }

    /**
     * set up
     * @param custIndustry
     */
    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }

    /**
     * obtain
     * @return custPhone
     */
    public String getCustPhone() {
        return custPhone;
    }

    /**
     * set up
     * @param custPhone
     */
    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }

    /**
     * obtain
     * @return custAddress
     */
    public String getCustAddress() {
        return custAddress;
    }

    /**
     * set up
     * @param custAddress
     */
    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }

    /**
     * obtain
     * @return linkmans
     */
    public Set<Linkman> getLinkmans() {
        return linkmans;
    }

    /**
     * set up
     * @param linkmans
     */
    public void setLinkmans(Set<Linkman> linkmans) {
        this.linkmans = linkmans;
    }

    public String toString() {
        return "Customer{custId = " + custId + ", custName = " + custName + ", custSource = " + custSource + ", custLevel = " + custLevel + ", custIndustry = " + custIndustry + ", custPhone = " + custPhone + ", custAddress = " + custAddress + ", linkmans = " + linkmans + "}";
    }
}


2. Test

package com.xjggb.test;

import com.xjggb.mapper.CustomerMapper;
import com.xjggb.pojo.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest7 {

    @Autowired
    private CustomerMapper customerMapper;


    @Test
    @Transactional
    @Rollback(false)
    public void show(){
//a. Under the default [maintain foreign keys by both parties], it will set the foreign key field to null, and then delete the main table data. If there is a non NULL constraint on the foreign key field in the database table structure, an error will be reported by default.
        //b. If it is configured to give up the right to maintain the association relationship, it cannot be deleted (it has nothing to do with whether the foreign key field is allowed to be null), because it will not update the foreign key field of the slave table at all.
        //c. If you also want to delete, use cascading to delete references
        /**
         * Cascade operation:
         * 		When we operate an object, let the code secretly operate another object in the background
         * Cascade delete:
         * 		When we delete a customer, let the code delete its associated contact attribute first, and then delete the main table data
         *
         * Configuration cascade: [use with caution] [Zhulian nine families]
         * 		1,We configure cascades where we operate. We delete customers now, so we configure cascades where customers are
         * 		2,Configure cascading in relationship annotations:
         * 			@OneToMany(cascade=CascadeType.ALL)       Cascade save update delete
         * 			@OneToMany(cascade=CascadeType.PERSIST)   Cascade save
         * 			@OneToMany(cascade=CascadeType.MERGE)	     update cascade 
         * 			@OneToMany(cascade=CascadeType.REMOVE)    cascading deletion
         *
         */
        customerMapper.delete(1L);


    }

}


Summary

1. Relationship notes:

@OneToMany(mappedBy = "attribute name with @ JoinColumn annotation on the other side", targeenity = "", cascade = "")

@ManyToOne(targeEntity="",cascade = "") / / mappedBy cannot be configured. You cannot give up your foreign key maintenance

2. Maintain foreign key annotation: whoever has it can maintain foreign keys

@JoinColumn(name = "foreign key name", referenceColumnName = "primary key name of main table")

3. Operations: save and delete

Key point finding foreign key

5. Many to many mapping

1. Many to many save

1. Step 1

User: a user can have multiple roles

Role: you can have multiple users

Many to many relationship

2. Step 2

Find the middle table

User table

Role table

Intermediate table of user role, two columns, primary key of source user table and role table, and joint primary key

3. Step 3

A user has multiple roles:

A role contains multiple users:

User entity class

package com.xjggb.pojo;


import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author Johnny.Chen
 *
 */
@Entity
//@Table(name="User") / / if the table name is the same as the class name, it can be omitted
public class User implements Serializable {

    @Id
    //@Column(name="userId") / / if the field name is the same as the property name, it can be omitted
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer userId;

    private String name;
    private String age;
    private String pwd;

    //A user contains multiple roles
//    Relational annotation configuration many to many
    @ManyToMany(targetEntity = Role.class)

//    Maintain intermediate table notes
    @JoinTable(
            name = "T_user_Role_Ref" , //Intermediate table name
//            Foreign key of the current intermediate table
            joinColumns = @JoinColumn(name = "u_id",referencedColumnName = "userId"),
//            Foreign key of the opposite party in the middle table
            inverseJoinColumns = @JoinColumn(name = "r_id",referencedColumnName = "roleId")

    )

    private Set<Role> roles = new HashSet<>(0);



    public Set<Role> getRoles() {
        return roles;
    }
    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
    public Integer getUserId() {
        return userId;
    }
    public void setUserId(Integer userId) {
        this.userId = userId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    @Override
    public String toString() {
        return "User [userId=" + userId + ", name=" + name + ", age=" + age + ", pwd=" + pwd + "]";
    }

}


Role class

package com.xjggb.pojo;


import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
public class Role {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer roleId;
    private String roleName;
//
//    //A role contains multiple users
//    @ManyToMany(targetEntity =User.class )
    Maintain intermediate table notes
//    @JoinTable(
//            name = "T_user_Role_Ref", / / intermediate table name
            Foreign key of the current intermediate table
//            joinColumns = @JoinColumn(name = "r_id",referencedColumnName = "roleId"),
            Foreign key of the opposite party in the middle table
//            inverseJoinColumns = @JoinColumn(name = "u_id",referencedColumnName = "userId")



    @ManyToMany(
            mappedBy = "roles",
            cascade = CascadeType.ALL //Cascade operation

    )
    private Set<User> users = new HashSet<>(0);



    public Set<User> getUsers() {
        return users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }
    public Integer getRoleId() {
        return roleId;
    }
    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
    public String getRoleName() {
        return roleName;
    }
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    @Override
    public String toString() {
        return "Role [roleId=" + roleId + ", roleName=" + roleName + "]";
    }



}



4. Step 4

test

package com.xjggb.test;

import com.xjggb.mapper.CustomerMapper;
import com.xjggb.mapper.RoleMapper;
import com.xjggb.mapper.UserMapper;
import com.xjggb.pojo.Customer;
import com.xjggb.pojo.Role;
import com.xjggb.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest8 {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;



    /*
     *
     * */

    @Test
    @Transactional
    @Rollback(false)
    public void show(){

        User user = new User();
        user.setName("Mitsui Shou");


        Role role = new Role();
        role.setRoleName("dentist");

//        Anyone who gives up can maintain an intermediate table with only one table, otherwise the error Duplicate entry '1-1' for key 'PRIMARY' will be reported
        role.getUsers().add(user);

        user.getRoles().add(role);


        userMapper.save(user);
        roleMapper.save(role);


    }

}


2. Many to many deletion

Entity class

package com.xjggb.pojo;


import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
public class Role {

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Integer roleId;
    private String roleName;
//
//    //A role contains multiple users
//    @ManyToMany(targetEntity =User.class )
    Maintain intermediate table notes
//    @JoinTable(
//            name = "T_user_Role_Ref", / / middle table name
            Foreign key of the current intermediate table
//            joinColumns = @JoinColumn(name = "r_id",referencedColumnName = "roleId"),
            Foreign key of the other party in the middle table
//            inverseJoinColumns = @JoinColumn(name = "u_id",referencedColumnName = "userId")



    @ManyToMany(
            mappedBy = "roles",
            cascade = CascadeType.ALL //Cascade operation

    )
    private Set<User> users = new HashSet<>(0);



    public Set<User> getUsers() {
        return users;
    }
    public void setUsers(Set<User> users) {
        this.users = users;
    }
    public Integer getRoleId() {
        return roleId;
    }
    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }
    public String getRoleName() {
        return roleName;
    }
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    @Override
    public String toString() {
        return "Role [roleId=" + roleId + ", roleName=" + roleName + "]";
    }



}



test

package com.xjggb.test;

import com.xjggb.mapper.CustomerMapper;
import com.xjggb.mapper.RoleMapper;
import com.xjggb.mapper.UserMapper;
import com.xjggb.pojo.Customer;
import com.xjggb.pojo.Role;
import com.xjggb.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

//Specify operation period
@RunWith(SpringJUnit4ClassRunner.class)
//Load profile
@ContextConfiguration("classpath:applicationContext.xml")
public class JpaTest8 {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;



    /**
     * delete
     */
    @Test
    //To resolve the exception: join the transaction first
    @Transactional
    //Because during the test phase, spring rolls back
    @Rollback(false)
    public void test3() {
        //roleDao.delete(1); // If you have configured to discard the maintenance of intermediate tables, you cannot delete them

        /**
         * Cascade:
         * 		1)Unidirectional cascade:
         * 		2)Two way cascade: the relationship annotations on both sides are configured with cascade [disable] and [no grass]
         */
        roleMapper.delete(1); //If you have configured to discard the maintenance of intermediate tables, you cannot delete them by default. If you have configured cascading, you can delete them



        //At work: delete the user first, and then delete the role
		/*userDao.delete(1);
		roleDao.delete(1);*/
    }



    /*
     *
     * */

    @Test
    @Transactional
    @Rollback(false)
    public void show(){

        User user = new User();
        user.setName("Mitsui Shou");


        Role role = new Role();
        role.setRoleName("dentist");

//        Anyone who gives up can maintain an intermediate table with only one table, otherwise the error Duplicate entry '1-1' for key 'PRIMARY' will be reported
        role.getUsers().add(user);

        user.getRoles().add(role);


        userMapper.save(user);
        roleMapper.save(role);


    }

}


6. Object navigation query

Object navigation query: call management attribute query when managing objects

1) Query contact through customer navigation: customer getLinkmen() :

  • The default is delayed loading
  • You can change to load immediately: configure the fetch attribute in the relationship annotation

2) Contact navigation query customer: linkman getCustomer()

  • The default is load now
  • You can change to deferred loading: configure the fetch attribute in the relationship annotation
 //The customer does not maintain foreign keys
    @OneToMany(
            mappedBy="customer",//mappedBy: the name of the attribute with @ JoinColumn annotation on the other side of the configuration
            cascade = CascadeType.ALL//Cascade save update delete
            ,fetch = FetchType.EAGER  //Configure immediate load LAZY load EAGER immediate load
    )

The code is as follows

    @Test
    //To resolve the exception: join the transaction first
    @Transactional
    //Because during the test phase, spring rolls back
    @Rollback(false)
    public void show(){


//Query customer default delayed loading through contact navigation
//Query contact through customer navigation: lazy loading
        Customer one = customerMapper.findOne(1L);//Check the customer first
        System.out.println("one = " + one);
        Set<Linkman> linkmans = one.getLinkmans();//Check the contact again

        //iteration
        for (Linkman linkman : linkmans) {
            System.out.println(linkman);
        }


    }







summary

  1. Introduction to jpa CRUD

  2. Extraction of jpa tools

  3. Interface method definition query

  4. Use of Specification query

  5. Mapping of one to many queries

  6. Many to many mapping

Topics: Java