Chapter 01- What is ORM

Section 01- How does the JDBC Template operate on a database

  1. Start by creating the User table in the database
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL.PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;
Copy the code
  1. Creating an entity Class
public class User{
    private Integer id;
    private String username;
    private String password;
    // Omit getter/setter/toString methods here
}
Copy the code

3. Inject the jdbcTemplate and data source configuration into the applicationContext. XML configuration file

<! -- Data source -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url"
              value="jdbc:mysql://localhost:3306/test? useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
<! --JdbcTemplate provides data CRUD API-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>
Copy the code

4. Create the UserDao in the DAO layer using the jdbcTemplate

public class UserDao {

    private JdbcTemplate jdbcTemplate;

    public JdbcTemplate getJdbcTemplate(a) {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public User findById(Integer id){
        String sql = "SELECT * FROM user WHERE id=?";
        //BeanPropertyRowMapper transforms database data to entity objects
        // queryForObject Queries a single item of data
        User user = jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<Employee>(Employee.class));
        returnuser; }}Copy the code

JdbcTemplate simplifies native JDBC operations, encapsulating operations such as obtaining database connections and creating prepareStatment objects, but still requires writing SQL statements in code and assigning placeholders. . Just use preparementStatment setString assignment operating parameters to be included in the array instead and assignment of a placeholder for operation, if you want to connect the SQL statement also encapsulate, this won’t appear the SQL statements in your code, This simplifies the JDBC operation process. For example, the SQL statement is SELECT * FROM user WHERE ID =? Which indicates that the user and the change of name of the primary key id is, the rest is a fixed structure, and the name of the entity class and attribute is with the database table name and field is the one-to-one, therefore can be determined by the entity class attribute names are written to the name of the database table and field operation, which can be according to different entity class piece together the different SQL statements. The main purpose of the ORM idea is that operating on entity classes is equivalent to operating on database tables. This requires the establishment of two mappings, the mapping between entity classes and tables, and the mapping between entity class fields and table attributes. Don’t focus on the SQL statement to achieve the framework of the ORM thought with Hibernate, Mybatis

Section 02- What is JPA

JPA is a set of specifications, internally composed of interfaces and abstract classes, Hibernate is the ORM framework that implements THE JPA specification

The full name of JPA is Java Persistence API, that is, Java Persistence API, which is a set of ORM based specification launched by SUN Company. It is composed of a series of interfaces and abstract classes

Standardization of 1.

JPA is one of the Java EE standards published by the JCP organization, so any framework that claims to conform to the JPA standard follows the same architecture and provides the same access API, which ensures that enterprise applications developed based on JPA can run under different JPA frameworks with minimal modifications.

2. Support for container-level features

Container-level transactions such as large data sets, transactions, and concurrency are supported in the JPA framework, which enables JPA to play a greater role in enterprise applications beyond the limitations of simple persistence frameworks.

3. Easy and convenient

One of the main goals of JPA is to provide a simpler programming model: Creating entities in the JPA framework is as simple as creating Java classes. There are no restrictions or restrictions, only need to use javax.persistence.Entity annotation, JPA framework and interface are very simple, not too many special rules and design pattern requirements, developers can easily master. JPA is designed on a non-invasive basis so it can be easily integrated with other frameworks or containers

4. Query ability

JPA’s query language is object-oriented rather than database-oriented, and it constructs queries in object-oriented natural syntax, which can be regarded as the equivalent of Hibernate HQL. JPA defines the unique Java Persistence Query Language (JPQL), an extension of EJB QL, which is a Query Language for entities that operate on entities rather than tables in a relational database, It also supports advanced query features such as batch updates and modifications, joins, GROUP BY, and HAVING that are normally only available in SQL, and even supports subqueries.

5. Advanced features

The ability to support advanced object-oriented features such as inheritance between classes, polymorphism, and complex relationships between classes in JPA allows developers to maximize the use of object-oriented models to design enterprise applications without having to deal with the persistence of these features in relational databases.

Section 02- How to use the JPA API

Add, delete, change and check of customers

  1. Create customer-related database tables
CREATE TABLE customer (
      cust_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'Customer Number (primary key)',
      cust_name varchar(32) NOT NULL COMMENT 'Customer Name (Company Name)',
      cust_source varchar(32) DEFAULT NULL COMMENT 'Source of Customer Information',
      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;
Copy the code
  1. Create a Maven project and add dependencies

  2. Configure the JPA core configuration file


      
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--需要配置persistence-unit节点
        持久化单元:
            name:持久化单元名称
            transaction-type:事务管理的方式
                    JTA:分布式事务管理
                    RESOURCE_LOCAL:本地事务管理
    -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <! -- JPA implementation -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <! Optional configuration: Configure jPA implementer configuration information -->
        <properties>
            <! - the database information the user name, javax.mail. Persistence. JDBC. User password, javax.mail. Persistence. JDBC. Password drive, . Javax.mail. Persistence. JDBC driver database address javax.mail. Persistence.. JDBC url - >
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test? useUnicode=true&amp;characterEncoding=utf8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai"/>

            <! - configure jpa implementation party (hibernate) configuration information display SQL: false | true automatically create a database table, hibernate. Hbm2ddl. Auto create: Update: Create a table while the program is running (if there is a table, the table will not be created) None: create a table -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>
Copy the code
  1. Write customer entity classes and configure mappings between entity classes and tables and between class attributes and table fields
Mysql database supports self-increment of primary keys and can use IDENTITY. Oracle does not support SEQUENCE AUTO to automatically select primary key generation policy */
@Entity // indicates an entity class
@Table(name = "customer") // indicate the mapping
public class Customer {

    @Id// Declare primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)// Declare a primary key generation policy
    @Column(name = "cust_id") // Attribute and field mapping
    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;
    
    // The getter/setter/toString methods are omitted
}
Copy the code
  1. Create the class CustomerDaoTest in the Test package and use Junit for JPA testing
public class CustomerDaoTest {

    @Test
    public void testInsert(a){
        //1. Load the configuration file to create the factory class
        EntityManagerFactory managerFactory = Persistence.createEntityManagerFactory("myJpa");
        //2. Get the instance manager from the factory class
        EntityManager entityManager = managerFactory.createEntityManager();
        //3. Obtain the transaction object and start the transaction
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Customer customer = new Customer();
        customer.setCustName("Tony Stark");
        customer.setCustSource("FB");
        customer.setCustLevel("VIP");
        customer.setCustIndustry("Military Industry");
        customer.setCustPhone(null);
        customer.setCustAddress("NY");
        //4. Add, delete, modify and check operations
        entityManager.persist(customer);
        //5. Commit/rollback transaction
        transaction.commit();
        //6. Close the resourceentityManager.close(); managerFactory.close(); }}Copy the code

API objects in JPA

Persistence

Action: Creates an EntityManagerFactory based on the persistence unit name. Methods: createEntityManagerFactory, static method, the parameters of the persistence unit name, returns the EntityManagerFactory

EntityManagerFactory

Createentitymanager createEntityManger The EntityManagerFactory creation process is a waste of resources. You can create an EntityManagerFactory within a static block of code

  • The database connection information is maintained internally
  • The cache information is maintained internally
  • All entity class managed objects are maintained internally
  • The database table corresponding to the entity class can be created or not created depending on the configuration
EntityManager

Entity class manager, where all operations on tables are performed:

  • BeginTrabsaction: Creates a transaction
  • Presist: save
  • Update the merge:
  • Remove: removing
  • Find /getRefrence: Searches by ID
Transaction

Function: Transaction control method:

  • Begin: starts the transaction
  • Commit: Commits the transaction. The update operation must commit the transaction
  • The rollback: rolled back

Extract the utility class JPAUtils management factory class

public class JPAUtils {

    private static EntityManagerFactory managerFactory;

    static {
        managerFactory = Persistence.createEntityManagerFactory("myJpa");
    }

    / / get the EntityManager
    public static EntityManager getEntityManager(a){
        returnmanagerFactory.createEntityManager(); }}Copy the code

Modify the CustomerDao to use JPAUtils

public class CustomerDaoTest {

    @Test
    public void testInsert(a){
        //1. Load the configuration file to create the factory class
        // EntityManagerFactory managerFactory = Persistence.createEntityManagerFactory("myJpa");
        //2. Get the instance manager from the factory class
        EntityManager entityManager = JPAUtils.getEntityManager();
        //3. Obtain the transaction object and start the transaction
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        Customer customer = new Customer();
        customer.setCustName("Tony Stark");
        customer.setCustSource("FB");
        customer.setCustLevel("VIP");
        customer.setCustIndustry("Military Industry");
        customer.setCustPhone(null);
        customer.setCustAddress("NY");
        //4. Add, delete, modify and check operations
        entityManager.persist(customer);
        //5. Commit/rollback transaction
        transaction.commit();
        //6. Close the resource
        entityManager.close();
        // managerFactory.close();}}Copy the code

Use the find() method in CustomerDaoTest to perform the query

@Test
public void testFindById(a){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Customer customer = entityManager.find(Customer.class, 1l);
    System.out.println(customer);
    transaction.commit();
    entityManager.close();
}
Copy the code

SQL: Hibernate: select customer0_.cust_id as cust_id1_0_0_, customer0_.cust_address as cust_add2_0_0_, customer0_.cust_industry as cust_ind3_0_0_, customer0_.cust_level as cust_lev4_0_0_, customer0_.cust_name as cust_nam5_0_0_, customer0_.cust_phone as cust_pho6_0_0_, customer0_.cust_source as cust_sou7_0_0_ from customer customer0_ where customer0_.cust_id=? Output result: Customer{custId=1, custName=’Tony Stark’, custSource=’FB’, custLevel=’VIP’, custIndustry=’Military Industry’, custPhone=’null’, custAddress=’NY’}

Use the getReference() method to perform the query in CustomerDaoTest

@Test
public void testGetReferenceById(a){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Customer customer = entityManager.getReference(Customer.class, 1l);
    System.out.println(customer);
    transaction.commit();
    entityManager.close();
}
Copy the code

Find () returns the Customer object after execution of entityManager.find() and prints the SQL statement on the console, which is loaded immediately

The getReference() method obtains a dynamic proxy object, and no SQL statement is immediately sent during the method invocation. When is the SQL statement executed? Lazy loading is usually used

Perform the delete operation

@Test
public void testDelete(){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Customer customer = entityManager.getReference(Customer.class, 1l);
    entityManager.remove(customer);
    System.out.println(customer);
    transaction.commit();
    entityManager.close();
}
Copy the code

Perform update operations

@Test
public void testMerge(a){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Customer customer = entityManager.getReference(Customer.class, 1l);
    customer.setCustName("IronMan Tony Stark");
    entityManager.merge(customer);
    System.out.println(customer);
    transaction.commit();
    entityManager.close();
}
Copy the code

Section 03- What is a JPQL query

JPQL stands for Java Persistence Query Language

Based on the EJB Query Language (EJB QL) first introduced in EJB2.0,Java Persistent Query Language (JPQL) is a portable query language designed to bind SQL syntax and simple query semantics in the expression of object-oriented expression language. Queries written in this language are portable. Can be compiled into SQL on all major database servers.

It has characteristics similar to native SQL statements and is fully object-oriented, accessed by class names and attributes rather than table names and attributes.

All the query

Create a new test class JPQLTest in the Test Package

public class JPQLTest {

    @Test
    public void testFindAll(a){
        EntityManager entityManager = JPAUtils.getEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        String jpql = "FROM Customer";
        Query query = entityManager.createQuery(jpql);
        // Send the query encapsulation result
        List resultList = query.getResultList();
        for(Object o : resultList) { System.out.println(o); } transaction.commit(); entityManager.close(); }}Copy the code

Reverse order query

@Test
public void testFindAllOrderById(a){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    String jpql = "FROM Customer ORDER BY custId DESC";
    Query query = entityManager.createQuery(jpql);
    // Send the query encapsulation result
    List resultList = query.getResultList();
    for (Object o : resultList) {
        System.out.println(o);
    }
    transaction.commit();
    entityManager.close();
}
Copy the code

Statistical query

@Test
public void testCount(a){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    String jpql = "SELECT COUNT(custId) FROM Customer";
    Query query = entityManager.createQuery(jpql);
    // Send the query encapsulation result
    Object resultList = query.getSingleResult();
    System.out.println(resultList.toString());
    transaction.commit();
    entityManager.close();
}
Copy the code

Paging query

    @Test
    public void testPaged(a){
        EntityManager entityManager = JPAUtils.getEntityManager();
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        // query all
        String jpql = "FROM Customer";
        Query query = entityManager.createQuery(jpql);
        // Assign the paging parameters
        // Start index
        query.setFirstResult(1);
        // Number of queries per page
        query.setMaxResults(1);
        // Send the query encapsulation result
        List resultList = query.getResultList();
        for(Object o : resultList) { System.out.println(o); } transaction.commit(); entityManager.close(); }}Copy the code

Conditions of the query

@Test
public void testCondition(a){
    EntityManager entityManager = JPAUtils.getEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    // query all
    String jpql = "FROM Customer WHERE custName LIKE ?";
    Query query = entityManager.createQuery(jpql);
    query.setParameter(1."Peter%");
    // Send the query encapsulation result
    List resultList = query.getResultList();
    for (Object o : resultList) {
        System.out.println(o);
    }
    transaction.commit();
    entityManager.close();
}
Copy the code

JPQL does not support SELECT *