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>

你可能感兴趣的:(Hibernate,mysql,session,table,Integer,Class)