[spring] spring jpa – hibernate terminology & configuration

[spring] spring jpa – hibernate terminology & amp; configuration

I have gone through the content of dependency injection before. This time I will go through the data-related part. After completing this part, the next part will involve API implementation.

The operation part will be left to the next article. This article is mainly about concepts + configuration.

Overall, nearly 1/3 of the course has been completed. It should be possible to finish the spring boot related content before the end of the year.

Term explanation

Before starting to use jpa/hibernate, let’s start by explaining some terms

  • MVC

    MVC is not directly related to spring. It is a broader model about the Model-View-Controller design pattern, which:

    • Model

      Represents content related to data and business logic. Simply put, it is the part responsible for communicating with the database and updating data.

    • View

      The rendering layer is the part that directly interacts with the user, including obtaining data from the background, interacting with the user in the foreground, and obtaining user input and transmitting it to the background.

    • Controller

      Responsible for the bridge between model and view, passing the data received from the view to the model for data update, and passing the data obtained from the model to the front desk for rendering.

    Some of the more popular MVC frameworks are Ruby, Django (python), Spring MVC (java) express (js), ASP .NET MVC (C#)

  • SSH

    The abbreviation of Struts-Spring-Hibernate framework, where Struts represents the View structure, Spring is responsible for the Controller + Model, and Hibernate is responsible for assisting in communication with the database and is also part of the Model.

  • SSM

    That is Spring + Spring MVC + Mybatis

    Here Spring is also responsible for the Controller + Model part, Spring MVC is responsible for rendering, and Mybatis replaces Hibernate and is responsible for assisting database communication.

  • ORM

    Object-Relationship Mapping

    Using this framework can map objects to relational databases, freeing developers from writing SQL and directly operating on objects.

    The more popular ORMs are: Hibernate (Java), ActiveRecord (Ruby), Django’s ORM (Python), Entity Framework (.Net), Sequelize (JS, Node)

  • Mybatis

    Mybatis is a SQL mapping framework with a low learning threshold and quick start, so it occupies a place in the SSM framework.

    Basically, Mybatis can shorten the time to write SQL for development, and MyBatis is responsible for communicating with the database, providing relatively high flexibility.

    Using MyBatis, developers still need to write their own SQL. It isnot an ORM framework

  • Hibernate

    Hibernate is an ORM framework, so it allows developers to only operate Java objects, while Hibernate is responsible for communicating with the database

    In short, Hibernate maps the corresponding java object to the database and implements SQL operations

    Hibernate is Spring Boot’s default JPA Provider. It essentially calls JDBC to implement specific database operations.

  • JPA

    The abbreviation of Java Persistence API, this is the API specification, Hibernate is the ORM framework that implements JPA

    In other words, in addition to Hibernate, there are other frameworks that also implement JPA, such as EclipseLink

    : JPA seems to have been renamed Jakarta Persistence API

  • Spring JPA

    Provides boilerplate code to speed up JDBC operations

    To use Spring JPA, you must have a JPA provider. The more popular provider is Hibernate.

    Without Provider, Spring JPA cannot communicate with the database

This can probably explain a little bit about the relationship between JPA, Spring JPA and Hibernate…?

Configuration

Configure spring initializr

The main thing is to add two additional dependencies:

Configuration database

Configuring the database is mainly configured from application.properties. The content of my configuration is as follows:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/student_tracker
spring.datasource.username=springstudent
spring.datasource.password=springstudent
# deprecated
#spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
# use org.hibernate.dialect.MySQLDialect instead
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect

This configuration is relatively simple, and the running results are as follows:

To add: I have created the corresponding user and password. If not, you can use the default user name and password root.

Possible problems encountered in configuration

Although this step is very fast, I was actually stuck on this step for a long time. I mainly encountered the following problems:

  1. Missing dialect

    The configuration given in the tutorial does not include spring.jpa.database. Later, Google added MySQL8Dialect.

  2. typo

    It should be org.hibernate.dialect.MySQL8Dialect, I missed org

  3. Database does not match

    The tutorial uses MySQL, and my local database is MariaDB v11

    Later, I tried to switch the Dialect of MariaDB 106, and then found that the POM needed to be updated again. After trying several times to no avail, I had to re-download MySQL before it worked.

    Therefore, the database version still needs to be consistent with the Dialect provided by Hibernate. I suspect that MariaDB11 and 106 are not compatible (because there is a major version difference)

  4. Local reload database conflict

    MariaDB used to be a shell of MySQL, but now the difference between the two is getting bigger and bigger…

    If you uninstall Maria with brew, the deletion will be relatively clean. However, when deleting MySQL, there are residual folders. If I re-download other DBs (Maria/MySQL), the startup will fail. The solution is to completely delete the remaining folders. Just reinstall it

    The script I use is:

    ? brew uninstall mysql
    ? rm -Rf /usr/local/var/mysql
    ? brew install mysql
    ? mysql.server start
    

After the configuration is completed, spring boot will automatically create the corresponding DataSource, EntityManager and other database-related beans based on the configuration.

Project configuration

Because the operation of CRUD is more troublesome, the CLI is used in the tutorial. The specific content is as follows:

package com.example.hibernatejpa;

import com.example.hibernatejpa.dao.StudentDAO;
import com.example.hibernatejpa.entity.Student;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class HibernateJpaApplication {<!-- -->

public static void main(String[] args) {<!-- -->
SpringApplication.run(HibernateJpaApplication.class, args);
}

@Bean
public CommandLineRunner commandLineRunner(StudentDAO studentDAO) {<!-- -->

return runner -> System.out.println("Hello World");
}
}

commandLineRunner mainly executes some command line output statements after Spring is started. For example, it logs here Hello World:

You can also modify the properties file here to reduce the log output:

spring.main.banner-mode=off
logging.level.root=warn

After modification, info related content and Spring banner will not be output:

JPA annotations

Some annotations used in this note are as follows:

  • Entity Mapping

    @Entity, @Table

  • Primary Key

    @Id, @GeneratedValue

  • Columnh Mapping

    @Column

  • Relationship

    It will not be used in this case for the time being, but it is this relationship: @OneToOne etc.

  • Query

    @NamedQuery

  • from Spring

    @Transactional means that the data will be mutated. The specific operations here are quite complicated, involving rollback and other operations. I will see if it will be covered in the course. If not, I will take the time to study it.

There are many of these, but you just need to understand them after you use them.

Some classes, such as EntityManager, DataSource, Spring will automatically generate according to the configuration, and you can use them directly later.

The operation process is as follows:

  1. Definition Entity Object

    JPA will map this class with the entity in the database, which is why there is the source of the annotation @Entity

    • Student
    package com.example.hibernatejpa.entity;
    
    import jakarta.persistence.*;
    
    @Entity
    @Table(name = "student")
    public class Student {<!-- -->
    }
    
    

    @Table refers to the table student in the database

  2. Perform data mapping

     @Entity
      @Table(name = "student")
      public class Student {<!-- -->
            // defined fields
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "Id")
        private int id;
    
        @Column(name = "first_name")
        private String firstName;
    
        @Column(name = "last_name")
        private String lastName;
    
        @Column(name = "email")
        private String email;
    
         public Student() {<!-- -->
         }
    
         public Student(String firstName, String lastName, String email) {<!-- -->
             this.firstName = firstName;
             this.lastName = lastName;
             this.email = email;
         }
      }
    

    Here you need a parameterless constructor to allow hibernate to use reflection to create the corresponding instance.

    Here, the data in the table and the attributes in the object are mapped. After all, the structure of the database is as follows:

    @Column is optional, if not provided the name in the database will be the same as the property name in Java. However, DB generally uses snake as its attribute name, and Java uses camel, so this is not recommended.

    In addition, if the code needs to be updated (such as changing the name, etc.), if you don’t pay attention to the modifications here, the project may not run.

    Similarly, the annotation @Table is also optional

    The primary key of the database map here is id, @GeneratedValue, that is, the primary key is generated through database management, so there is no need to pass the primary key when creating a new object.

    GenerationType can be overridden by implementing IdentifierGenerator and rewriting the corresponding method.

At this point, ORM mapping is implemented here.

The next step is to rewrite the setter/getter/toString method, which will be skipped here.

In addition to manual operation, you can also use lombok to remove duplicate setter/getter/no-argument constructors

Reference

  • Some of the more popular DB Dialects

    RDBMS Dialects
    DB2 org.hibernate.dialect.DB2Dialect
    DB2 AS/400 org.hibernate.dialect.DB2400Dialect
    DB2 OS390 org.hibernate.dialect.DB2390Dialect
    PostgreSQL org.hibernate.dialect.PostgreSQLDialect
    MySQL5 org.hibernate.dialect.MySQL5Dialect
    MySQL5 with InnoDB org .hibernate.dialect.MySQL5InnoDBDialect
    MySQL with MyISAM org.hibernate.dialect. MySQLMyISAMDialect
    Oracle (any version) org.hibernate.dialect.OracleDialect
    Oracle 9i org.hibernate.dialect.Oracle9iDialect
    Sybase org.hibernate.dialect.SybaseASE15Dialect
    Microsoft SQL Server 2000 org.hibernate.dialect.SQLServerDialect
    Microsoft SQL Server 2008 org.hibernate.dialect.SQLServer2008Dialect
    SAP DB org.hibernate.dialect.SAPDBDialect
    Informix org.hibernate.dialect.InformixDialect
    HypersonicSQL org.hibernate.dialect.HSQLDialect
    H2 Database org.hibernate.dialect. H2Dialect
    Ingres org.hibernate.dialect.IngresDialect
    Progress org.hibernate.dialect.ProgressDialect
    Mckoi SQL org.hibernate.dialect.MckoiDialect
    Interbase org.hibernate.dialect.InterbaseDialect
    Pointbase org.hibernate.dialect.PointbaseDialect
    FrontBase org.hibernate.dialect.FrontbaseDialect
    Firebird org.hibernate. dialect.FirebirdDialect

    It’s not very up-to-date, MySQL8Dialect has been deprecated, and the MySQL version I’m using now is 8, but it’s okay to use as a reference.

  • Mysql start up issues | ERROR! The server quit without updating PID file