hibernate 學習

hibernate學習

//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"
  */

 
class層面有:
@hibernate.cache
@hibernate.jcs-cache
@hibernate.joined-subclass
@hibernate.joined-subclass-key
@hibernate.query

 
method 層面
 
@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語言
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 保存到數據庫
以上會出現約束爲例,關聯字段允許爲null
最後的解決方式:讓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 對於多對多一般不採用級聯刪除
多對多需要
多對多關聯必須同時對關聯雙方進行保存


發佈了35 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章