hibernate筆記
標示符屬性生成策略:
1、 increment:獲取最大的值,加一做爲當前的屬性的值,什麼數據庫中都可以使用。
<id name="id" type="javalang.Integer" column = "ID">
<grenrator class = "increment"> </grenrator>
</id>
2、identity:MS SQL Server、MySql和DB2中,有一個自動增長的字段。
Oracle數據庫就不支持,一位Oracle數據庫不支持這個
3、sequence:
4、hilo:高低位生成策略。
<id name="id" type="javalang.Integer" column = "ID">
<grenrator class = "hilo">
<param name = table >hibernate_key</param>
<param name=column>next_hivalue</param>
</grenrator>
</id>
創建一個表名字叫做hibernate_key 其中一個字段叫做next_hivalue,整形數據
5、uuid,如何數據中都可以使用,生成一串字符串,不重複的,產生的不是全數字,數度很快,它不用任何參數。
<id name=id type=java.lang.String column=ID>
<generator class=uid></generator>
</id>
6、guid:只有在ms sql和mysql中應用。
<id name=id type=java.lang.String column=ID>
<generator class=guid></generator>
</id>
7、native:根據使用的數據庫的支持功能自動選擇,從identity、sequence、hilo生成策略中選擇一個。
8、assigned:客戶包辦,由客戶指定
hibernate對象的生命週期:
Persistent:持久態
session.save(gb)
Transient:順管
GuestBook g = new()
g.set(....)
....
沒有調用save的()的時候
調用svae()後就變了persistent態了
detached:脫管態
session.close()
remove:刪除態
session.geginTransacation().commit()
=============================================
session 髒數據的檢查
GuestBook book = session.get(GuestBook.class, Integer(1));
book.set(....)
沒掉用save方法,調用了set數據變髒了
Transaction tran = session.begsinStra.....
tran.commit()
調用了commit,hibernate會自動更新數據庫,因爲現在現在的對象處於了持久態
========session.saveOrUpdate(gb):
會自動判斷,判斷id是否已經存在數據庫中了,自動添加或者修改。
========session.flash(),他已經跟close方法綁定了在一起了。
========session.close(),當sessin對象跟實物綁定在一起,則調用commit會自動調用了
只要是session.getCurrentSession().跟當前實物綁定session對象。
=========================================================================
不可更改的持久化對象。只讀對象
<class name= table= mutiable="false">
</class>
Open Session In View模式:
比如:上面說的用getCurrentSession()的形式get到session的時候
Transaction.commit(gb)後我們又調用gb.getTitle()
則可能會拋出異常了。
Configuration config = new Configuration().configure();
SessionFactory sfac = config.buildSessionFactory();
this.session = sfac.getCurrentSession();
。。。。。。。。。。。。。
Transaction.commit()
。。。。。。
System.println(gb.getTitle())
泛型DAO的設計模式與實現:
比如與底層的數據操作,我可以用JDBC實現也可以用hibernate實現,那麼這個時候我們就Kyocera用dao模型來實現,方便我們切換。
定義個泛型接口:
Public interface GenericDao<T, PK extends Serializable> {
Public T findById(PK id);
Public List<T> findAll();
…………………………
}
頂一個累實現上面的接口:
Public class GreneriacDaohibernate< T, PK extends Serializable > implements GenericDao<T, PK> {
Private Class<T> clazz;
}
集合映射:
Set:不能重複,不記錄對象加入的先後順序
sprivate Set<String> emails = new HashSet<String>();
<class name="" table="" schema="">
<id name="" type="">
<column name="" precision="" scale=""></column>
<generator class="increment"></generator>
</id>
<property name="" type="">
<column name="" not-null="" .....></column>
</property>
............
<set name="emails(對象的屬性名字)" table="email">
<key column="userID" foreign="id"(對應主表對象的主鍵屬性名) ></key>
<element type="" column="email(表的字段名字)"
</set>
</class>
List:可以重複,記錄對象的加入先後順序
private List<String> emails = new ArrayList();
<list name="" table="">
<key column="" foreign-key=""></key>
<index column="idx" type=""></index>
<element type="" column=></element>
</list>
Bag:允許重複,不記錄對象的加入先後順序
private Collection<String> emails = new ArrayList();
<bag name="" table="">
<key column="" foreign-key=""/>
<element type="" column=""/>
</bag>
IdBag: 是Bag的擴展,可以指定id值,跟List相識
---------------------------------------------------
Map映射:保存key及對應的value的,key不可以重複
Map:
eg:phonse("office", "110") phones("hone","113") phones("mobile", "333")
排序:sort是以key排序,用set或者map的sort排序,是在內存中排序再輸出的。數據量大的時候不推薦用此方法排序
order by排序,按字段排序,order-by=userID desc
<map name="phones" table="userPhone" sort="natural" [order-by="phoneNumber"]>
<key column="userID" foreign-key="id"></key>
<map-key type="java.lang.String" column="usage"></map-key>
<element type="java.lang.String" column="phoneNumber"></element>
</map>
HashMap:不記錄加入的加入的先後循序。
LinkedHashMap:記錄加入的先後順序。
TreeMap:支持排序
組建映射:
組建映射的單向關聯、組建映射的雙向關聯:
<!-- 組建(component)映射,雙向關聯 -->
<component name="Profile" class="com.hibernate.test.study.study7.Profile">
<!-- name是 profile對象的 關聯屬性名字 (指定雙向關聯)-->
<parent name="user"/>
<property name="sex" type="java.lang.String">
<column name="sex" length="16" not-null="true" />
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="20" not-null="true" />
</property>
<property name="email" type="java.lang.String">
<column name="email" length="30" not-null="true" />
</property>
<property name="address" type="java.lang.String">
<column name="address" length="100" />
</property>
<property name="postCode" type="java.lang.String">
<column name="postCode" length="6" />
</property>
</component>
組建集合映射:
<!-- 組建集合映射 雙向關聯 -->
<!-- name = Product類的屬性名字 table = 表的名字 -->
<set name="productImages" table="productImages">
<!-- 指定外鍵 -->
<key column="productID" foreign-key="id" not-null="true"></key>
<composite-element class="com.hibernate.test.study.study7.Image">
<!-- 指定Image中雙向關聯的屬性名字 -->
<parent name="product"/>
<property name="fileName" column="fileName"></property>
<property name="filePath" column="filePath"></property>
<property name="fileSize" column="fileSize"></property>
</composite-element>
</set>
映射多對一,一對多關係 單向、雙向:
一對多映射關係: 當products中有該category的一個分類的時候,即有該分類的產品存在products表的時候,mysql不允許刪除該分類,Oracle好像是允許刪除,然後置該產品的外鍵爲空。
<hibernate-mapping>
<class name="com.hibernate.test.study.study8.Category" table="category" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="30" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="65535" />
</property>
<!-- 映射一對多關係 name=類的關聯屬性名字 cascade級聯-->
<set name="productses" inverse="true" [cascade="savesave-update"] >
<key>
<column name="categoryID" />
</key>
<one-to-many class="com.hibernate.test.study.study8.Products" />
</set>
</class>
</hibernate-mapping>
映射多對多對一關係:
<hibernate-mapping>
<class name="com.hibernate.test.study.study8.Products" table="products" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="100" />
</property>
<property name="price" type="java.lang.Float">
<column name="price" precision="12" scale="0" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="65535" />
</property>
<!-- 映射多對一的關係 nameo=對象關聯屬性名稱 必須指明class outer-join="true" 表示使用關聯查詢,一次查詢出來-->
<many-to-one name="category" class="com.hibernate.test.study.study8.Category" outer-join="true">
<column name="categoryID" />
</many-to-one>
</class>
</hibernate-mapping>
級聯:主動方執行一個動作的時候,被動方(關聯方)也執行相應的動作
cascade:
none:默認
save-update: 主動方調用save update saveOrUpdate的時候關聯方也執行
delete:主動方執行save的時候被動執行
delete-orphan:只應用於一對多,主動方掉delete的時候,此時不被任何一個關聯對象所引用被關聯對象全被刪除,即刪除孤立項
all:
<!-- 映射一對多關係 name=類的關聯屬性名字,inverse="true"控制反轉, cascade級聯-->
<set name="productses" inverse="true" [cascade="savesave-update"] >
<key>
<column name="categoryID" />
</key>
<one-to-many class="com.hibernate.test.study.study8.Products" />
</set>
java code:
public void addproduct2() {
Session session = HibernateSessionFactoryUtil.sfac.openSession();
session.getTransaction().begin();
Category cat = new Category();
cat.setName("U盤");
cat.setDescription("各式各樣的U盤");
Products pro = new Products();
pro.setName("金斯頓1gU盤");
pro.setPrice(5999.0f);
pro.setDescription("金斯頓1gU盤金斯頓1gU盤");
Products pro2 = new Products();
pro2.setName("金斯頓2gU盤");
pro2.setPrice(5999.0f);
pro2.setDescription("金斯頓2gU盤金斯頓2gU盤");
pro.setCategory(cat);
pro2.setCategory(cat);
cat.getProductses().add(pro);
cat.getProductses().add(pro2);
session.save(cat);
session.getTransaction().commit();
session.close();
}
映射 一對一關係,單向、雙向,一共有兩種方式:
1、共享主鍵關聯
2、唯一外鍵關聯
1、共享主鍵關聯:公用一個主鍵,具有相同的值。
Userinfo4.hm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study9.Userinfo4" table="userinfo4" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<!-- 指定共享主鍵 -->
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="email" type="java.lang.String">
<column name="email" length="30" />
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="20" />
</property>
<one-to-one name="user" class="com.hibernate.test.study.study9.User4"></one-to-one>
</class>
</hibernate-mapping>
User4.hm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study9.User4" table="user4" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="userName" type="java.lang.String">
<column name="userName" length="20" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="20" not-null="true" />
</property>
<one-to-one name="userInfo" class="com.hibernate.test.study.study9.Userinfo4"></one-to-one>
</class>
</hibernate-mapping>
java code:
public void addUser() {
Session session = HibernateSessionFactoryUtil.sfac.openSession();
session.getTransaction().begin();
User4 user = new User4();
user.setUserName("zhuxiangdong");
user.setPassword("333333");
Userinfo4 userInfo = new Userinfo4();
userInfo.setEmail("[email protected]");
userInfo.setTel("8662012");
user.setUserInfo(userInfo);
userInfo.setUser(user);
session.save(user);
session.save(userInfo);
//userInfo會自動獲取user的ID作爲自己的ID主鍵
session.getTransaction().commit();
session.close();
}
User4跟Userinfo4是雙向關聯的:
eg:
//通過User可以找到Userinfo
public void loadUser() {
Session session = HibernateSessionFactoryUtil.sfac.openSession();
User4 user = (User4) session.load(User4.class, new Integer(4));
System.out.println(user.getId());
System.out.println(user.getUserName());
System.out.println(user.getPassword());
Userinfo4 userInfo = user.getUserInfo();
System.out.println(userInfo.getId());
System.out.println(userInfo.getEmail());
System.out.println(userInfo.getTel());
}
//通過Userinfo可以找到User
public void loadUserinfo() {
Session session = HibernateSessionFactoryUtil.sfac.openSession();
Userinfo4 userInfo = (Userinfo4) session.load(Userinfo4.class, new Integer(4));
System.out.println(userInfo.getId());
System.out.println(userInfo.getEmail());
System.out.println(userInfo.getTel());
User4 user = userInfo.getUser();
System.out.println(user.getId());
System.out.println(user.getUserName());
System.out.println(user.getPassword());
}
2、唯一外鍵關聯:(數據庫設置的是外鍵不可重複,約定只有一條記錄與之對應,即一對一關係),配置,我們應用多對一,一對多的配置相似。靠uniqu="true"這個類控制的。
Userinfo4.hbm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study9.Userinfo4" table="userinfo4" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<!-- 指定共享主鍵 -->
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<property name="email" type="java.lang.String">
<column name="email" length="30" />
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="20" />
</property>
<!--指定唯一外鍵:unique=“true”-->
<many-to-one name="user" class="com.hibernate.test.study.study9.User4" uniqu="true"></many-to-one>
</class>
</hibernate-mapping>
User4.hbm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study9.User4" table="user4" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="userName" type="java.lang.String">
<column name="userName" length="20" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="20" not-null="true" />
</property>
<one-to-one name="userInfo" class="com.hibernate.test.study.study9.Userinfo4" unique="true"></one-to-one>
</class>
</hibernate-mapping>
映射多對多關聯,單向、雙向:需要借用一箇中間表
Orders5.hbm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study10.Orders5" table="orders5" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="relName" type="java.lang.String">
<column name="relName" length="20" />
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="10" />
</property>
<property name="totalMoney" type="java.lang.Float">
<column name="totalMoney" precision="12" scale="0" />
</property>
<set name="products" table="orderProduct5">
<key column="orderID"></key>
<many-to-many class="com.hibernate.test.study.study10.Products5" column="productID"></many-to-many>
</set>
</class>
</hibernate-mapping>
products5.hbm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study10.Products5" table="products5" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="60" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="65535" />
</property>
</class>
</hibernate-mapping>
(備註:上面只做了單向關聯,但是上面呢沒有雙向關聯的必要,若要加上雙向,請加上下面的配置:)
<hibernate-mapping>
<class name="com.hibernate.test.study.study10.Products5" table="products5" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="60" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="65535" />
</property>
<set name="orders" table="Orders5">
<key column="productID"></key>
<many-to-many class="com.hibernate.test.study.study10.Orders5" column="orderID"></many-to-many>
</set>
</class>
</hibernate-mapping>
多對多關聯拆分爲兩個一對多的關聯:因爲上面無法記錄我們購買的數量和購買的時候的價格,因爲價格是波動的,不同時期價格不同的。
Orders7.hbm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study10.Orders7" table="orders7" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="relName" type="java.lang.String">
<column name="relName" length="20" />
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length="10" />
</property>
<property name="totalMoney" type="java.lang.Float">
<column name="totalMoney" precision="12" scale="0" />
</property>
<!-- 同時指定級聯朝着 -->
<set name="orderProducts" cascade="save-update">
<key>
<column name="orderID"></column>
</key>
<one-to-many class="com.hibernate.test.study.study10.Orderproduct7"/>
</set>
</class>
</hibernate-mapping>
orderProduct7.hbm.xml:
<hibernate-mapping>
<class name="com.hibernate.test.study.study10.Orderproduct7" table="orderProduct7" catalog="test_mysql">
<!-- 指定複合主鍵 -->
<composite-id>
<key-many-to-one name="product" class="com.hibernate.test.study.study10.Products7">
<column name="productID" />
</key-many-to-one>
<key-many-to-one name="order" class="com.hibernate.test.study.study10.Orders7">
<column name="orderID" />
</key-many-to-one>
<key-property name="quantity" type="java.lang.Integer">
<column name="quantity" />
</key-property>
<key-property name="price" type="java.lang.Float">
<column name="price" precision="12" scale="0" />
</key-property>
</composite-id>
</class>
</hibernate-mapping>
主意:如果我們需要使用複合主鍵的時候,如果我們使用set集合的時候,因爲set是不允許重複的,如果元素是一個對象的時候,java可能不知道如何去判斷着兩個對象是否相等,這個時候就需要我們重寫
對象的equals方法,而equals方法用到hashCode方法它是一個比較技術,所以我們 也要重寫hashcode方法:
eg:
public class Orders7 implements java.io.Serializable {
// Fields
private Integer id;
private String relName;
private String tel;
private Float totalMoney;
private Set orderProducts = new HashSet(0);
........
}
public class Orderproduct7 implements java.io.Serializable {
private static final long serialVersionUID = -2002077161452152357L;
// Fields
private Orders7 order;
private Products7 product;
private Integer quantity;
private float price;
.............
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((order == null) ? 0 : order.hashCode());
result = PRIME * result + Float.floatToIntBits(price);
result = PRIME * result + ((product == null) ? 0 : product.hashCode());
result = PRIME * result + ((quantity == null) ? 0 : quantity.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Orderproduct7 other = (Orderproduct7) obj;
if (order == null) {
if (other.order != null)
return false;
} else if (!order.equals(other.order))
return false;
if (Float.floatToIntBits(price) != Float.floatToIntBits(other.price))
return false;
if (product == null) {
if (other.product != null)
return false;
} else if (!product.equals(other.product))
return false;
if (quantity == null) {
if (other.quantity != null)
return false;
} else if (!quantity.equals(other.quantity))
return false;
return true;
}
}
一個特殊的多對多關聯:無限子類別:
java code:
// Fields
private Integer id;
private String name;
private String description;
private Integer parentId;
private Integer level;
//設置父類
private Category1 category;
//設置子類
private Set categorys = new HashSet(0);
// Constructors
public Category1 getCategory() {
return category;
}
配置:
Category.hbm.xml:
<class name="com.hibernate.test.study.study10.Category1" table="category1" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="30" not-null="true" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="200" not-null="true" />
</property>
<property name="parentId" type="java.lang.Integer">
<column name="parentID" />
</property>
<property name="level" type="java.lang.Integer">
<column name="level" />
</property>
<!-- 配置父類 -->
<many-to-one name="category" class="com.hibernate.test.study.study10.Category1" fetch="select" insert="false" update="false">
<column name="parentID"></column>
</many-to-one>
<!-- 配置子類 -->
<set name="categorys" inverse="true">
<key>
<column name="parentID"></column>
</key>
<one-to-many class="com.hibernate.test.study.study10.Category1"/>
</set>
</class>
Criteria查詢
public void loadByE() {
Session session = HibernateSessionFactoryUtil.sfac.openSession();
session.getTransaction().begin();
Criteria cri = session.createCriteria(Guestbook11.class);
// Criterion criterion = Restrictions.eq("name", "朱向東");
// Criterion criterion = Restrictions.between("id", 1, 2);
// Criterion criterion = Restrictions.gt("id", 2);
// Criterion criterion1 = Restrictions.like("name", "朱%");
// Criterion criterion2 = Restrictions.between("id", 1, 2);
//Criterion orCriterion = Restrictions.or(criterion1, criterion2);
//and 複合條件
// cri.add(criterion1);
// cri.add(criterion2);
// cri.add(orCriterion);
//排序設置
cri.addOrder(Order.asc("id"));
//設置分頁
// cri.setMaxResults(4); //設置返回的數據的條數
// cri.setFirstResult(0); //設置從第幾條數據開始讀
//設置值返回一條記錄
// cri.setMaxResults(1);
// //設置返回一條記錄的時候,不用去讀list集合了,直接用uniqueRest()方法
// Guestbook11 tempGb = (Guestbook11) cri.uniqueResult();
// System.out.println(tempGb.getId()+ "---" + tempGb.getName());
List<Guestbook11> list = cri.list();
for (Guestbook11 item : list) {
System.out.println(item.getId()+ "---" + item.getName());
}
session.getTransaction().commit();
session.close();
}
聚集函數查詢:
public void loadByE2() {
Session session = HibernateSessionFactoryUtil.sfac.openSession();
session.getTransaction().begin();
Criteria criteria = session.createCriteria(Guestbook11.class);
//聚集函數查詢
// criteria.setProjection(Projections.max("id"));
// Integer maxId = (Integer) criteria.uniqueResult();
// System.out.println(maxId.intValue());
//多個聚集函數查詢
// ProjectionList projectionList = Projections.projectionList();
// projectionList.add(Projections.max("id"));
// projectionList.add(Projections.rowCount());
// projectionList.add(Projections.count("id"));
// projectionList.add(Projections.min("id"));
// projectionList.add(Projections.sum("id"));
// projectionList.add(Projections.avg("id"));
// criteria.setProjection(projectionList);
// Object[] objects = (Object[]) criteria.uniqueResult();
// for(Object item : objects) {
// System.out.println(item.toString());
// }
session.getTransaction().commit();
session.close();
}
分組查詢
Criteria criteria = session.createCriteria(Guestbook11.class);
criteria.setProjection(Projections.groupProperty("name"));
List<String> list = criteria.list();
for(String item : list) {
System.out.println(item);
}
分組統計查詢:
Criteria criteria = session.createCriteria(Guestbook11.class);
ProjectionList prolist = Projections.projectionList();
prolist.add(Projections.groupProperty("name"));
prolist.add(Projections.rowCount());
criteria.setProjection(prolist);
List<Object[]> list = criteria.list();
for(Object[] item : list) {
for (Object item2 : item) {
System.out.print(item2);
}
System.out.println();
}
投影查詢:
criteria.setProjection(Property.forName("name"));
criteria.setProjection(Property.forName("id"));
......
//根據實例查詢
Guestbook11 gb = new Guestbook11();
gb.setName("朱向東");
Criteria criteria = session.createCriteria(Guestbook11.class);
criteria.add(Example.create(gb));
List<Guestbook11> list = criteria.list();
for(Guestbook11 item : list) {
System.out.println(item.getName());
}
org.hibernate.criterion.Restrictions 類的方法:
HQL與Native SQL查詢
Query接口的常用方法:
list()
iterate() //1+N方式查詢,會使用非常多sql語句,先把所有的id查出來放在緩存,在根據緩存中的id一個一個區查詢所有記錄,
setMaxResults()
setFirstResult()
uniqueRestlt()
Query query = session.createQuery("From GuestBook11");
query.setMaxResults(20);
query.setFirstResult(0);
//query.serMaxResults(1);
//Guestbook11 gb = (Guestbook11) query.uniqueResult();
List<Guestbook11> list = query.list();
//Iterate iterate = query.iterate();
-------------------------------------------------------------------------
HQL:
Query query = session.createQuery("select id, title, name form guestbook");
List<Object[]> list = query.list();
//一定要保證這種類型的構造方法存在
//Query query = session.createQuery("select new Guestbook11(id, title, name) from guestbook11");
//List<Guestbook11> list = query.list();
//Query query = session.createQuery("select new Map(id, title, name) from guestbook11");
//List<Map> list = query.list();
//for(Map m : list) {
// m.get("0"); m.get("1"); m.get("3");
//}
//使用別名 key value一一對應
//Query query = session.createQuery("select new Map(gb.id as id, gb.title as title, gb.name as name) from guestbook11 as gb");
//List<Map> list = query.list();
//for(Map m : list) {
// m.get("id"); m.get("title"); m.get("name");
//}
----------------------------------------------------------------------
"from guestbook where name like '%liu%'"
"from guestbook where name like '?liu%'"
"from guestbook where name like 'liu%'"
"from guestbook where name like '%liu'"
"from guestbook where name not like 'liu%'"
"from guestbook where id>100 order by id desc"
"from guesbook where not (id>1) order by id, price asc "
session.createQuery("from guestbook id>:myid")
query.setInteger("mydi", 12);
Query q = session.createQuery("select avb(price), count(*) from product group by category.id having price > 12.1");
hibernate與search
搜索引擎:
全文搜索引擎:Google 百度 雅虎
目錄索引搜索引擎:黃頁等。。。。
元搜索引擎:搜索的數據來自於多個搜索引擎數據的組合。
Lucene:java領域的全文搜索的工具包,http://lucene.apache.org
Hibernate Search:支持索引數據的自動更新,支持衆多的搜索方式。。。。。。。
繼承映射
方法一:把所有子類信息放到一個表中;它支持多態查詢,並且多態查詢的性能高,但是會導致數據庫空間的浪費。
<hibernate-mapping>
<class name="com.hibernate.test.study13.car13" table="car13" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<discriminator column="carType"></discriminator>
<property name="createDate" type="java.util.Date">
<column name="createDate" length="0" not-null="true" />
</property>
<property name="color" type="java.lang.String">
<column name="color" length="10" not-null="true" />
</property>
<subclass name="com.hibernate.test.study13.minCar13" discriminator-value="minCar">
<property name="isBaoMa" type="java.lang.String">
<column name="isbaoma" length="10" not-null="false" />
</property>
</subclass>
<subclass name="com.hibernate.test.study13.bigCar13" discriminator-value="bigCar">
<property name="isDongFeng" type="java.lang.String">
<column name="isdongfeng" length="10" not-null="false" />
</property>
</subclass>
</class>
</hibernate-mapping>
javacode:
public void insertMinCar() {
minCar13 mcar = new minCar13();
mcar.setColor("blue");
mcar.setCreateDate(new Date("2/2/2010"));
mcar.setIsBaoMa("yes");
bigCar13 bcar = new bigCar13();
bcar.setColor("white");
bcar.setCreateDate(new Date("9/9/1999"));
bcar.setIsDongFeng("yes");
Session session = HibernateSessionFactoryUtil.sfac.openSession();
session.getTransaction().begin();
session.save(mcar);
session.save(bcar);
session.getTransaction().commit();
session.close();
}
方法二:父類定義爲abstract,所有的子類對應一個表,並且子類的表多包涵共同的屬性,兩表無外鍵關聯等;辭方式支持多態查詢,多態查詢的性能不理想。
<hibernate-mapping>
<class name="com.hibernate.test.study13.car13" table="car13" catalog="test_mysql" abstract=“true”>
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="createDate" type="java.util.Date">
<column name="createDate" length="0" not-null="true" />
</property>
<property name="color" type="java.lang.String">
<column name="color" length="10" not-null="true" />
</property>
<union-subclass name="com.hibernate.test.study13.minCar13" table="minCar">
<property name="isBaoMa" type="java.lang.String">
<column name="isbaoma" length="10" not-null="false" />
</property>
</union-subclass>
<union-subclass name="com.hibernate.test.study13.bigCar13" table="bigCar">
<property name="isDongFeng" type="java.lang.String">
<column name="isdongfeng" length="10" not-null="false" />
</property>
</union-subclass>
</class>
</hibernate-mapping>
方法三:每個類多用對應一個表,把公共的信息放到父類對應的表,子類對應的信息放到子類對應的表,兩字表通過外鍵關聯父類表,可以設置即是主鍵也是外鍵來實現。查詢的時候會用到連接查詢,多態查詢的時候會連接查詢。性能較高,複合關係數據庫的設計(公共信息放到一個表中),缺點關聯查詢效率不太高,因爲要操作多個表。
<hibernate-mapping>
<class name="com.hibernate.test.study13.car13" table="car13" catalog="test_mysql">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="createDate" type="java.util.Date">
<column name="createDate" length="0" not-null="true" />
</property>
<property name="color" type="java.lang.String">
<column name="color" length="10" not-null="true" />
</property>
<joined-subclass name="com.hibernate.test.study13.minCar13" table="minCar">
<key column="id" forign-key="id"></key>
<property name="isBaoMa" type="java.lang.String">
<column name="isbaoma" length="10" not-null="false" />
</property>
</joined-subclass>
<joined-subclass name="com.hibernate.test.study13.bigCar13" table="bigCar">
<key column="id" forign-key="id"></key>
<property name="isDongFeng" type="java.lang.String">
<column name="isdongfeng" length="10" not-null="false" />
</property>
</joined-subclass>
</class>
</hibernate-mapping>
Hibernate事物管理
Hibernate中的事物:hibernate中有兩種事物的管理凡是,默認的是採用jdbc的方式去管理,另外可以可用JTA來管理,這種管理方式一般用於多數據庫操作的情況下比較多。
<hibernate-configuration>
<session-factory>
<!--設定事物管理的工廠類-->
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</protery>
</protery>
</session-factory>
</hibernate-configuration>
一系列的數據庫的操作組成一個單元,要麼全部執行,要麼全部取消(一榮俱榮,一損俱損)。這個單元我們可以成爲一個事物
事物的特性:
原子性,一致性(數據的一致性),隔離性(一個事物沒完成,避免另外一個事物的干擾),持久性(當中斷了,如斷電了,下一次啓動的時候能自動的全部回滾。。。。)。
數據併發訪問有可能引發的問題:
1、丟失更新。
2、髒讀。
3、不開重複讀:第一次與第一次讀出來的數據不一致。
4、幻讀:a事物讀取了某個表的記錄,發現40條記錄,後來又讀了一次,卻發現41條記錄了(b事物在期間增加了一條記錄,並且提交了事物)。
事物隔離級別:
1、Read Uncommitted
2、Read Commited 某個事物僅可以讀,不能修改和刪除另外一個事物提交了的數據。
3、Repeatable Read 某個事物已經讀取的數據,不允許其他事物寫入
4、Serializable 所有的事物只能像序列化的執行,一個一個來。
org.hibernate.Transaction
Commit()
Rollback()
鎖:
悲觀鎖:其使用具有完全的排他性,性能比較低。
方法一:
Query query = session.crateQuery("From guestbook gb")
query.setLockMode("gb", LockMode.UPGRADE);
方法二:
GuestBook gb = (GuestBook) session.get(GuestBook.class, new Integer(1));
session.lock(gb, LockMode.UPGRADE);
方法三:
GuestBook gb = (Guestbook)session.get(GuestBook.class, new Integer(1), LockMode,UPGRADE);
樂觀鎖:多個事物同時去更新一個數據的時候,另外一個更新動作會發生異常。
版本號方法實現:
在表中加一個version來記錄版本號,這個字段讓Hibernate去操作它,不是人爲去操作。
public class Guestbook implements java.io.Serializable {
//用來記錄版本號,不需要提供setter getter方法
private Integer version;
}
<class name="com.test.Guestbook" table="" optimistic-lock="version">
<id name="" type=""> </id>
<version name="version" column="version" access="field"></version>
</class>
access="field"表示這個字段有Hibernate去管理,不用提哦那個getter和setter方法。
時間戳實現樂觀鎖:表字段的類型是 TMESTAMP類型
public class Guestbook implements java.io.Serializable{
private java.sql.Timestamp updateTime;
}
<class name="" table="">
<id name="" type=""></id>
<timestamp name="updateTime" column="updateTime" access="field"></timestamp>
</class>
Hibernate過濾器
類似servlt過濾器,配置在映射文件中
錯誤記錄:
關於hibernate從 mysql 到 mssql的 轉換一直找不到錯誤的地方,昨天晚上發現,對於mssql下的map文件,
如
<class name="edu.lhq.pojo.Userinfo" table="userinfo" catalog="gjms">
必須再添加一個schema="dbo"的屬性
因爲在mssql中,表是使用gjms.dbo.userinfo來訪問的,所以schema屬性值可以根據在企業管理器中看到的來設置,初步判斷應該是權限值,正確的語句如下:
<class name="edu.lhq.pojo.Userinfo" table="userinfo" schema="dbo" catalog="gjms">
因爲在mysql中沒有這一說所以在mssql中需要補上。
Hibernate 添加到數據庫中亂碼:
在Hibernate .cfg.xml加上 connection.characterEncoding 的配置:
<property name="connection.characterEncoding">utf-8</property>
SSH框架中調用HibernateDaoSupport.getTemplate().save(obj)後,能保存到緩存中,單沒有提交到數據中:只需早Hibernate.cfg.xml中加入autocommit配置:
<property name="hibernate.connection.autocommit">true</property>