Hibernate study notes

The core of Hibernate

1. Configuration interface: responsible for configuring and starting Hibernate
2. SessionFactory interface: responsible for initializing Hibernate
3. Session interface: responsible for CRUD operations of persistent objects
4. Transaction interface: responsible for transactions
5. Query interface and Criteria interface: responsible for execution Various database queries

Note : The Configuration instance is a startup object and is discarded once the SessionFactory is created.

Read the properties file information in the WEB-INF directory from the Spring configuration file
<bean id="propertyPlaceholderConfigurer"   
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    <property name="location">  
        <value>/WEB-INF/config.properties</value>  
    </property>  
	</bean>  
<property name="configLocation" value="/WEB-INF/hibernate.cfg.xml"></property>


Spring + SpringMVC + Hibernate
<!-- Configure data source c3p0 -->
		<bean id="jdbcDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
			destroy-method="close">
			<property name="driverClass">
				<value>${driver}</value>
			</property>
			<property name="jdbcUrl">
				<value>${url}</value>
			</property>
			<property name="user">
				<value>${username}</value>
			</property>
			<property name="password">
				<value></value>
			</property>
			<!-- request timeout-->
			<property name="checkoutTimeout" value="30000" />
			<!-- Check all connection pools for idle connections every 60 seconds. Default: 0, do not check -->
			<property name="idleConnectionTestPeriod" value="30" />
			<!-- The maximum idle time for connecting to the database connection pool-->
			<property name="maxIdleTime" value="30" />
			<!-- Connection pool initialization connection number-->
			<property name="initialPoolSize" value="5" />
			<property name="minPoolSize" value="5" />
			<property name="maxPoolSize" value="20" />
			<!--The number of connections obtained by c3p0 at one time when the connections in the connection pool are exhausted. Default: 3 -->
			<property name="acquireIncrement" value="5" />
		</bean>
<!-- Configure SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <!-- Specify the location of the hibernate configuration file-->
        <property name="configLocation" value="/WEB-INF/hibernate.cfg.xml"></property>
        <!-- Configure c3p0 database connection pool -->
        <property name="dataSource" ref="jdbcDataSource">
        </property>
</bean>

Objects in three states
Persistent objects can be ordinary Javabeans, the only special thing is that they are associated with (only one) Session. JavaBeans has three states in Hibernate:
1. Temporary state (transient): When a JavaBean object exists in isolation in memory and does not have any relationship with the data in the database, then this JavaBeans object is called a temporary object (Transient). Object).
2. Persistent state (persistent): When a JavaBean object is associated with a Session, it becomes a persistent object (Persistent Object)
3. Detached state (detached): When the Session is closed, the object is also When it leaves the persistent state, it becomes a Detached Object, which can be freely used by any layer of the application, such as a Data Transfer Object that can deal with the presentation layer.


flush()
When session.flush is executed, the object in the previous session will be forced to persist
Hibernate query
1. Query all fields of the entire mapping object
String hql = "from Users";    
Query query = session.createQuery(hql);    
List<Users> users = query.list();    

2. Query a single field
String hql = " select name from Users";    
 Query query = session.createQuery(hql);    
List<String> list = query.list();

3. Query several of these fields
String hql = " select name,passwd from Users";    
 Query query = session.createQuery(hql);    
 //The default query list stores an Object array    
 List<Object[]> list = query.list();    

4. Modify the default query result (query.list()) not to return it as an Object[] array, but to return it as a List
String hql = " select new list(name,passwd) from Users";  
Query query = session.createQuery(hql);  
       //The default queried list stores an Object array, but here the list is no longer the default Object array, but the List collection  
 List<List> list = query.list();
 
5. Modify the default query result (query.list()) not to return it in the form of Object[] array, but return it in the form of Map
String hql = " select new map(name,passwd) from Users";    
 Query query = session.createQuery(hql);   
           //The default query list stores an Object array, but here the list is no longer the default Object array, but a Map collection    
List<Map> list = query.list();  
  
6. Modify the default query result (query.list()) is not returned in the form of Object[] array, but returned in the form of a custom type
//The list stored by query.list() is no longer the default Object array, Instead, the custom class MyUser must add the package name. The Users class in String hql = "from Users"; must also add the package name, but because <hibernate-mapping auto-import=" in Users.hbm.xml true"> The default value of auto-import is true (so the auto-import attribute can also be omitted), which is automatically imported   
         
String hql = " select new  com.domain.MyUser(name,passwd) from Users";    
Query query = session.createQuery(hql);    
           //The default queried list stores an Object array, but here the list is no longer the default Object array, but the MyUser object    
           List<MyUser> myUsers = query.list();   


7: Conditional query
(1) //Conditional query, parameter index value starts from 0, index position. Set parameters through setString, setParameter   
         
String hql = "from Users where name=? and passwd=?";    
           Query query = session.createQuery(hql);    
           //The first way    
   //      query.setString(0, "name1");    
   //      query.setString(1, "password1");    
           //The second way    
           query.setParameter(0, "name1",Hibernate.STRING);    
           query.setParameter(1, "password1",Hibernate.STRING);    


(2) //Conditional query, custom index name (parameter name): username,:password. Set parameters through setString, setParameter   
         
String hql = "from Users where name=:username and passwd=:password";    
           Query query = session.createQuery(hql);    
           //The first way    
   //      query.setString("username", "name1");    
   //      query.setString("password", "password1");    
           //The second way, the third parameter determines the type    
           query.setParameter("username", "name1",Hibernate.STRING);    
           query.setParameter("password", "password1",Hibernate.STRING);   


Relationship Mapping
Many-to-One
<many-to-one name="" class="" column=""/>

One-to-many
(Set)
<set name="">
        <key column=""></key>
        <one-to-many class=""/>
</set>

Many-to-many
(Set)
<set name="" table="">
        <key column=""></key>
        <many-to-many class="" column=""/>
</set>

• name attribute: attribute name
• class attribute: associated entity type
• column attribute:
               ○ <many-to-one column="..">: generally can be written as attribute name plus Id suffix, if the attribute is group, the column value Written as groupId.
               ○ <key column=".."> in one-to-many: copy the column value from the associated counterpart (the counterpart is many-to-one) mapping.
               ○ <key column=“..”> in many-to-many: Generally, the name of the cost object can be written with the Id suffix. If the name of the object is User, it is written as userId.
               ○ <many-to-many column=“..”> in many-to-many: generally can be written as the name of the associated object plus Id suffix.
Many-to-one
1. <!-- The group attribute expresses the many-to-one relationship between this object and the Group --> 
2. <many-to-one name="group" class="Group" column="groupid "></many-to-one> One-to-
One
When the foreign key in the slave table is the primary key, it is called a one-to-one association based on the primary key. <one-to-one is used in the hbm.xml of the master table >Configure from the table's hbm.xml also use <one-to-one> configuration, and use <generator class="foreign"> at the same time, specify that its primary key is the same as the foreign key.
When the foreign key in the slave table has a uinique constraint, it is called a one-to-one association based on a unique foreign key. Use <one-to-one> in the hbm.xml of the master table to configure the slave table's hbm.xml using <many- to-one> configuration, and specify the unique attribute as true

(primary key association)
<!-- idCard attribute, which expresses the one-to-one relationship between this object and IdCard. -->
	<id name="id">  
	        <!-- Using the foreign generation strategy, forgeign will obtain the identity of another associated object -->  
	            <generator class="foreign" >  
	                <param name="property">idCard</param>  
	            </generator>  
	 </id>  
  
	 <one-to-one name="idCard" class="IdCard"  constrained="true"></one-to-one>  

One-to-one instructs hibernate how to load its associated objects. By default, loading is based on the primary key 
            , that is, to get the value of the relationship field, and the associated object is loaded according to the primary key of the opposite end. 
             
            constrained="true" means constraints, the current primary key (person's primary key) is still a The foreign key 
            refers to the primary key of the opposite end (the primary key of IdCard), that is, a foreign key constraint statement 
(unique foreign key association) will be generated
<id name="id">  
	            <generator class="native" ></generator>  
	</id>  
	 <!-- Since it is a one-to-one unique foreign key association, it is a special case of a many-to-one association, and comments can be directly written as a many-to-one association -->  
	        <!-- idCard attribute, which expresses the many-to-one relationship between this object and IdCard. -->  
	        <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one>

Bidirectional one- to-one
(unique primary key association)
Card
<!-- How to load objects, grab strategy: join joint query (default), select: query one by one -->  
 <one-to-one name="person" class="Person" fetch="join"></one-to-one>


Person:
<one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one>

(unique foreign key association)
Person
<!-- Since it is a one-to-one unique foreign key association, it is a special case of a many-to-one association, and comments can be directly written as a many-to-one association -->  
 <!-- idCard attribute, which expresses the many-to-one relationship between this object and IdCard. -->  
 <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one>

Card:
<!-- One-to-one unique foreign key associations are bidirectionally mapped using the <one-to-one> tag, and <one-to-one> must be specified  
 The property-ref attribute in the tag is the name of the relation field -->  
<one-to-one name="person" class="Person" property-ref="idCard"></one-to-one>

One-way one-to-many
<!-- users attribute, which expresses the one-to-many relationship between this object and User -->  
<set name="users">  
     <!--The primary key of the current table (Group)-->  
     <key column="groupid"/>  
     <one-to-many class="com.liang.hibernate.User"/>  
</set>  

Two-way one-to-many
Group:
<!-- Affect inversion of control: inverse="false", the more end maintains the relationship, and the one end fails -->  
<set name="users" inverse="true">  
    <key column="groupid" not-null="true"/>  
    <one-to-many class="User"/>  
 </set>  

User:
<!-- groups attribute, which expresses the many-to-one relationship between this object and Group -->  
<many-to-one name="groups" class="Group" column="groupid"/>  

Bidirectional many-to-many
User:
<!-- roles attribute, which expresses the many-to-many relationship between this object (User) and Role -->    
<set name="roles" table="t_user_role">  
    <!--The primary key of the current table (User)-->  
    <key column="user_id"></key>  
    <many-to-many class="Role" column="role_id"></many-to-many>  
</set>  

Role
<!-- users attribute, which expresses the many-to-many relationship between this object (Role) and User -->    
<set name="users" table="t_user_role">  
    <!--The primary key of the current table (Role)-->                  
    <key column="role_id"></key>  
    <many-to-many class="User" column="user_id"></many-to-many>  
</set>  


fetch fetching strategy
When the value of fetch is select, the primary persistent object will be queried first, and then the associated object will be queried according to the foreign key of the persistent object. Therefore, if there are N persistent objects with query, the primary persistent object will be queried first. Use one SQL to query all persistent objects, and then send N multiple tables based on the foreign key association of each persistent object. So there will be a problem of N+1. (It does not matter if there is only one main persistent object.)
When fetch is a join, an SQL statement will be used to query the main object and related objects. So there is no N+1 problem.
The default value of constrained
constrained is false
constrained can only be used in one-to-one mapping (generally in the mapping of the main table, the table with the foreign key). If constrained=true, it means that there is a foreign key corresponding to the association table, and there must be a corresponding key in the association table corresponding to it. In addition, the most critical option of this option is to affect the order of save and delete. For example, when adding, if contained=true, the associated table will be added first, and then this table will be added. The opposite is true when deleting.
In the one-to-one one-way association, if constrained=false, all of them will be taken out at the time of query, and the left outer join method will be used. If constrained=true, hibernate will delay loading sql, only find out the main table, and then send sql to retrieve the related table.
In the one-to-one bidirectional association, constrained=true must be set, otherwise there will be repeated data reads, such as 2 tables user, car; when it is false, the sql is as follows: select * from user a left outer join car b on a.id=b.id left outer join on user c on a.id=c.id where a.id=? When deleting, it is best to delete the slave table. When deleting the master table, the master table will be queried first, and then the joint query will be performed. .
inverse
The inverse attribute can be used in one-to-many and many-to-many bidirectional associations. The inverse attribute defaults to false, which means that the local end maintains the relationship. If inverse is true, the local end cannot maintain the relationship and will be handed over to the other end to maintain the relationship. , the local end fails. Therefore, in one-to-many association mapping, we usually maintain the relationship at the many end and let the one end fail, so set inverse to true.
Hibernate cache mechanism
Hibernate first level cache is also known as "Session cache". 2.Hibernate secondary cache is also known as "SessionFactory cache".
What kind of data is suitable for storing in the second level cache?   
1) Data that is rarely modified   
2) Data that is not very important, allowing occasional concurrent data   
3) Data that will not be accessed concurrently   
4) Constant data Data   
that is not    suitable for storage in the second level cache?
1) Data that is frequently modified   
2) Data with concurrent access is absolutely not allowed, such as financial data, and   
3) Data shared with other applications is absolutely not allowed.
ehcache
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

		<!-- Enable Second-Level Cache and Query Cache Settings -->
		<property name="hibernate.cache.use_second_level_cache">true</property>
		<property name="hibernate.cache.use_query_cache">true</property>
		<class-cache usage="read-only" class="com.sds.bean.Person"/>

Transaction isolation The isolation level can be set explicitly
in the Hibernate configuration file. Each isolation level corresponds to an integer:
1: Read Uncommitted
2: Read Committed
4: Repeatable Read
8: Serializable
For example, the following code sets the isolation level in the hibernate.cfg.xml file to Read Committed:
hibernate.connection.isolation =2
For each connection obtained from the database connection pool, Hibernate will change it to use the Read Committed isolation level.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326129575&siteId=291194637