Use Hibernate for persistent storage of object data

1 Introduction

ORM (Object Relationship Mapping), which uses object-oriented applications to store object information in a relational database. However, if the SQL statements related to the underlying database are written directly in the application, the program will be too dependent on the specific database, which is not conducive to the transplantation and expansion of the program, and the SQL syntax of different databases is different. Therefore, the ORM framework is needed to achieve the separation of object-oriented and data storage.

Hibernate is an open source ORM framework for lightweight packaging of JDBC in the Java field. As shown in the following figure, hibernate as a persistence layer, the data objects generated by the business logic layer are stored persistently in the database

Hibernate implementation process is as follows, first read the database configuration file hibernate.cfg.xml to generate Configuration objects, then read the object mapping file Entity.hbm.xml to generate factory objects, and finally create Session objects for database operations, Session is similar to JDBC Connection, through the session to add, delete, modify and check the database. The difference is that a connection can provide multiple session objects. When performing specific operations, it must be executed in the form of transaction Transaction, hibernate will not automatically submit by default, so after the session operation is completed, you need to manually submit the transaction to save the operation of the database.

You can get session object through sessionFactory.getCurrentSession () or openSession (). The first one will automatically end the session, but you need to configure <property name = "current_session_context_class"> thread </ property> in cfg.xml file. The second type does not require other configuration, but the session needs to be ended manually, otherwise each SessionFactory will allocate a new session object, causing overflow.

2. Create a Hibernate application

1. First, you need to import the jar package to the lib directory. In addition to the jar package required by hibernate, you also need to import the jar package of jdbc

2. Create a configuration file hibernate.cfg.xml in the src directory, configure the database url, driver, corresponding mapping entity, user name, password and other database configuration.

3. Then create the corresponding entity class, for example, create the StudentEntity class in the mypackage directory for the student table, which should meet the requirements of JavaBean (the class is public, the attributes are private and there are corresponding get / set methods)

4. Generate the mapping between the table and the class, create a Students.hbm.xml file to describe the corresponding mapping relationship, or you can declare the mapping relationship through annotations in the StudentEntity class

5. Test the insertion of the mapping object into the database through Junit

The above is a manual creation process. It is very convenient to create a Hibernate application through IDEA:

Right-click on the project root directory, select new-> Module to pop up as follows, select the Hibernate framework, and then check the Create default configuration file and import database, and the first time you need to download the default Libraries, then pop up interface to select the file name and save location, complete the project creation .

Then pop up the interface to configure the database and the corresponding mapping. You can also call up the Hibernate window in the View-> Tool Windows-> Persistence of IDEA in the lower left corner of the interface, then right-click the current HibernateXML project and select Generate Persistence Mapping to generate the mapping interface

Configure mapping in XML

Choose Data Source to select the database to be mapped, Package to select the package name stored in the generated Java object class, Entity prefix / suffix to set the object class name prefix and suffix, for example, here is generated StudentEntity class under the entity package Database Schema Mapping selects the table name in the database to be mapped, and finally Generate Separate XML per Entity generates a mapping relationship file for each table in the form of an XML file.

After setting, the hibernate.cfg.xml file is automatically generated as follows. Set the database in <property>, where url is the address of the database, driver_class is the database driver, dialect is the dialect of the database, and the dialect can be optimized for different databases. Username , Password are the user name and password of the database. show_sql, format_sql set the format to output database operation statements. hbm2ddl.auto sets the way to operate the database. update stands for updating the data table. create will create a new table. If it originally exists, delete it and then create it.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.username">root</property>
        <property name="connection.password">password</property>
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <mapping resource="StudentEntity.hbm.xml"/>
        <mapping resource="CoursesEntity.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

The resulting StudentEntity.hbm.xml file indicates the mapping relationship between object variables and data table fields

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="entity.StudentEntity" table="student" schema="test">
        <id name="id" column="id"/>
        <property name="name" column="Name"/>
        <property name="age" column="Age"/>
    </class>
</hibernate-mapping>

And the reverse engineering of IDEA will automatically generate Java's StudentEntity class under the entity folder, including the variables corresponding to the fields and their get / set methods and equals and hashCode methods. Note that if there is no default parameterless constructor, you need to add it manually , Otherwise it will report an error after execution

package entity;

import java.util.Objects;

public class StudentEntity {
    private int id;
    private String name;
    private Integer age;

    public StudentEntity() {    //手动添加无参构造方法
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StudentEntity that = (StudentEntity) o;
        return id == that.id &&
                Objects.equals(name, that.name) &&
                Objects.equals(age, that.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

Annotate the mapping

In addition to using the .hbm.xml file, you can also express the mapping relationship between Java classes and data tables through annotations. Select Generate JPA Annotations in the step of import database schema

The StudentEntity class file is generated as follows. It can be seen that not only the variables and get / set methods corresponding to the fields are generated, but also annotations are added to the classes and methods to indicate the mapping relationship.

@Entity
@Table(name = "student", schema = "test", catalog = "")
public class StudentEntity {
    private int id;
    private String name;
    private Integer age;

    @Id
    @Column(name = "id")
    public int getId() {
        return id;
    }

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

    @Basic
    @Column(name = "Name")
    public String getName() {
        return name;
    }

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

    @Basic
    @Column(name = "Age")
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StudentEntity that = (StudentEntity) o;
        return id == that.id &&
                Objects.equals(name, that.name) &&
                Objects.equals(age, that.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

3. Use Hibernate

In this way, a simple hibernate architecture is generated. We test the generated Student mapping through JUnit, click alt + insert in the StudentEntity.class file, select generate Test, generate a class test method, and select automatically generate setUp and tearDown methods. Used for operations performed before and after testing

As shown below is the generated StudentEntityTest file, create hibernate service in setUp and start the transaction, and close the resource in tearDown. Create a method in @test annotation for testing, create an object and save it to the corresponding student table in the database. After checking the database, it was found that the data of the student "Zhao Liu" was inserted.

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;
import org.junit.jupiter.api.Test;

class StudentEntityTest {
    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;

    @org.junit.jupiter.api.BeforeEach
    void setUp() {
        //创建服务注册对象
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();
        //创建会话工厂对象
        sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
        //会话对象
        session = sessionFactory.openSession();
        //开启事物
        transaction = session.beginTransaction();
    }

    @org.junit.jupiter.api.AfterEach
    void tearDown() {
        //提交事物
        transaction.commit();
        //关闭会话
        session.close();
        //关闭会话工厂
        sessionFactory.close();
    }

    @Test
    void testStudent(){
        StudentEntity student = new StudentEntity();        //创建一个对象
        student.setId(1007);
        student.setName("赵六");
        student.setAge(12);
        session.save(student);        //将对象保存到数据库中对应的表
    }
}

CRUD operation

Hibernate's addition, deletion, modification and inspection are implemented through the session's save (), delete (), update (), get () / load () methods, where get () will query and return an object immediately after the call, load () only Save the object id, and then execute the query when other properties of the object are used later. And when the object information cannot be queried, get () returns null, and load () will throw a hibernate.ObjectNotFoundException, for example, the test file is as follows

@Test
    void testStudent(){
        StudentEntity student = new StudentEntity();
        student.setId(1007);
        student.setName("赵六");
        student.setAge(12);
        session.save(student);              //向数据库中持久化保存对象
        StudentEntity s2=session.get(StudentEntity.class,1007);     //通过主键id取出对象
        System.out.println(s2.getName());
        s2.setAge(22);
        session.update(s2);             //修改对象
        session.delete(s2);             //删除对象
    }

Component properties

Sometimes it is necessary to combine multiple attributes of a table into an object as a mapping instead of direct mapping. For example, the students table has two fields, city and street, which need to be mapped to an Address object by the prime minister, and then used as an attribute of Student, which is the component.

First declare an Adress class

public class Address {
    private String city;
    private String street;

    public Address() {
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

Then modify the Student class, add the address attribute and set the corresponding get / set method

public class StudentEntity {
    private int id;
    private String name;
    private Integer age;
    private Address address;        //添加address对象属性

    ......

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

Then modify the student.hbm.xml mapping file and add the address component

    <class name="entity.StudentEntity" table="students" schema="test">
        <id name="id" column="id"/>
        <property name="name" column="Name"/>
        <property name="age" column="Age"/>
        <component name="address" class="entity.Address">
            <property name="city" column="city"/>
            <property name="street" column="street"/>
        </component>
    </class>

 Next, in the test method, first get the student with id 1006, and then add the address object attribute to it and save it

    void testStudent(){
        StudentEntity s2=session.get(StudentEntity.class,1006);     //通过主键id取出对象
        Address address=new Address();
        address.setCity("北京");
        address.setStreet("新直门");
        s2.setAddress(address);            //为学生添加address对象
        session.save(s2);
    }

View the database results as follows, you can see that the city and street fields corresponding to the address have been saved

 

Published 124 original articles · Like 65 · Visit 130,000+

Guess you like

Origin blog.csdn.net/theVicTory/article/details/104474124