cool hit counter SSH framework journey - hibernate (2)_Intefrankly

SSH framework journey - hibernate (2)


hibernate

1.Primary key generation strategy


1.1 Two types of primary keys

  • Natural primary key: use a business field in the data table as the primary key of the table. If a user table has the user's username as the primary key of the user table. The prerequisites for doing so are that 1. the user's username cannot be empty, 2. the user's username cannot be duplicated, and the user's username cannot be modified. This, while also possible, does not meet the changing business needs well, so the natural primary key approach is not recommended.
  • Proxy primary key: Set a separate field for the data table as the primary key for the data table. As the primary key of this field has no business meaning, usually directly named id, usually for the integer type, because the integer type to save database space than the character type, so are generally used as a proxy primary key to set the primary key of the data table.

Note: In development, it is recommended to use a proxy primary key.

1.2 Primary key generation strategy in hibernate

  • Assigned Natural Primary Key Type Set the primary key in the program. If the mapping table is not set in generator attribute, hibernate uses this primary key generation policy by default. However, this is not recommended and manual manipulation of the primary key should be kept to a minimum.
  • increment proxy primary key type Used for integer types, automatically generated by hibernate in increments of one per increment, but only available when no other process is inserting data in the same table, not available in a clustered environment.
  • identity proxy primary key type The primary key is set by the underlying database and has nothing to do with hibernate. But only if the database you are using supports autogrowth data types, e.g. MySQL supports primary key autogrowth, but Oracle does not support primary key autogrowth. It is possible to use this primary key generation strategy if the database supports primary key self-increment.
  • sequence proxy primary key type Primary keys are generated by the underlying database based on sequences and are not related to hibernate. But only if the database supports sequences, which Oracle does. It is possible to use this primary key generation strategy if the database supports sequences.
  • hilo proxy primary key type hibernate generate primary key, hilo is high low (high low way) abbreviation, is a common way to generate hibernate, need an additional table to store hi (high) value, and manually set the value of max_lo, and then through the algorithm formula (hi * (max_lo + 1) + 0) to generate the primary key. This generation strategy can be used across databases, but the flags generated by the hilo algorithm are only guaranteed to be unique in one database.
  • natve proxy primary key type The identity, sequence, and hilo policies are automatically selected based on the underlying database. However, since the control of the generation strategy is in the hands of hibernate, it is not recommended and this generation strategy is less efficient.
  • uuid proxy primary key type The identifier (primary key) is generated by hibernate using a 128-value UUID algorithm that generates a unique string identifier in a network environment. The length is a 32-bit hexadecimal string, which takes up more control space and corresponds to the char/varchar type of the database. This generation strategy is database-independent, so it can be cross-database, facilitate database portability, and is efficient because primary key values can be generated without accessing the database, and uniqueness can be guaranteed.

2.Persistent category


2.1 Rules for writing persistent classes

Entity classes are converted to persistent classes by hibernate operations, and the following rules are still used to illustrate entity classes.

  • Entity classes provide constructor methods with no parameters. The parameterless constructor is fine even if we don't write it, because jdk will do it for us, but it's better to add this parameterless constructor.
  • The properties of the entity class are private and manipulated using the public set and get methods hibernate wraps the queried data in the underlying layer and uses reflection to generate instances of the class.
  • Entity classes should have properties as unique values hibernate has to distinguish whether there is a persistent class in memory by a unique identifier. In java, it distinguishes whether it is the same object by address, and in relational databases, it distinguishes whether there is a record in a table by primary key.
  • The basic type of the entity class property suggests using a wrapper class for the basic data type The default values for wrapper classes and basic data types are different, for example, the default value for the int type is 0 and the default value for the Integer type is null. And the semantic description of the wrapper class is clearer than the basic data type. For example, a student's grade can be 0 or 100, but if the student has no grade, it would be difficult to represent it with the basic data type, but the wrapper class can be represented by null, so that no ambiguity arises.
  • The mapped entity class should not be modified with the final keyword hibernate has a deferred loading mechanism, this mechanism will generate proxy objects, the generation of proxy objects is done through bytecode enhancement techniques, in fact, is the generation of the current class of subclasses object implementation, but with the final keyword modification can not generate subclasses.

2.2 Three states of persistent classes

  • Transient (temporary state) (free state) The transient state is that the object has only been created and opened up in memory, but it is not yet associated with the session, that is, the session has not been used to manipulate the object in memory, there is no record in the database at this time.
  • persistent state The new materialized class object is added to the session cache after the session operation, and the session associated with this object is not closed, this time is the persistent state, there are corresponding records in the database, each record corresponds to a unique persistent object, note that the persistent object is already persistent before the transaction is committed.
  • Hosted state (free state) (offline state) When a persistent instance is associated with a session object and the session is closed, the object becomes managed, and changes to the value of the object's properties are not detected by hibernate because the instance object has lost its association with the session.

The three states can be understood in the context of the curd operation and first-level cache below.

3.curd operation


Code for the entity class

package cc.wenshixin.entity;

public class Notice {

    private int id; //  Announcement serial number
    private String title; //  Announcement Title
    private String content; //  Announcement content
    private String people; //  Posted by.
    private String date; //  Release Date

    public Notice()
    {
        
    }
    
    public Notice(String title, String content, String people, String date) {
        super();
        this.title = title;
        this.content = content;
        this.people = people;
        this.date = date;
    }

    public int getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getPeople() {
        return people;
    }

    public void setPeople(String people) {
        this.people = people;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "Notice [id=" + id + ", title=" + title + ", content=" + content + ", people=" + people + ", date=" + date
                + "]";
    }

}

hibernate Custom tool class for easy manipulation of hibernate.

package cc.wenshixin.utility;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtility {
    private static Configuration cfg = null;
    private static SessionFactory sessionFactory = null;
    
     //Static code blocks
    static
    {
         // Load the core configuration file
        cfg = new Configuration().configure();
        sessionFactory = cfg.buildSessionFactory();
    }
    
     /*Provide method to return sessionFactory*/
    public static SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }
    
     /* Provide session methods bound to local threads */
    public static Session getSession()
    {
        return sessionFactory.getCurrentSession();
    }
}

The following actions are all code tested using the JUnit testing tool.

3.1 Add operation

Adding an operation changes a persistent class from a transient to a persistent state.

@Test
    public void testSave()
    {
         //Get the sessionFactory object
        SessionFactory sessionFactory = HibernateUtility.getSessionFactory();
         // get session object
        Session session = sessionFactory.openSession();
         // Open transaction
        Transaction tx = session.beginTransaction();
        
         /* perform curd operation*/
        
        Notice notice = new Notice(" Laboratory openings", "Students are free to choose experiments outside of class", "admin", "2017-10-1");
        session.save(notice);
    
         //Execution services
        tx.commit();
         //close session and sessionFactory
        session.close();
        sessionFactory.close();
    }

3.2 Query operations

hibernate's delete and change operations are implemented based on query operations.

@Test
    public void testGet()
    {
         //Get the sessionFactory object
        SessionFactory sessionFactory = HibernateUtility.getSessionFactory();
         //Get the session
        Session session = sessionFactory.openSession();
         // Open transaction
        Transaction tx = session.beginTransaction();
        
         // Perform query operations
        Notice notice = session.get(Notice.class, 2);
         // Here you have to override the toString() method first
        System.out.println(notice.toString());
        
         //Submitted transactions
        tx.commit();
        
         //close session and sessionFactory
        session.close();
        sessionFactory.close();
    }

3.3 Delete operation

The following shows two ways to delete a row, but it is recommended to use the first one, query first and delete later, and the second one, which sets the value of the corresponding attribute of the primary key directly, should be avoided.

@Test
    public void testDelete()
    {
         //Get the sessionFactory object
        SessionFactory sessionFactory = HibernateUtility.getSessionFactory();
         //Get the session targets
        Session session = sessionFactory.openSession();
         // Open transaction
        Transaction tx = session.beginTransaction();
        
         // Perform delete operation
         // First method
        //Notice notice = session.get(Notice.class, 3);
        
         // Second method
        //Notice notice = new Notice();
        //notice.setId(2);

        session.delete(notice);
        
         //Submitted transactions
        tx.commit();
        
         //close session and sessionFactory
        session.close();
        sessionFactory.close();
    }

3.4 Modifying operations

obtain first persistent state object of, And then operate on this object。

@Test
    public void testUpdate()
    {
         //Get the sessionFactory object
        SessionFactory sessionFactory = HibernateUtility.getSessionFactory();
         //Get the session targets
        Session session = sessionFactory.openSession();
         // Open transaction
        Transaction tx = session.beginTransaction();
        
         // Perform update operations
        Notice notice = session.get(Notice.class, 2);
        notice.setTitle(" I've changed.");
        session.update(notice);
        
         //Execution services
        tx.commit();
        
         //close session and sessionFactory
        session.close();
        sessionFactory.close();
    }

3.5 Adding or updating operations

saveOrUpdate() method is more persistent object state to do the add or update operation, the object if the transient state, then the execution of the transaction to do the add operation, if the object is managed state, then the execution of the transaction to do the update operation, but at this time to note that the update operation to set the value of all the properties of the persistent class, otherwise the field without setting the value of the property is null, the following code will produce this situation, so it is not recommended to use the managed state to modify the data table kind of record.

@Test
    public void testSaveOrUpdate()
    {
         //Get the sessionFactory object
        SessionFactory sessionFactory = HibernateUtility.getSessionFactory();
         //Get the session targets
        Session session = sessionFactory.openSession();
         // Open transaction
        Transaction tx = session.beginTransaction();
        
         // Perform add or update operations
        //Notice notice = new Notice(" New announcement", " Announcement content", "admin", "2017-10-9");
        Notice notice = new Notice();
        notice.setId(4);
        notice.setPeople("admin");
        session.saveOrUpdate(notice);
        
         //Submitted transactions
        tx.commit();
        
         //close session and sessionFactory
        session.close();
        sessionFactory.close(); 
    }

3.6 Transformation between persistent class states

  • Transient state to other states transient state persistent state: execute session target group save() method or saveOrUpdate() approach Transient to Managed: sets the persistent identity for the transient object, i.e. calls the setId() method
 Notice notice = new Notice();  /transient state
notice. setId(2);  //hosting state
  • persistent state switch to other status Persistent objects can be obtained from the database by performing get() and load() methods on session objects, or by Query queries (described later). persistent state transient state: executesession ofdelete() approach persistent state sub-hosting state: execute session ofclose()、clear() perhaps evict() approach,evict() method is used to clear a certain object from the first-level buffer,close() method is used to close the session targets, Clear the entire level 1 cache,clear() method is used to clear all objects in the first-level cache。
  • Hosted to gaseous state Managed state objects are not directly available, they are transformed from other state objects, and the difference between managed and transient states is whether the OID has a value or not. Hosted to persistent: execute the update(), saveOrUpdate() or lock() methods of the session Managed to transient: sets the OID identifier of the managed persistence to null, i.e. sets the value of the attribute that is the primary key to null

Note: Since the value of the persistent state object changes, you don't actually need to call the update() method or saveOrUpdate() method, you can automatically update the database after executing the transaction (the automatic update will be explained in the level 1 cache), but it is still recommended to add the method to make it easier to read the code.

4.Level 1 Cache


4.1 What is Level 1 Cache

First we need to understand what is cache, the database itself is actually a file system, and we know that the use of streams to manipulate files is not efficient, so we put the data inside the memory, so that you can directly read the data inside the memory to improve the efficiency of reading.

The hibernate framework provides a number of optimizations, and first-level caching is one of them. hibernate also has a second level cache, but that is no longer available and uses redis technology instead.

The first level of hibernate cache is the session cache, session cache is a memory space used to store mutually managed java objects, when using hibernate query object, first according to the object OID (unique identifier) to the first level of the cache to find, if found directly from the first level of the cache to use, do not have to go to the database query, so as to improve the efficiency of the query, if not in the first level of the cache, we have to go to the database query, and then the data information found into the first level of the cache. The purpose of hibernate's level 1 cache is to reduce accesses to the database.

4.2 Characteristics of the first-level cache

  • 1.hibernate's first-level cache is turned on by default.
  • 2.The first-level cache in hibernate uses the session scope, which is from session creation to session closure.
  • 3.The first-level cache of hibernate, which stores data, must be persistent data.

4.3 Verify Level 1 Cache presence

    Notice notice1 = session.get(Notice.class, 1);
    System.out.println(notice1);
    Notice notice2 = session.get(Notice.class, 1);
    System.out.println(notice2);
     // The comparison is whether the addresses pointed to by the objects are the same
    System.out.println(notice1==notice2);

Successive execution of the query operation, observe the console output, found that only once the query sql statement, which means that the second query is not in the database query to get, but directly from the hibernate level 1 cache, and compare the two object reference address is also true.

Verify Level 1 Cache

4.4 account for Automatic update of persistent classes

Earlier we said that the persistent class can automatically update the records inside the database without using the update() method after changing the value of a property, and we need guidance on the internal structure of the hibernate first-level cache. After executing the query operation, put the queried data into the buffer and copy a copy of the data to the snapshot area, change the property values of the persistent object directly through the set method, which will also change the contents inside the buffer, and compare the data inside the buffer and snapshot area when the transaction is committed to see if they are consistent, and if they are not, update the records in the database and update the data in the snapshot area. The role of the snapshot area is to ensure that the data in the primary cache is consistent with the data in the database.

Automatic update of persistent classes

5.transaction operation


hibernate is a lightweight wrapper for jdbc, and hibernate's transactions are database transactions.

5.1 What is a transaction

In database operations, a transaction is an indivisible unit of work consisting of one or more sql statements that operate on the database. The entire transaction is committed to the database only when all operations in the transaction have completed properly. If a transaction consists of an operation that does not complete, the entire transaction is rolled back. A transaction is simply understood to be a set of logical operations, and the individual units that make up the set either succeed together or fail together with uniformity.

5.2 The four characteristics of transactions are explained in detail

Transactions are very strictly defined and need to satisfy all four of the following characteristics, which are commonly referred to as ACID characteristics.

  • Atomic: indicates that the operations done in the transaction are bundled into an indivisible unit, i.e., all or none of the operations performed on the transaction, such as data modifications, are executed.
  • Consistency: indicates that all data must be in a consistent state when the transaction completes.
  • Isolation (Isolation): means that the execution of a transaction cannot be interfered with by other transactions, that is, the operations within a transaction and the data used are isolated from other transactions of the concurrent execution, and the concurrently executed transactions cannot interfere with each other.
  • Durability:Durability, also known as permanence, means that once a transaction is committed, the changes it makes to the data in the database should be permanent. Other transactions after commit will have no effect on it for other operations or failures.

5.3 Concurrency issues in transactions

In real-world applications, databases are to be accessed by multiple users together, and concurrency problems may occur when multiple transactions use the same data at the same time.

  • Dirty read: a transaction reads data that was not committed by another transaction.
  • Non-repeatability: one transaction reads data from an update that has already been committed by another transaction, resulting in inconsistent query results in the same transaction.
  • False/phantom reads: one transaction reads data from an insert that has already been committed by another transaction, resulting in inconsistent results for multiple queries in the same transaction.

5.4 Isolation levels of transactions

In order to avoid the transaction concurrency problem described above, so in the standard SQL specification, four transaction isolation levels are defined, and different isolation levels handle transactions differently.

  • Read Uncommitted (Level 1): A transaction can access both newly inserted data and uncommitted modified data during execution, i.e., if its transaction is uncommitted. This isolation level prevents lost updates if one transaction has started writing data and another transaction is not allowed to write at the same time, but other transactions are allowed to read this row of data.
  • Committed Read (Read Commited, level 2): a transaction can access both newly inserted data that has been successfully committed by other transactions and data that has been successfully modified during execution. A transaction that reads data allows other transactions to continue to access that row of data, but an uncommitted write transaction will prohibit other transactions from accessing that row. This isolation level effectively prevents dirty reads.
  • Repeated Read (Level 4): A transaction can access newly inserted data that was successfully committed by other transactions during execution, but not data that was successfully modified. A transaction that reads data will prohibit write transactions (but allow read transactions), and a write transaction will prohibit any other transactions; this isolation level effectively prevents non-repeatable and dirty reads.
  • Serialization/Serialization (Serializable, level 8): provides strict transaction isolation; it requires transactions to be executed serially, and transactions can only be executed one after the other, but not concurrently. This isolation level effectively prevents dirty reads, non-repeatable reads and phantom reads.

The isolation level of the transaction is provided by the database, but not all databases support all four isolation levels. When using a database, the higher the isolation level, the higher the security and the lower the performance. In practical development, the highest or lowest isolation level is not chosen; using the database default is sufficient.

5.5 hibernate transaction specification code

In hibernate, managed transactions can be manipulated in code, such as through the Transaction tx = session.beginTransaction(); After opening a transaction and persisting the operation, the transaction is opened via the tx.commit(); Commit the transaction, and if there is an exception to the transaction, pass the tx.rollback(); operation to undo the transaction (rollback the transaction).

In addition to opening, committing and rolling back transactions in code, you can also configure transactions in the hibernate configuration file. In the configuration file, you can set the isolation level of the transaction. It is configured in the hibernate.cfg.xml file in the property The tag in which this is done. Configuration method.<property name="hibernate.connection.isolation">4</property> , and we need to take into account the application scenario of transactions when doing real transaction management, the control of transactions should not be placed in the DAO layer, but in the Service layer to call multiple DAOs to implement the operation of a business logic. The main thing is to ensure that the Session object used to open a transaction in the Service and the Session object used by multiple operations in the DAO are the same.

layers of transaction processing

Here are two solutions.

    1. Sessions can be fetched at the business layer and passed as parameters to the DAO.
    1. You can use ThreadLocal to bind the Session fetched by the business layer to the current thread, and then fetch the Session from the current thread when fetching it in the DAO.

The second way is the best solution, and the implementation is already done internally by hibernate, we just need to configure it. hibernate5 provides three methods for managing Session objects.

    1. The life cycle of a Session object is bound to the local thread
    1. The lifecycle of a Session object is transactionally bound to the JTA (Java Transaction API, a Java Enterprise Edition application programming interface)
    1. The hibernate delegate manages the lifecycle of Session objects

(located) at hibernate in the configuration file of,hibernate.current_session_context_class attribute is used to specify the Session Management style, The available values are:1. tread, The life cycle of a Session object is bound to the local thread;2. jta,Session The life cycle of an object is similar to that of JTA transaction binding;managed,hibernate Delegate procedures to manage Session Life cycle of an object。 Here we choose tread happen to, (located) at hibernate.cfg.xml Configure in:<property name="hibernate.current_session_context_class">thread</property> and the getCurrentSession() method is provided in hibernate to create a Session bound to the local thread TreadLocal.

     /* Provide session methods bound to local threads */
    public static Session getSession()
    {
        return sessionFactory.getCurrentSession();
    }

This Session provided by hibernate bound to the local thread can be closed without having to close it, and will be closed automatically when the thread finishes executing.

The canonical code writing for transactional operations is given below.

The code structure is as follows.

try {
   Opening of the service
Submission services
}catch() {
   Rollback transactions
}finally {
   close
}
    @Test
    public void testTx1()
    {
        Session session = null;
        Transaction tx = null;
        
        try{
             // Get the Session bound to the local thread
            session = HibernateUtility.getSession();
             // Open transaction
            tx = session.beginTransaction();
            
             // Add operation
            Notice notice = new Notice(" Local thread binding", " Standardize operations", "admin", "2017-10-8");
            session.save(notice);
            
             //Submitted transactions
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
             //rollback transactions
            tx.rollback();
        } finally {
             // No need to close the session
        }
    }
    
     // The code below is just a comparison of the code above
    @Test
    public void testTx2()
    {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction tx = null;
        
        try{
            sessionFactory = HibernateUtility.getSessionFactory();
             // A Session that is not bound to a local thread, similar to the singleton pattern.
            session = sessionFactory.openSession();
             // Open transaction
            tx = session.beginTransaction();
            
             // Add operation
            Notice notice = new Notice(" Local thread binding", " Standardize operations", "admin", "2017-10-8");
            session.save(notice);
            
             //Submitted transactions
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
             //rollback transactions
            tx.rollback();
        } finally {
             // need to close session
            session.close();
            sessionFactory.close();
        }
    }

6.A brief introduction to the hibernate query-related API


For query operations, hibernate has several different APIs that can be used, which are briefly described here and described in detail later.

6.1 Query object

With query objects, you don't need to write sql statements, but you do need to write simple hql (hibernate query language) statements.

Difference between hql and sql statements.

    1. The hql statement is a query that uses entity classes and properties directly
    1. sql statements are to manipulate data tables and fields

The hql statement is written. from the name of the entity class

Use of the Query object.

    1. Creating a query object
    1. Call the methods inside the query object to get the results

The sample code is as follows.

    @Test
    // Query all data in the table
    public void testQuery1()
    {
        Session session = HibernateUtility.getSession();
        Transaction tx = session.beginTransaction();
        
        Query<Notice> query = session.createQuery("from Notice");
        List<Notice> list = query.list();
        for(Notice notice : list)
        {
            System.out.println(notice);
        }
    }
    
    @Test
    // Conditional queries
    public void testQuery2()
    {
        Session session = HibernateUtility.getSession();
        Transaction tx = session.beginTransaction();
        
        Query<Notice> query = session.createQuery("from Notice where title=?");
        query.setString(0, " Laboratory openings");
        List<Notice> list = query.list();
        for(Notice notice : list)
        {
            System.out.println(notice);
        }
    }

6.2 Criteria object

Using criteria objects, you don't need to write statements, just call the methods directly to implement them.

Use of criteria object.

    1. Creating criteria objects
    1. Call the method inside the object to get the result

The sample code is as follows.

    @Test
    // Query all data in the table
    public void testCriteria1()
    {
        Session session = HibernateUtility.getSession();
        Transaction tx = session.beginTransaction();
        
        Criteria criteria = session.createCriteria(Notice.class);
        List<Notice> list = criteria.list();
        for(Notice notice : list)
        {
            System.out.println(notice);
        }   
    }
    
    @Test
    // Conditional queries
    public void testCriterial2()
    {
        Session session = HibernateUtility.getSession();
        Transaction tx = session.beginTransaction();
        
        Criteria criteria = session.createCriteria(Notice.class);
        criteria.add(Restrictions.eq("title", " Laboratory openings"));
        List<Notice> list = criteria.list();
        for(Notice notice : list)
        {
            System.out.println(notice);
        }
    }

6.3 SQLQuery object

You can see from the name is related to sql, directly write sql statements, the underlying hibernate call is sql statements implemented.

SQLQuery object

    1. establish SQLQuery object
    1. Call the object's method to get the result

The sample code is as follows.

@Test
    public void testSQLQuery()
    {
        Session session = HibernateUtility.getSession();
        Transaction tx = session.beginTransaction();
        
        SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM notice_content");
        List<Object[]> list = sqlQuery.list();
        for(Object[] objects : list)
        {
            System.out.println(Arrays.toString(objects));
        }
    }

Recommended>>
1、php learning of htmls tag attributes three
2、Build ApacheMySqlPHPphpMyAdmin runtime environment under Linux server
3、js remove spaces
4、Those good debugging software under Windows
5、Two years of Java development work experience interview summary

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号