A. Hibernate:關於復雜的sql統計語句是不是就不適合使用Hibernate了
在這方面我也和你有同感。
不同的ORM工具各有其優缺點和適用范圍。Hibernate使數據操作對象化,在對象和數據之間做了很好的銜接,非常適用於數據的維護類操作和明細查詢操作,而對於數據統計類的操作則顯得作用不強。Hibernate歷來支持原生的SQL,較新的版本也支持對SQL、Stored Procere甚至XML的封裝,也可以像iBatis,現在叫作MyBatis,對部分欄位封裝。Hibernate的新功能越來越像iBatis了。iBatis或MyBatis是對SQL的封裝,相對簡單、靈活,性能也相對好些,但不是絕對的,其性能的好壞主要取衡悔決於編寫的SQL的質量,而iBatis的動態SQL本身就是對性能的一種威脅。iBatis或MyBatis適用於做各種數據操作,不過需要良好的SQL能力和對具體資料庫(如Oracle、SQLServer)的了解,故而在維護、變更或資料庫升級、遷移時比較復雜。較新的MyBatis提供了一些類似於Hibernate的特徵,比如可以支持父子表對象之間的雙相關聯;而另外一些特性,衫攔嘩比如註解式的SQL封裝、通過代理根據介面定義自動實例化DAO,似乎比Hibernate還要好些。JDBC 3.0和4.0比以前也增加了一些新特徵,具體的我還沒有仔細研究。呵呵
在我看來,報表是需求中最不穩定的部分,形式多樣、變化多端,無論是自己編寫的還是第三方的公共組件,都只能在基礎查詢和表現形式上加工;具體的報表邏輯仍需手工開發。所以無論用哪種技術做報表,在報表邏輯方面的復雜度是相同的。我一般會採用相對最簡單的技術條件來設計報表,避免程序員把功夫較多得花在不太熟悉的數據工具和報表工具上。
希望能對你或行有所幫助。
B. hibernate更新某個欄位其餘null欄位不能新怎麼實現
在<class 寫 dynamic-update="true"> Hibernate生成動態SQL語句的消耗的系統資源(比如CPU,內存等)是很小枝圓首的,
所以不會影響到系猛數統的性能,如果表中包含N多欄位,建議把 dynamic-update屬性和insert屬性設腔猛置為true,
這樣在插入和修改數據的時候,語句中只包括要插入或者修改的欄位.可以節省SQL語句的執行時間,提高程序的運行效率.
C. hibernate,jpa資料庫連接問題。我沒法確定要連接什麼資料庫,但是我要用原生sql來update數據
寫個適配器器吧,傳入資料庫類型,輸出拼接的sql。
其實個人更建議你使用hibernate的Hql來作sql相關操作,首先它語法和通用Sql是近似的,不一樣的地方在於 語句里寫的是類名 不是表名,最後hibernate會根據Hql翻譯成當前資料庫可執行的sql來執行,這樣你就不需要去判斷究竟是什麼資料庫,寫法支持不支持。
當然,如果你的語句特復雜一定得用Sql server或者Oracle的特殊語法,那沒辦法,寫個適配器吧
以下是HQL相關資料
HQL查詢:
Criteria查詢對查詢條件進行了面向對象封裝,符合編程人員的思維方式,不過HQL(Hibernate Query Lanaguage)查詢提供了更加豐富的和靈活的查詢特性,因此
Hibernate將HQL查詢方式立為官方推薦的標准查詢方式,HQL查詢在涵蓋Criteria查詢的所有功能的前提下,提供了類似標准SQL語句的查詢方式,同時也提供了更
加面向對象的封裝。完整的HQL語句形勢如下:
Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc
其中的update/delete為Hibernate3中所新添加的功能,可見HQL查詢非常類似於標准SQL查詢。由於HQL查詢在整個Hibernate實體操作體系中的核心地位,這一節我
將專門圍繞HQL操作的具體技術細節進行講解。
1、 實體查詢:
有關實體查詢技術,其實我們在先前已經有多次涉及,比如下面的例子:
String hql=」from User user 」;
List list=session.CreateQuery(hql).list();
上面的代碼執行結果是,查詢出User實體對象所對應的所有數據,而且將數據封裝成User實體對象,並且放入List中返回。這里需要注意的是,Hibernate的實體查
詢存在著對繼承關系的判定,比如我們前面討論映射實體繼承關系中的Employee實體對象,它有兩個子類分別是HourlyEmployee,SalariedEmployee,如果有這樣的
HQL語句:「from Employee」,當執行檢索時Hibernate會檢索出所有Employee類型實體對象所對應的數據(包括它的子類HourlyEmployee,SalariedEmployee對應
的數據)。
因為HQL語句與標准SQL語句相似,所以我們也可以在HQL語句中使用where字句,並且可以在where字句中使用各種表達式,比較操作符以及使用「and」,」or」連接
不同的查詢條件的組合。看下面的一些簡單的例子:
from User user where user.age=20;
from User user where user.age between 20 and 30;
from User user where user.age in(20,30);
from User user where user.name is null;
from User user where user.name like 『%zx%』;
from User user where (user.age%2)=1;
from User user where user.age=20 and user.name like 『%zx%』;
2、 實體的更新和刪除:
在繼續講解HQL其他更為強大的查詢功能前,我們先來講解以下利用HQL進行實體更新和刪除的技術。這項技術功能是Hibernate3的新加入的功能,在Hibernate2
中是不具備的。比如在Hibernate2中,如果我們想將資料庫中所有18歲的用戶的年齡全部改為20歲,那麼我們要首先將年齡在18歲的用戶檢索出來,然後將他們的
年齡修改為20歲,最後調用Session.update()語句進行更新。在Hibernate3中對這個問題提供了更加靈活和更具效率的解決辦法,如下面的代碼:
Transaction trans=session.beginTransaction();
String hql=」update User user set user.age=20 where user.age=18」;
Query queryupdate=session.createQuery(hql);
int ret=queryupdate.executeUpdate();
trans.commit();
通過這種方式我們可以在Hibernate3中,一次性完成批量數據的更新,對性能的提高是相當的可觀。同樣也可以通過類似的方式來完成delete操作,如下面的代碼
:
Transaction trans=session.beginTransaction();
String hql=」delete from User user where user.age=18」;
Query queryupdate=session.createQuery(hql);
int ret=queryupdate.executeUpdate();
trans.commit();
如果你是逐個章節閱讀的化,那麼你一定會記起我在第二部分中有關批量數據操作的相關論述中,討論過這種操作方式,這種操作方式在Hibernate3中稱為bulk
delete/update,這種方式能夠在很大程度上提高操作的靈活性和運行效率,但是採用這種方式極有可能引起緩存同步上的問題(請參考相關論述)。
3、 屬性查詢:
很多時候我們在檢索數據時,並不需要獲得實體對象所對應的全部數據,而只需要檢索實體對象的部分屬性所對應的數據。這時候就可以利用HQL屬性查詢技術
,如下面程序示例:
List list=session.createQuery(「select user.name from User user 」).list();
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
我們只檢索了User實體的name屬性對應的數據,此時返回的包含結果集的list中每個條目都是String類型的name屬性對應的數據。我們也可以一次檢索多個屬性,
如下面程序:
List list=session.createQuery(「select user.name,user.age from User user 」).list();
for(int i=0;i<list.size();i++){
Object[] obj=(Object[])list.get(i);
System.out.println(obj[0]);
System.out.println(obj[1]);
}
此時返回的結果集list中,所包含的每個條目都是一個Object[]類型,其中包含對應的屬性數據值。作為當今我們這一代深受面向對象思想影響的開發人員,可能
會覺得上面返回Object[]不夠符合面向對象風格,這時我們可以利用HQL提供的動態構造實例的功能對這些平面數據進行封裝,如下面的程序代碼:
List list=session.createQuery(「select new User(user.name,user.age) from User user 」).list();
for(int i=0;i<list.size();i++){
User user=(User)list.get(i);
System.out.println(user.getName());
System.out.println(user.getAge());
}
這里我們通過動態構造實例對象,對返回結果進行了封裝,使我們的程序更加符合面向對象風格,但是這里有一個問題必須注意,那就是這時所返回的User對象,
僅僅只是一個普通的Java對象而以,除了查詢結果值之外,其它的屬性值都為null(包括主鍵值id),也就是說不能通過Session對象對此對象執行持久化的更新操
作。如下面的代碼:
List list=session.createQuery(「select new User(user.name,user.age) from User user 」).list();
for(int i=0;i<list.size();i++){
User user=(User)list.get(i);
user.setName(「gam」);
session.saveOrUpdate(user);//這里將會實際執行一個save操作,而不會執行update操作,因為這個User對象的id屬性為null,Hibernate會把它作為一個自由對
象(請參考持久化對象狀態部分的論述),因此會對它執行save操作。
}
4、 分組與排序
A、Order by子句:
與SQL語句相似,HQL查詢也可以通過order by子句對查詢結果集進行排序,並且可以通過asc或者desc關鍵字指定排序方式,如下面的代碼:
from User user order by user.name asc,user.age desc;
上面HQL查詢語句,會以name屬性進行升序排序,以age屬性進行降序排序,而且與SQL語句一樣,默認的排序方式為asc,即升序排序。
B、Group by子句與統計查詢:
在HQL語句中同樣支持使用group by子句分組查詢,還支持group by子句結合聚集函數的分組統計查詢,大部分標準的SQL聚集函數都可以在HQL語句中使用,比如:
count(),sum(),max(),min(),avg()等。如下面的程序代碼:
String hql=」select count(user),user.age from User user group by user.age having count(user)>10 」;
List list=session.createQuery(hql).list();
C、優化統計查詢:
假設我們現在有兩張資料庫表,分別是customer表和order表,它們的結構如下:
customer
ID varchar2(14)
age number(10)
name varchar2(20)
order
ID varchar2(14)
order_number number(10)
customer_ID varchar2(14)
現在有兩條HQL查詢語句,分別如下:
from Customer c inner join c.orders o group by c.age;(1)
select c.ID,c.name,c.age,o.ID,o.order_number,o.customer_ID
from Customer c inner join c.orders c group by c.age;(2)
這兩條語句使用了HQL語句的內連接查詢(我們將在HQL語句的連接查詢部分專門討論),現在我們可以看出這兩條查詢語句最後所返回的結果是一樣的,但是它們
其實是有明顯區別的,語句(1)檢索的結果會返回Customer與Order持久化對象,而且它們會被置於Hibernate的Session緩存之中,並且Session會負責它們在緩存
中的唯一性以及與後台資料庫數據的同步,只有事務提交後它們才會從緩存中被清除;而語句(2)返回的是關系數據而並非是持久化對象,因此它們不會佔用
Hibernate的Session緩存,只要在檢索之後應用程序不在訪問它們,它們所佔用的內存就有可能被JVM的垃圾回收器回收,而且Hibernate不會同步對它們的修改。
在我們的系統開發中,尤其是Mis系統,不可避免的要進行統計查詢的開發,這類功能有兩個特點:第一數據量大;第二一般情況下都是只讀操作而不會涉及到對統
計數據進行修改,那麼如果採用第一種查詢方式,必然會導致大量持久化對象位於Hibernate的Session緩存中,而且Hibernate的Session緩存還要負責它們與數據
庫數據的同步。而如果採用第二種查詢方式,顯然就會提高查詢性能,因為不需要Hibernate的Session緩存的管理開銷,而且只要應用程序不在使用這些數據,它
們所佔用的內存空間就會被回收釋放。
因此在開發統計查詢系統時,盡量使用通過select語句寫出需要查詢的屬性的方式來返回關系數據,而避免使用第一種查詢方式返回持久化對象(這種方式是在有
修改需求時使用比較適合),這樣可以提高運行效率並且減少內存消耗。㊣真正的高手並不是精通一切,而是精通在合適的場合使用合適的手段。
5、 參數綁定:
Hibernate中對動態查詢參數綁定提供了豐富的支持,那麼什麼是查詢參數動態綁定呢?其實如果我們熟悉傳統JDBC編程的話,我們就不難理解查詢參數動態綁定,
如下代碼傳統JDBC的參數綁定:
PrepareStatement pre=connection.prepare(「select * from User where user.name=?」);
pre.setString(1,」zhaoxin」);
ResultSet rs=pre.executeQuery();
在Hibernate中也提供了類似這種的查詢參數綁定功能,而且在Hibernate中對這個功能還提供了比傳統JDBC操作豐富的多的特性,在Hibernate中共存在4種參數綁
定的方式,下面我們將分別介紹:
A、 按參數名稱綁定:
在HQL語句中定義命名參數要用」:」開頭,形式如下:
Query query=session.createQuery(「from User user where user.name=:customername and user.customerage=:age 」);
query.setString(「customername」,name);
query.setInteger(「customerage」,age);
上面代碼中用:customername和:customerage分別定義了命名參數customername和customerage,然後用Query介面的setXXX()方法設定名參數值,setXXX()方法包
含兩個參數,分別是命名參數名稱和命名參數實際值。
B、 按參數位置邦定:
在HQL查詢語句中用」?」來定義參數位置,形式如下:
Query query=session.createQuery(「from User user where user.name=? and user.age =? 」);
query.setString(0,name);
query.setInteger(1,age);
同樣使用setXXX()方法設定綁定參數,只不過這時setXXX()方法的第一個參數代表邦定參數在HQL語句中出現的位置編號(由0開始編號),第二個參數仍然代表參
數實際值。
註:在實際開發中,提倡使用按名稱邦定命名參數,因為這不但可以提供非常好的程序可讀性,而且也提高了程序的易維護性,因為當查詢參數的位置發生改變時
,按名稱邦定名參數的方式中是不需要調整程序代碼的。
C、 setParameter()方法:
在Hibernate的HQL查詢中可以通過setParameter()方法邦定任意類型的參數,如下代碼:
String hql=」from User user where user.name=:customername 」;
Query query=session.createQuery(hql);
query.setParameter(「customername」,name,Hibernate.STRING);
如上面代碼所示,setParameter()方法包含三個參數,分別是命名參數名稱,命名參數實際值,以及命名參數映射類型。對於某些參數類型setParameter()方法可
以更具參數值的Java類型,猜測出對應的映射類型,因此這時不需要顯示寫出映射類型,像上面的例子,可以直接這樣寫:
query.setParameter(「customername」,name);但是對於一些類型就必須寫明映射類型,比如java.util.Date類型,因為它會對應Hibernate的多種映射類型,比如
Hibernate.DATA或者Hibernate.TIMESTAMP。
D、 setProperties()方法:
在Hibernate中可以使用setProperties()方法,將命名參數與一個對象的屬性值綁定在一起,如下程序代碼:
Customer customer=new Customer();
customer.setName(「pansl」);
customer.setAge(80);
Query query=session.createQuery(「from Customer c where c.name=:name and c.age=:age 」);
query.setProperties(customer);
setProperties()方法會自動將customer對象實例的屬性值匹配到命名參數上,但是要求命名參數名稱必須要與實體對象相應的屬性同名。
這里還有一個特殊的setEntity()方法,它會把命名參數與一個持久化對象相關聯,如下面代碼所示:
Customer customer=(Customer)session.load(Customer.class,」1」);
Query query=session.createQuery(「from Order order where order.customer=:customer 」);
query. setProperties(「customer」,customer);
List list=query.list();
上面的代碼會生成類似如下的SQL語句:
Select * from order where customer_ID=』1』;
E、 使用綁定參數的優勢:
我們為什麼要使用綁定命名參數?任何一個事物的存在都是有其價值的,具體到綁定參數對於HQL查詢來說,主要有以下兩個主要優勢:
①、 可以利用資料庫實施性能優化,因為對Hibernate來說在底層使用的是PrepareStatement來完成查詢,因此對於語法相同參數不同的SQL語句,可
以充分利用預編譯SQL語句緩存,從而提升查詢效率。
②、 可以防止SQL Injection安全漏洞的產生:
SQL Injection是一種專門針對SQL語句拼裝的攻擊方式,比如對於我們常見的用戶登錄,在登錄界面上,用戶輸入用戶名和口令,這時登錄驗證程序可能會生成如
下的HQL語句:
「from User user where user.name=』」+name+」』 and user.password=』」+password+」』 」
這個HQL語句從邏輯上來說是沒有任何問題的,這個登錄驗證功能在一般情況下也是會正確完成的,但是如果在登錄時在用戶名中輸入」zhaoxin or 『x』=』x」,
這時如果使用簡單的HQL語句的字元串拼裝,就會生成如下的HQL語句:
「from User user where user.name=』zhaoxin』 or 『x』=』x』 and user.password=』admin』 」;
顯然這條HQL語句的where字句將會永遠為真,而使用戶口令的作用失去意義,這就是SQL Injection攻擊的基本原理。
而使用綁定參數方式,就可以妥善處理這問題,當使用綁定參數時,會得到下面的HQL語句:
from User user where user.name=』』zhaoxin』』 or 『』x=』』x』』 『 and user.password=』admin』;由此可見使用綁定參數會將用戶名中輸入的單引號解
析成字元串(如果想在字元串中包含單引號,應使用重復單引號形式),所以參數綁定能夠有效防止SQL Injection安全漏洞。
D. Hibernate4 升級到Hibernate5 中 sql查詢注意事項
在 Hibernate4 中,利用原生SQL語句查詢時,
1、可使用Session.createSQLQuery(sql)建立Qurey(org.hibernate.Query),
2、可使用Query.setParameter(int index, Object obj),對sql語句中的參數根據位置進行參數值動態綁定;
升級到 Hibernate5 後
1、org.hibernate.Query被標記為@Deprecated
2、Session().createSQLQuery(sql)返回類型為org.hibernate.query.Query;
3、並且Session().createSQLQuery也已經被標記為@Deprecated;
4、可使用Session().createNativeQuery(sql)代替createSQLQuery。
5、createNativeQuery返回的Query, 不可 通過setParameter(int index, Object obj) 根據位置 進行參數值動態綁定; 只可以 通過setParameter(String paramname, Object obj) 按參數名稱綁定 。
6、createNativeQuery(sql)中的sql語句中的 查詢佔位符
只可使用 命名參數 方式進行編寫。
上問錯誤例子中,將導致如下錯誤:
E. Hibernate有幾種查詢方法
轉錄:
從點到面,講講hibernate查詢的6種方法。分別是HQL查詢
,對象化查詢Criteria方法,動態查詢DetachedCriteria,例子查詢,sql查詢,命名查詢。
如果單純的使用hibernate查詢資料庫只需要懂其中的一項就可以完成想要實現的一般功能,但是
從一個點,讓我們掌握6中方法,則提供了更多選擇。每一種方法都有其適用的情況與前提。
HQL查詢
HQL是hibernate自己的一套查詢語言,於SQL語法不同,具有跨資料庫的優點。示例代碼:
static void query(String name){
Session s=null;
try{
s=HibernateUtil.getSession();
//from後面是對象,不是表名
String hql="from Admin as admin where admin.aname=:name";//使用命名參數,推薦使用,易讀。
Query query=s.createQuery(hql);
query.setString("name", name);
List<Admin> list=query.list();
for(Admin admin:list){
System.out.println(admin.getAname());
}
}finally{
if(s!=null)
s.close();
}
}
適用情況:常用方法,比較傳統,類似jdbc。缺點:新的查詢語言,適用面有限,僅適用於Hibernate框架。
對象化查詢Criteria方法:
static void cri(String name,String password){
Session s=null;
try{
s=HibernateUtil.getSession();
Criteria c=s.createCriteria(Admin.class);
c.add(Restrictions.eq("aname",name));//eq是等於,gt是大於,lt是小於,or是或
c.add(Restrictions.eq("apassword", password));
List<Admin> list=c.list();
for(Admin admin:list){
System.out.println(admin.getAname());
}
}finally{
if(s!=null)
s.close();
}
}
適用情況:面向對象操作,革新了以前的資料庫操作方式,易讀。缺點:適用面較HQL有限。
動態分離查詢DetachedCriteria
static List dc(DetachedCriteria dc) {
Session s = HibernateUtil.getSession();
Criteria c = dc.getExecutableCriteria(s);
List rs = c.list();
s.close();
return rs;
}
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
int id = 1;
if (id != 0)
dc.add(Restrictions.eq("id", id));
Date age = new Date();
if (age != null)
dc.add(Restrictions.le("birthday", age));
List users = dc(dc);
System.out.println("離線查詢返回結果:" + users);
適用情況:面向對象操作,分離業務與底層,不需要欄位屬性攝入到Dao實現層。 缺點:適用面較HQL有限。
例子查詢
static List example(User user) {
Session s = HibernateUtil.getSession();
List<User> users = s.createCriteria(User.class).add(
Example.create(user)).list();
// List<User>
// users2=s.createCriteria(User.class).add((Example.create(user)).ignoreCase())
// .createCriteria("child").add((Example.create(user))).list();
return users;
}
適用情況:面向對象操作。 缺點:適用面較HQL有限,不推薦。
sql查詢
static List sql() {
Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}
適用情況:不熟悉HQL的朋友,又不打算轉資料庫平台的朋友,萬能方法 缺點:破壞跨平台,不易維護,不面向對象。
命名查詢
static List namedQuery(int id) {
Session s = HibernateUtil.getSession();
Query q = s.getNamedQuery("getUserById");
q.setInteger("id", id);
return q.list();
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sy.vo.User" table="user" catalog="news">
</class>
<!-- 命名查詢:定義查詢條件 -->
<query name="getUserById">
<![CDATA[from User where id=:id]]>
</query>
<!-- 命名查詢中使用sql,不推薦使用,影響跨資料庫
<sql-query name="getUserById2">
<![CDATA[select * from User where ]]>
</sql-query> -->
</hibernate-mapping>
適用情況:萬能方法,有點像ibatis輕量級框架的操作,方便維護。 缺點:不面向對象。基於hql和sql,有一定缺陷。
F. 各位大俠們,hibernate怎麼完成動態生成sql語句的啊
用QueryByCriteria模式
G. Hibernate和MyBatis哪個好
使用Hibernate進行編程有以下好處:
1,消除了代碼的映射規則,它全部分離到了xml或者註解裡面去配置。
2,無需在管理資料庫連接,它也配置到xml裡面了。
3,一個會話中不需要操作多個對象,只需要操作Session對象。
4,關閉資源只需要關閉一個Session便可。
這就是Hibernate的優勢,在配置了映射文件和資料庫連接文件後,Hibernate就可以通過Session操作,非常容易,消除了jdbc帶來的大量代碼,大大提高了編程的簡易性和可讀性。Hibernate還提供了級聯,緩存,映射,一對多等功能。Hibernate是全表映射,通過HQL去操作pojo進而操作資料庫的數據。
Hibernate的缺點:
1,全表映射帶來的不便,比如更新時需要發送所有的欄位。
2,無法根據不同的條件組裝不同的SQL。
3,對多表關聯和復雜的sql查詢支持較差,需要自己寫sql,返回後,需要自己將數據封裝為pojo。
4,不能有效的支持存儲過程。
5,雖然有HQL,但是性能較差,大型互聯網系統往往需要優化sql,而hibernate做不到。
Mybatis:
為了解決Hibernate的不足,Mybatis出現了,Mybatis是半自動的框架。之所以稱它為半自動,是因為它需要手工匹配提供POJO,sql和映射關系,而全表映射的Hibernate只需要提供pojo和映射關系即可。
Mybatis需要提供的映射文件包含了一下三個部分:sql,映射規則,pojo。在Mybatis裡面你需要自己編寫sql,雖然比Hibernate配置多,但是Mybatis可以配置動態sql,解決了hibernate表名根據時間變化,不同條件下列不一樣的問題,同時你也可以對sql進行優化,通過配置決定你的sql映射規則,也能支持存儲過程,所以對於一些復雜和需要優化性能的sql查詢它就更加方便。Mybatis幾乎可以做到jdbc所有能做到的事情。
什麼時候使用Hibernate,Mybatis
Hibernate作為留下的Java orm框架,它確實編程簡易,需要我們提供映射的規則,完全可以通過IDE生成,同時無需編寫sql確實開發效率優於Mybatis。此外Hibernate還提供了緩存,日誌,級聯等強大的功能,但是Hibernate的缺陷也是十分明顯,多表關聯復雜sql,數據系統許可權限制,根據條件變化的sql,存儲過程等場景使用Hibernate十分不方便,而性能又難以通過sql優化,所以註定了Hibernate只適用於在場景不太復雜,要求性能不太苛刻的時候使用。
如果你需要一個靈活的,可以動態生成映射關系的框架,那麼Mybatis確實是一個最好的選擇。它幾乎可以替代jdbc,擁有動態列,動態表名,存儲過程支持,同時提供了簡易的緩存,日誌,級聯。但是它的缺陷是需要你提供映射規則和sql,所以開發工作量比hibernate要大些。
H. 現在有個需求,用的是hibernate,需要在hibernate攔截器中對查詢的sql進行where條件拼接
這個寫起來很麻煩,提供解決思路。
1、在web.xml里實現攔截器配置。針對於某一個連接跳轉的。
2、攔截器功能實現,拿到參數。實現需要反射進行實現,同時要保證線程安全。
3、參數處理放到Session里。
4、在實際SQL語句中查詢。
如果跟spring集成的話,建議使用spring的AOP,進行動態代理實現。 進行初期處理。
I. java hibernate執行多條SQL語句的問題
要兼容,還是分開語句吧。多寫幾行代碼而已。
sql.append("create table tempTestTable(a char(4)); ");
sql.append("alter table tempTestTable add test " + columnType + "(50);");
既然都是自己處理的,兩句合成一句,不更方便
sql.append("create table tempTestTable(a " + columnType + "(50) ");
columnType 還要看可能輸入的情況
J. hibernate框架用什麼替代好呢這個框架太復雜,載入太慢。
ibatis替代即可,優點如下:
Ibatis的優勢。
Ibatis是一個混合性的解決方案,吸取了這些所有解決方案中最有價值的思想,並將他們融會貫通.
1) proc(procere) 支持對 procere 的直接調用; 業務碧褲邏輯從資料庫中分離出來,程序念慧鏈有更好的移植性。
2) 內聯sql 允許sql以最自然的方式書寫,沒有字元串拼接,沒有參數設置,沒有結果獲取; 對應用程序的代碼沒有任何的影響.
3) o/rm Ibatis有許多o/rm工具一樣的特性,高速緩存,運行時生成代碼,延遲載入等; 可用於任意數據模型和對象模型的組合。javaBean或業務類。
4) 動態 sql Ibatis支持動態sql來處理查詢; 不要求sql被寫成一堆字元串。
Ibatis的特點
o/rm通過java對象和Db之間的映射,而仔孫Ibatis通過sql與資料庫的映射,通過sql的查詢參數和結果來和java對象映射
總結:
1 容易上手,小巧
2 生產效力高
3 性能好
4 分工明確
5 支持java,.net,ruby
6 開源