一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 詳解Java的Hibernate框架中的緩存與原生SQL語(yǔ)句的使用

詳解Java的Hibernate框架中的緩存與原生SQL語(yǔ)句的使用

2020-03-13 13:24goldensun JAVA教程

這篇文章主要介紹了Java的Hibernate框架中的緩存與原生SQL語(yǔ)句的使用,Hibernate是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下

Hibernate緩存
緩存是所有關(guān)于應(yīng)用程序的性能優(yōu)化和它位于應(yīng)用程序和數(shù)據(jù)庫(kù)之間,以避免數(shù)據(jù)庫(kù)訪問(wèn)多次,讓性能關(guān)鍵型應(yīng)用程序有更好的表現(xiàn)。

緩存對(duì)Hibernate很重要,它采用了多級(jí)緩存方案下文所述:

詳解Java的Hibernate框架中的緩存與原生SQL語(yǔ)句的使用

第一級(jí)緩存:
第一級(jí)緩存是Session的緩存,是一個(gè)強(qiáng)制性的緩存,通過(guò)它所有的請(qǐng)求都必須通過(guò)。 Session對(duì)象不斷自身的動(dòng)力的對(duì)象,提交到數(shù)據(jù)庫(kù)之前。

如果發(fā)出多個(gè)更新一個(gè)對(duì)象,Hibernate試圖拖延盡可能長(zhǎng)的時(shí)間做了更新,以減少發(fā)出的更新SQL語(yǔ)句的數(shù)量。如果您關(guān)閉會(huì)話,所有被緩存的對(duì)象都將丟失,要么持久,或在數(shù)據(jù)庫(kù)中更新。

二級(jí)緩存:
二級(jí)緩存是可選的緩存和一級(jí)緩存,總是會(huì)征詢?nèi)魏卧噲D找到一個(gè)對(duì)象的二級(jí)緩存之前。第二級(jí)緩存可以在每個(gè)類和每個(gè)集合基礎(chǔ)上進(jìn)行配置,主要負(fù)責(zé)在會(huì)話緩存的對(duì)象。

任何第三方緩存可以使用Hibernate。org.hibernate.cache.CacheProvider接口提供,必須實(shí)施提供Hibernate一個(gè)句柄緩存實(shí)現(xiàn)。

查詢級(jí)別緩存:
Hibernate也實(shí)現(xiàn)了查詢結(jié)果集緩存與二級(jí)緩存的緊密集成在一起。

這是一個(gè)可選功能,需要兩個(gè)額外的物理緩存中保存緩存的查詢結(jié)果和地區(qū)當(dāng)一個(gè)表的最后更新的時(shí)間戳。這只是針對(duì)那些使用相同的參數(shù)經(jīng)常運(yùn)行的查詢非常有用。

二級(jí)緩存:
Hibernate使用一級(jí)緩存,默認(rèn)情況下,你什么都沒(méi)有做使用第一級(jí)緩存。讓我們直接進(jìn)入可選的第二級(jí)緩存。并不是所有的類受益于緩存,這樣一來(lái)就能禁用二級(jí)緩存是很重要的

Hibernate二級(jí)緩存被設(shè)置為兩個(gè)步驟。首先,必須決定要使用的并發(fā)策略。在此之后,可以配置緩存過(guò)期和使用緩存提供物理緩存屬性。

并發(fā)策略:
并發(fā)策略是一個(gè)中介的負(fù)責(zé)存儲(chǔ)數(shù)據(jù)項(xiàng)在緩存并從緩存中檢索它們。如果要啟用二級(jí)緩存,將必須決定,為每個(gè)持久化類和集合,要使用的緩存并發(fā)策略。

Transactional: 使用這種策略的主要讀取數(shù)據(jù)的地方,以防止過(guò)時(shí)的數(shù)據(jù)的并發(fā)事務(wù),在更新的罕見(jiàn)情況下是至關(guān)重要的。

Read-write: 再次使用這種策略的主要讀取數(shù)據(jù)的地方,以防止并發(fā)事務(wù)陳舊的數(shù)據(jù)是至關(guān)重要的,在更新的罕見(jiàn)情況。

Nonstrict-read-write: 這種策略不保證緩存與數(shù)據(jù)庫(kù)之間的一致性。使用此策略,如果數(shù)據(jù)很少改變和陳舊數(shù)據(jù)的可能性很小關(guān)鍵是不關(guān)注。

Read-only: 并發(fā)策略適用于數(shù)據(jù),永遠(yuǎn)不會(huì)改變。使用數(shù)據(jù)僅供參考。

如果我們要使用第二級(jí)緩存為我們的Employee類,讓我們添加告訴Hibernate使用可讀寫(xiě)的高速緩存策略Employee實(shí)例所需的映射元素。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
  <class name="Employee" table="EMPLOYEE">
   <meta attribute="class-description">
     This class contains the employee detail.
   </meta>
   <cache usage="read-write"/>
   <id name="id" type="int" column="id">
     <generator class="native"/>
   </id>
   <property name="firstName" column="first_name" type="string"/>
   <property name="lastName" column="last_name" type="string"/>
   <property name="salary" column="salary" type="int"/>
  </class>
</hibernate-mapping>

 usage="read-write" 屬性告訴Hibernate使用一個(gè)可讀寫(xiě)的并發(fā)策略定義的緩存。

緩存提供者:
考慮到會(huì)用你的緩存候選類的并發(fā)策略后,下一步就是選擇一個(gè)緩存提供程序。Hibernate迫使選擇一個(gè)緩存提供整個(gè)應(yīng)用程序。

詳解Java的Hibernate框架中的緩存與原生SQL語(yǔ)句的使用

在指定hibernate.cfg.xml配置文件中的緩存提供。選擇EHCache作為第二級(jí)緩存提供程序:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
  <session-factory>
  <property name="hibernate.dialect">
   org.hibernate.dialect.MySQLDialect
  </property>
  <property name="hibernate.connection.driver_class">
   com.mysql.jdbc.Driver
  </property>
 
  <!-- Assume students is the database name -->
  <property name="hibernate.connection.url">
   jdbc:mysql://localhost/test
  </property>
  <property name="hibernate.connection.username">
   root
  </property>
  <property name="hibernate.connection.password">
   root123
  </property>
  <property name="hibernate.cache.provider_class">
   org.hibernate.cache.EhCacheProvider
  </property>
 
  <!-- List of XML mapping files -->
  <mapping resource="Employee.hbm.xml"/>
 
</session-factory>
</hibernate-configuration>

現(xiàn)在,需要指定緩存區(qū)域的屬性。EHCache都有自己的配置文件ehcache.xml,在應(yīng)用程序在CLASSPATH中。在ehcache.xml中Employee類高速緩存配置可能看起來(lái)像這樣:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
 
<cache name="Employee"
maxElementsInMemory="500"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>

就這樣,現(xiàn)在啟用Employee類的二級(jí)緩存和Hibernate現(xiàn)在二級(jí)緩存,每當(dāng)瀏覽到一個(gè)雇員或當(dāng)通過(guò)標(biāo)識(shí)符加載雇員。

應(yīng)該分析你所有的類,并選擇適當(dāng)?shù)木彺娌呗詾槊總€(gè)類。有時(shí),二級(jí)緩存可能降級(jí)的應(yīng)用程序的性能。所以建議到基準(zhǔn)應(yīng)用程序第一次沒(méi)有啟用緩存,非常適合緩存和檢查性能。如果緩存不提高系統(tǒng)性能再有就是在使任何類型的緩存是沒(méi)有意義的。

查詢級(jí)別緩存:
使用查詢緩存,必須先使用 hibernate.cache.use_query_cache="true"屬性配置文件中激活它。如果將此屬性設(shè)置為true,讓Hibernate的在內(nèi)存中創(chuàng)建所需的高速緩存來(lái)保存查詢和標(biāo)識(shí)符集。

接下來(lái),使用查詢緩存,可以使用Query類的setCacheable(Boolean)方法。例如:

?
1
2
3
4
5
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate也支持通過(guò)一個(gè)緩存區(qū)域的概念非常細(xì)粒度的緩存支持。緩存區(qū)是這是給定一個(gè)名稱緩存的一部分。

?
1
2
3
4
5
6
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

此代碼使用方法告訴Hibernate來(lái)存儲(chǔ)和查找在緩存中的員工方面的查詢。


Hibernate原生SQL
可以使用原生SQL來(lái)表達(dá)數(shù)據(jù)庫(kù)查詢,如果想利用數(shù)據(jù)庫(kù)特有的功能,如查詢提示或者Oracle中的CONNECT關(guān)鍵字。 Hibernate3.x允許使用手寫(xiě)SQL語(yǔ)句,包括存儲(chǔ)過(guò)程,所有的創(chuàng)建,更新,刪除和load操作。

應(yīng)用程序?qū)臅?huì)話創(chuàng)建一個(gè)原生SQL查詢(Session接口上)createSQLQuery()方法:

public SQLQuery createSQLQuery(String sqlString) throws HibernateException
當(dāng)傳遞一個(gè)包含SQL查詢到createSQLQuery()方法,可以將SQL結(jié)果與任何現(xiàn)有的Hibernate實(shí)體,聯(lián)接,或者一個(gè)標(biāo)量結(jié)果使用addEntity()方法,addJoin(),和addScalar()方法關(guān)聯(lián)的字符串。

標(biāo)量查詢:
最基本的SQL查詢是從一個(gè)或多個(gè)表中得到標(biāo)量(數(shù)值)的列表。以下是語(yǔ)法使用原生SQL標(biāo)量的值:

?
1
2
3
4
String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();

實(shí)體的查詢:
上面的查詢都是返回標(biāo)量值,也就是從resultset中返回的“裸”數(shù)據(jù)。以下是語(yǔ)法通過(guò)addEntity()方法來(lái)從原生SQL查詢獲得實(shí)體對(duì)象作為一個(gè)整體。

?
1
2
3
4
String sql = "SELECT * FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
List results = query.list();

命名SQL查詢:
以下是語(yǔ)法通過(guò)addEntity()方法來(lái)從原生SQL查詢獲得實(shí)體對(duì)象和使用命名SQL查詢。

?
1
2
3
4
5
String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();

Native SQL 例子:
考慮下面的POJO類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Employee {
  private int id;
  private String firstName;
  private String lastName; 
  private int salary;
 
  public Employee() {}
  public Employee(String fname, String lname, int salary) {
   this.firstName = fname;
   this.lastName = lname;
   this.salary = salary;
  }
  public int getId() {
   return id;
  }
  public void setId( int id ) {
   this.id = id;
  }
  public String getFirstName() {
   return firstName;
  }
  public void setFirstName( String first_name ) {
   this.firstName = first_name;
  }
  public String getLastName() {
   return lastName;
  }
  public void setLastName( String last_name ) {
   this.lastName = last_name;
  }
  public int getSalary() {
   return salary;
  }
  public void setSalary( int salary ) {
   this.salary = salary;
  }
}

讓我們創(chuàng)建下面的EMPLOYEE表來(lái)存儲(chǔ)Employee對(duì)象:

?
1
2
3
4
5
6
7
create table EMPLOYEE (
  id INT NOT NULL auto_increment,
  first_name VARCHAR(20) default NULL,
  last_name VARCHAR(20) default NULL,
  salary   INT default NULL,
  PRIMARY KEY (id)
);

以下將被映射文件。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
  <class name="Employee" table="EMPLOYEE">
   <meta attribute="class-description">
     This class contains the employee detail.
   </meta>
   <id name="id" type="int" column="id">
     <generator class="native"/>
   </id>
   <property name="firstName" column="first_name" type="string"/>
   <property name="lastName" column="last_name" type="string"/>
   <property name="salary" column="salary" type="int"/>
  </class>
</hibernate-mapping>

最后,我們將創(chuàng)建應(yīng)用程序類的main()方法來(lái)運(yùn)行,我們將使用原生SQL查詢的應(yīng)用程序:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import java.util.*;
 
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Configuration;
 
public class ManageEmployee {
  private static SessionFactory factory;
  public static void main(String[] args) {
   try{
     factory = new Configuration().configure().buildSessionFactory();
   }catch (Throwable ex) {
     System.err.println("Failed to create sessionFactory object." + ex);
     throw new ExceptionInInitializerError(ex);
   }
   ManageEmployee ME = new ManageEmployee();
 
   /* Add few employee records in database */
   Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
   Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
   Integer empID3 = ME.addEmployee("John", "Paul", 5000);
   Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);
 
   /* List down employees and their salary using Scalar Query */
   ME.listEmployeesScalar();
 
   /* List down complete employees information using Entity Query */
   ME.listEmployeesEntity();
  }
  /* Method to CREATE an employee in the database */
  public Integer addEmployee(String fname, String lname, int salary){
   Session session = factory.openSession();
   Transaction tx = null;
   Integer employeeID = null;
   try{
     tx = session.beginTransaction();
     Employee employee = new Employee(fname, lname, salary);
     employeeID = (Integer) session.save(employee);
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
   return employeeID;
  }
 
  /* Method to READ all the employees using Scalar Query */
  public void listEmployeesScalar( ){
   Session session = factory.openSession();
   Transaction tx = null;
   try{
     tx = session.beginTransaction();
     String sql = "SELECT first_name, salary FROM EMPLOYEE";
     SQLQuery query = session.createSQLQuery(sql);
     query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
     List data = query.list();
 
     for(Object object : data)
     {
      Map row = (Map)object;
      System.out.print("First Name: " + row.get("first_name"));
      System.out.println(", Salary: " + row.get("salary"));
     }
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
  }
 
  /* Method to READ all the employees using Entity Query */
  public void listEmployeesEntity( ){
   Session session = factory.openSession();
   Transaction tx = null;
   try{
     tx = session.beginTransaction();
     String sql = "SELECT * FROM EMPLOYEE";
     SQLQuery query = session.createSQLQuery(sql);
     query.addEntity(Employee.class);
     List employees = query.list();
 
     for (Iterator iterator =
              employees.iterator(); iterator.hasNext();){
      Employee employee = (Employee) iterator.next();
      System.out.print("First Name: " + employee.getFirstName());
      System.out.print(" Last Name: " + employee.getLastName());
      System.out.println(" Salary: " + employee.getSalary());
     }
     tx.commit();
   }catch (HibernateException e) {
     if (tx!=null) tx.rollback();
     e.printStackTrace();
   }finally {
     session.close();
   }
  }
}

編譯和執(zhí)行:
下面是步驟來(lái)編譯并運(yùn)行上述應(yīng)用程序。請(qǐng)確保在進(jìn)行的編譯和執(zhí)行之前,適當(dāng)?shù)卦O(shè)置PATH和CLASSPATH。

執(zhí)行ManageEmployee二進(jìn)制文件來(lái)運(yùn)行程序。

會(huì)得到以下結(jié)果,并記錄將在EMPLOYEE表中創(chuàng)建。

?
1
$java ManageEmployee
?
1
2
3
4
5
6
7
8
9
10
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........
 
First Name: Zara, Salary: 2000
First Name: Daisy, Salary: 5000
First Name: John, Salary: 5000
First Name: Mohd, Salary: 3000
First Name: Zara Last Name: Ali Salary: 2000
First Name: Daisy Last Name: Das Salary: 5000
First Name: John Last Name: Paul Salary: 5000
First Name: Mohd Last Name: Yasee Salary: 3000

如果檢查EMPLOYEE表,它應(yīng)該記錄下已:

?
1
mysql> select * from EMPLOYEE;
?
1
2
3
4
5
6
7
8
9
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 26 | Zara    | Ali    |  2000 |
| 27 | Daisy   | Das    |  5000 |
| 28 | John    | Paul   |  5000 |
| 29 | Mohd    | Yasee   |  3000 |
+----+------------+-----------+--------+
4 rows in set (0.00 sec)

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 韩国成人毛片aaa黄 含羞草国产亚洲精品岁国产精品 | 久久精品视频免费 | 俄罗斯女人与公拘i交酡 | 精品AV亚洲乱码一区二区 | 亚洲一卡2卡三卡4卡5卡组 | 色婷在线 | h肉动漫在线视频无修无遮挡 | 99久久久久国产 | a亚洲天堂 | 久久免费特黄毛片 | 三级伦理在线播放 | 四虎永久成人免费 | 波多野结衣在线免费观看 | 国产综合久久久久久 | 日韩在线视频免费观看 | 国产永久一区二区三区 | 精品国产线拍大陆久久尤物 | 免费特黄一级欧美大片 | 男人日女人p | 亚洲精品97福利在线 | 色老板最新网站视频地址 | 成人免费淫片95视频观看网站 | 我与白丝同桌的故事h文 | 精品国产一区二区三区在线 | 久久婷婷丁香五月色综合啪免费 | 99在线观看免费视频 | www视频免费看 | 亚洲视频一区二区在线观看 | 强迫高h | 亚洲第一成年免费网站 | 青青草精品在线 | 性奶老妇 视频 | 羞羞色男人的天堂伊人久久 | 暖暖视频日本 | 91aaa免费免费国产在线观看 | 国内精品久久久久久中文字幕 | 91最新高端约会系列178 | 草莓香蕉绿巨人丝瓜榴莲18 | 日本aaaa级 | 国产黄频在线观看高清免费 | 情缘免费观看完整版 |