hibernate筆記

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>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章