hibernate學習
學習hibernate:
middlegen
Hibernate 基本語義
Configuration\sesionFactory\Session
Hibernate高級特性
XDoclet 與 Hibernate的映射
數據檢索
數據關聯
數據訪問
事務管理
Hibernate分頁
Cache管理
Session管理
Hibernate in Spring
對象關係型數據映射:orm(object relational mapping) 映射文件".hbm.xml"
構建hebernate基本代碼的通常做法:
1.手工編寫
2.從關係型數據庫導出表結構,生成orm文件和java代碼(推薦)(middlegen-guberbate)
3.通過java代碼生成對應的映射文件,將java代碼和數據庫綁定(xdoclet)
映射文件中的主鍵生成發生:increment(少用 多個實例訪問數據庫可能造成主鍵重複)
Hibernate的配置
Hibernate.cfg.xml(hibernate.propertys)
sessionFactory 負責創建session實例.通過configuration 實例構建sessionFactory
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
Session 是持久層操作的基礎,相當於jdbc中的connection
sessionFactory.openSession();
Session提供所提供的save、find、flush等方法完成持久層操作
Session.flush()強制數據庫同步,事務提交的時候hibernate會自動調用flush方法,session關閉也會自動執行flush方法
Hibernate-doclet使用
下面是XDoclet的一些build.xml
<?xml version="1.0" encoding="GBK"?>
<project name="構建腳本" default="生成Hibernate配置文件" basedir=".">
<property name="src.dir" value="${basedir}/src"/>
<property name="build.dir" value="${basedir}/bin"/>
<property name="xdoclet.home" value="D:/xdoclet/xdoclet-plugins-1.0.3"/>
<!-- Build classpath -->
<path id="xdoclet.task.classpath">
<fileset dir="${xdoclet.home}/lib">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${xdoclet.home}/plugins">
<include name="**/*.jar"/>
</fileset>
</path>
<taskdef
name="xdoclet"
classname="org.xdoclet.ant.XDocletTask"
classpathref="xdoclet.task.classpath"
/>
<target name="生成Hibernate配置文件">
<xdoclet>
<fileset dir="${src.dir}/com/csy/model">
<include name="**/*.java"/>
</fileset>
<component
classname="org.xdoclet.plugin.hibernate.HibernateConfigPlugin"
destdir="${src.dir}"
version="3.0"
hbm2ddlauto="update"
jdbcurl="jdbc:mysql://127.0.0.1/csy"
jdbcdriver="com.mysql.jdbc.Driver"
jdbcusername="root"
jdbcpassword="bjsxt"
dialect="org.hibernate.dialect.MySQLDialect"
showsql="true"
/>
</xdoclet>
</target>
<target name="生成hibernate映射文件">
<xdoclet>
<fileset dir="${src.dir}/com/csy/model">
<include name="**/*.java"/>
</fileset>
<component
classname="org.xdoclet.plugin.hibernate.HibernateMappingPlugin"
version="3.0"
destdir="${src.dir}"
/>
</xdoclet>
</target>
</project>
下面列舉了點XDoclet的常用語法,官方指南http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html
和 http://www.hibernate.org
他可分爲class層面和method層面
/**
* @hibernate.class
* table="T_ACL"
* dynamic-update="true"
* dynamic-insert="true"
* proxy=""
* discriminator-value="1"
*/
/**
* @hibernate.id generator-class="native"
*/
/**
* @hibernate.set lazy="extra" inverse="true"
* @hibernate.key column="pid"
* @hibernate.one-to-many class="com.csy.userBean"
*/
/**
* @hibernate.many-to-one unique="true"
*/
/**
* @hibernate.property
* unique="true"
* not-null="true"
*/
/**
* @hibernate.one-to-one property-ref="person"
*/
@hibernate.cache
@hibernate.jcs-cache
@hibernate.joined-subclass
@hibernate.joined-subclass-key
@hibernate.query
@hibernate.array
@hibernate.bag
@hibernate.collection-cache
@hibernate.collection-composite-element
@hibernate.collection-element
@hibernate.collection-index
@hibernate.collection-jcs-cache
有三種:
1.Criteria Query
2.Hibernate Query Language (HQL)
3.SQL
先說下Criteria Query的用法:通過面向對象的設計
將數據查詢封裝爲一個對象
Criteria criteria = session.createCriteria(TUser.class);
criteria.add(Expression.eq("name","csy"));
criteria.add(Expression.eq("age",18));
//相當於 select * from t_user where name="csy" and age=18
其中Expression提供了對應的查詢限定機制,包括:
Expression.eq
Expression.allEq
Expression.gt
Expression.ge
Expression.lt
Expression.le
Expression.between
例子:
Expression.between("age",new Integer(10),new Integer(18));
Expression.like
Expression.in
Expression.eqProperty (用於比較兩個屬性的值)例子:
Expression.eqProperty(
"UserBean.ClassId",
"ClassBean.id"
);//對應於sql語句裏面的UserBean.ClassId = ClassBean.id
Expression.gtProperty
Expression.geProperty
Expression.ltProperty
Expression.and例子:
Expression.and(
Expression.eq("name","Erica"),
Expression.eq(
"sex",new Integer(1)
)
)
Expression.or
Expression.sql(
"lower({alias}.name) like lower(?)",
"csy%",
Hibernate.STRING
)
限定換回記錄
criteria.setFristResult/setMaxResults
對查詢結果進行排序
criteria.addOrder(Order.asc("name"));
criteria.addOrder(Order.desc("age"));
hql的格式如下:
String hql = "from UserBean as user where user.name='csy'";
Query query = session.createQuery(hql);
List userList = query.list();
//有時間再總結下hql的所有用法
下面學習下hibernate 的數據關聯
其中一對一關聯 如用戶和身份證就是一對一的關聯
只要在主控方進行控制
one-to-one節點有以下屬性
複製內容到剪貼板
name 映射屬性
class 映射類
cascade :all:none:save-update:delete
級聯(cascade)指的是 :當主控方執行操作時候,關聯對象(被動方)
同步執行同一操作。如對主控方對象調用save-update或delete方法時
是否通俗對關聯對象(被動方)進行save-update或者delete操作
代碼:
單向一對多 只要在一的一方進行配置
雙向一對多 要在兩邊都進行配置
一對多例子:用戶和地址
user.getAddresses().add(addr);
session.save(user);//通過主控對象級聯更新
tx.commit();
hibernate會分兩步來對地址的操作
save(user)時
insert into t_address(user_id,address) values (null,"南京")
tx.commit()時
update t_address set user_id="1" ,address="南京" where id = 2
這樣會有問題:t_address.user_id 爲"NOT NULL"就會報錯
出現以上問題的原因是:inverse 爲"true"
關聯方向是單向,關聯關係由userBean對象維護而被關聯的addressBean對象本身並不知道自己於userBean對象向關聯
也就是addressBean不知道user_id設什麼值
所以是保存addressBean時候關聯字段先插入一個空值,再由userBean對象將自身的id賦予關聯字段addressBean.user_id
導致address對象發生變化,commit的時候會通過update sql 保存到數據庫
最後的解決方式:讓addressBean對象知道獲取user_id字段,這樣還少了update語句,提高了性能
雙向一對多的關係就可以解決上面的問題
一對多
inverse 爲“true” 這意味這主控方不再是UserBean,把關聯關係交給addressBean,這樣就可以主動去獲取UserBean的id並將其作爲自己的user_id
java代碼編寫有所改變:
add.setUser(user);//設置關聯的userBean對象
user.getAddresses().add(addr);
session.save(user);//級聯更新
下面學習多對多 需要有一箇中間表。cascade 爲save-update 對於多對多一般不採用級聯刪除
多對多需要
多對多關聯必須同時對關聯雙方進行保存