一、Configuration
概述:Configuration类负责管理Hibernate的配置信息。它包括如下内容:
Hibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数据库Dialect,数据库连接池等。
Hibernate映射文件(*.hbm.xml)。
Hibernate配置的两种方法:
属性文件(hibernate.properties)。
调用代码:Configurationcfg= new Configuration();
Xml文件(hibernate.cfg.xml)。
调用代码:Configurationcfg= new Configuration().configure();
二、SessionFactory
应用程序从SessionFactory(会话工厂)里获得Session(会话)实例。它在多个应用线程间进行共享。通常情况下,整个应用只有唯一的一个会话工厂——例如在应用初始化时被创建。然而,如果你使用Hibernate访问多个数据库,你需要对每一个数据库使用一个会话工厂。会话工厂缓存了生成的SQL语句和Hibernate在运行时使用的映射元数据。
调用代码:
SessionFactorysessionFactory =cfg.buildSessionFactory();
说明:SessionFactory由Configuration对象创建,所以每个Hibernate配置文件,实际上是对SessionFactory的配置
三、Session(会话)
Session不是线程安全的,它代表与数据库之间的一次操作,它的概念介于Connection和Transaction之间。Session也称为持久化管理器,因为它是与持久化有关的操作接口。Session通过SessionFactory打开,在所有的工作完成后,需要关闭。它与Web层的HttpSession没有任何关系。
调用代码
Session session =sessionFactory.openSession();
四、Transaction(事务)
它将应用代码从底层的事务实现中抽象出来——这可能是一个JDBC事务,一个JTA用户事务或者甚至是一个公共对象请求代理结构(CORBA)——允许应用通过一组一致的API控制事务边界。这有助于保持Hibernate应用在不同类型的执行环境或容器中的可移植性。
调用代码:
Transaction tx =session.beginTransaction();
注:使用Hibernate进行操作时必须显式的调用Transaction(默认:autoCommit=false)。
五、Lifecycle接口(有侵入性,不建议使用)
可以在实体对象定义时实作Lifecycle接口,这个接口定义如下:
package org.hibernate.classic; import java.io.Serializable; import org.hibernate.CallbackException; import org.hibernate.Session; public interface Lifecycle { public static final boolean VETO = true; public static final boolean NO_VETO = false; public boolean onSave(Session s) throws CallbackException; public boolean onUpdate(Session s) throws CallbackException; public boolean onDelete(Session s) throws CallbackException; public void onLoad(Session s, Serializable id); }
当对象实作Lifecycle接口时,会在save()、update()、delete()、load()等方法执行之前呼叫对应的onSave()、onUpdate()、onDelete()与onLoad(),其中onSave()、onUpdate()、onDelete()与onLoad() 若传回true或丢出CallbackException,则对应的操作中止。
六、Validatable接口(有侵入性,不建议使用)
可以在实体对象定义时实作Validatable接口,其定义如下:
package org.hibernate.classic; public interface Validatable { public void validate() throws ValidationFailure; }
如果定义时实作了Validatable接口,当对象被持久化之前会呼叫validate()方法,如果丢出ValidationFailure,则验证失败,对象的数据不会储存至数据库中。
七、Query接口
除了直接使用find()方法并配合HQL来进行查询之外,我们还可以透过 org.hibernate.Query接口的实例来进行查询,
7.1、位置参数查询
透过Query接口,您可以先设定查询参数,之后透过setXXX()等方法,将指定的参数值填入,而不用每次都撰写完整的HQL
Query query = session.createQuery("select user.name from User as user where user.age = ? and user.sex = ?"); query.setInteger(0, 25); query.setCharacter(1, 'M'); List names = query.list(); for (ListIterator iterator = names.listIterator(); iterator.hasNext(); ) { String name = (String) iterator.next(); System.out.println("name: " + name); }
7.2、命名参数
您可以使用命名参数(Named Parameter)来取代这个方法,这可以不用依照特定的顺序来设定参数值,
Query query = session.createQuery("select user.name from User as user where user.age = :age and user.sex = :sex"); query.setInteger("age", 25); query.setCharacter("sex", 'M'); List names = query.list(); for (ListIterator iterator = names.listIterator(); iterator.hasNext(); ) { String name = (String) iterator.next(); System.out.println("name: " + name); }
设定命名参数时,在建立Query时先使用:后跟着参数名,之后我们就可以在setXXX()方法中直接指定参数名来设定参数值,而不用依照特定的顺序。
7.3、 session.getNamedQuery
我们也可以将HQL撰写在程序之外,以避免硬编码(hard code)在程序之中,在需要修改HQL时就很方便,在*.hbm.xml中使用<query/>标签,并在<![CDATA[与]] >之间撰写HQL,撰写的位置是在</hibernate-mapping>之前,例如:
User.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="onlyfun.caterpillar.User" table="USER"> <id name="id" type="string"> <column name="user_id" sql-type="char(32)" /> <generator class="uuid.hex"/> </id> <property name="name" type="string" not-null="true"> <column name="name" length="16" not-null="true"/> </property> <property name="sex" type="char"/> <property name="age" type="int"/> </class> <query name="org.wsz.queryUser"> <![CDATA[ select user.name from User as user where user.age = :age and user.sex = :sex ]]> </query> </hibernate-mapping>
<query>的name属性用来设定查询外部HQL时的名称依据,使用的例子如下:
Query query = session.getNamedQuery("org.wsz.queryUser"); query.setInteger("age", 25); query.setCharacter("sex", 'M'); List names = query.list(); for (ListIterator iterator = names.listIterator(); iterator.hasNext(); ) { String name = (String) iterator.next(); System.out.println("name: " + name); }
7.4、分页查询
package com.wsz.test; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.hibernate.Query; import org.hibernate.Session; import com.wsz.entity.HibernateUtils; import com.wsz.entity.User; public class TestQuery extends TestCase { public void testQuery() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); // 使用HQL查询 Query query = session.createQuery("from User"); // 分页 query.setFirstResult(0); query.setMaxResults(2); // query.list()返回的就是查询结果的对象list List userList = query.list(); for (Iterator iter = userList.iterator(); iter.hasNext();) { User user = (User) iter.next(); System.out.println(user.getId()); System.out.println(user.getName()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } }
7.5、如果查询返回多个值用list()方法
public void testQuery(){ Configuration config = new Configuration().configure(); SessionFactory factory = config.buildSessionFactory(); //创建SessionFactory Session session = factory.openSession(); //创建Session session.beginTransaction(); //开始事务 Query query = session.createQuery("from Student"); List list = query.list(); // 用list方法返回多个值 //List list = session.createQuery("from Student").list(); for(int i=0;i<list.size();i++){ Student student = (Student)list.get(i); System.out.print(student.getId()+" "); System.out.print(student.getName()+" "); System.out.print(student.getSex()+" "); System.out.print(student.getBirthday()); System.out.println(); } session.getTransaction().commit(); //提交事务 session.close(); //关闭Session }
7.6、当确定返回的实例只有一个或者null时 用uniqueResult()方法
public void testGet(){ Configuration config = new Configuration().configure(); SessionFactory factory = config.buildSessionFactory(); Session session = factory.openSession(); session.beginTransaction(); Query query = session.createQuery("from Student s where s.id=?"); query.setString(0, "2"); Student student = (Student)query.uniqueResult(); //当确定返回的实例只有一个或者null时 用uniqueResult()方法 //Student student = (Student)session.createQuery("from Student s where s.id=?").setString(0,"5").uniqueResult(); System.out.println(student.getName()); System.out.println(student.getBirthday()); session.getTransaction().commit(); session.close(); }