您好,登錄后才能下訂單哦!
org.hibernate.cfg.Configuration是配置管理類對象。
加載主配置文件的方法(hibernate.cfg.xml),默認加載src/hibernate.cfg.xml。
config.configure(“cn/config/hibernate.cfg.xml”); 加載指定路徑下指定名稱的主配置文件
創建session的工廠對象
Configuration部分源碼:
/** * An instance of <tt>Configuration</tt> allows the application * to specify properties and mapping documents to be used when * creating a <tt>SessionFactory</tt>. Usually an application will create * a single <tt>Configuration</tt>, build a single instance of * <tt>SessionFactory</tt> and then instantiate <tt>Session</tt>s in * threads servicing client requests. The <tt>Configuration</tt> is meant * only as an initialization-time object. <tt>SessionFactory</tt>s are * immutable and do not retain any association back to the * <tt>Configuration</tt>.<br> * <br> * A new <tt>Configuration</tt> will use the properties specified in * <tt>hibernate.properties</tt> by default. * * @author Gavin King * @see org.hibernate.SessionFactory */ public class Configuration implements Serializable { /** * Use the mappings and properties specified in an application resource named <tt>hibernate.cfg.xml</tt>. * * @return this for method chaining * * @throws HibernateException Generally indicates we cannot find <tt>hibernate.cfg.xml</tt> * * @see #configure(String) */ public Configuration configure() throws HibernateException { configure( "/hibernate.cfg.xml" ); return this; } /** * Use the mappings and properties specified in the given application resource. The format of the resource is * defined in <tt>hibernate-configuration-3.0.dtd</tt>. * <p/> * The resource is found via {@link #getConfigurationInputStream} * * @param resource The resource to use * * @return this for method chaining * * @throws HibernateException Generally indicates we cannot find the named resource * * @see #doConfigure(java.io.InputStream, String) */ public Configuration configure(String resource) throws HibernateException { log.info( "configuring from resource: " + resource ); InputStream stream = getConfigurationInputStream( resource ); return doConfigure( stream, resource ); } /** * Create a {@link SessionFactory} using the properties and mappings in this configuration. The * {@link SessionFactory} will be immutable, so changes made to {@code this} {@link Configuration} after * building the {@link SessionFactory} will not affect it. * * @return The build {@link SessionFactory} * * @throws HibernateException usually indicates an invalid configuration or invalid mapping information */ public SessionFactory buildSessionFactory() throws HibernateException { log.debug( "Preparing to build session factory with filters : " + filterDefinitions ); secondPassCompile(); if ( ! metadataSourceQueue.isEmpty() ) { log.warn( "mapping metadata cache was not completely processed" ); } enableLegacyHibernateValidator(); enableBeanValidation(); enableHibernateSearch(); validate(); Environment.verifyProperties( properties ); Properties copy = new Properties(); copy.putAll( properties ); PropertiesHelper.resolvePlaceHolders( copy ); Settings settings = buildSettings( copy ); return new SessionFactoryImpl( this, mapping, settings, getInitializedEventListeners(), sessionFactoryObserver ); } }
org.hibernate.SessionFactory
session的工廠(或者說代表了這個hibernate.cfg.xml配置文件)
The main contract here is the creation of Session instances. Usually an application has a single SessionFactory instance and threads servicing client requests obtain Session instances from this factory.
SessionFactory是一個接口,它的主要職責就是創建Session實例。通常情況下,一個application只有一個單獨的SessionFactory實例,不同的線程從這個SessionFactory當中獲取Session的實例。
The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.
SessionFactory的內部狀態是不變以,也就是說,一旦SessionFactory被創建,它的內部就不會再發生變化。
創建一個sesison對象
創建session或取出session對象
SessionFactory部分源碼:
/** * The main contract here is the creation of {@link Session} instances. Usually * an application has a single {@link SessionFactory} instance and threads * servicing client requests obtain {@link Session} instances from this factory. * <p/> * The internal state of a {@link SessionFactory} is immutable. Once it is created * this internal state is set. This internal state includes all of the metadata * about Object/Relational Mapping. * <p/> * Implementors <strong>must</strong> be threadsafe. * * @see org.hibernate.cfg.Configuration * * @author Gavin King * @author Steve Ebersole */ public interface SessionFactory extends Referenceable, Serializable { /** * Open a {@link Session}. * <p/> * JDBC {@link Connection connection(s} will be obtained from the * configured {@link org.hibernate.connection.ConnectionProvider} as needed * to perform requested work. * * @return The created session. * * @throws HibernateException Indicates a peroblem opening the session; pretty rare here. */ public org.hibernate.classic.Session openSession() throws HibernateException; /** * Obtains the current session. The definition of what exactly "current" * means controlled by the {@link org.hibernate.context.CurrentSessionContext} impl configured * for use. * <p/> * Note that for backwards compatibility, if a {@link org.hibernate.context.CurrentSessionContext} * is not configured but a JTA {@link org.hibernate.transaction.TransactionManagerLookup} * is configured this will default to the {@link org.hibernate.context.JTASessionContext} * impl. * * @return The current session. * * @throws HibernateException Indicates an issue locating a suitable current session. */ public org.hibernate.classic.Session getCurrentSession() throws HibernateException; }
注意:openSession()和getCurrentSession()的返回值是 org.hibernate.classic.Session類型。
org.hibernate.classic.Session定義如下:
org.hibernate.classic.Session定義如下: /** * An extension of the <tt>Session</tt> API, including all * deprecated methods from Hibernate2. This interface is * provided to allow easier migration of existing applications. * New code should use <tt>org.hibernate.Session</tt>. * @author Gavin King */ public interface Session extends org.hibernate.Session { }
org.hibernate.Session定義如下:
/** * The main runtime interface between a Java application and Hibernate. This is the * central API class abstracting the notion of a persistence service.<br> * <br> * The lifecycle of a <tt>Session</tt> is bounded by the beginning and end of a logical * transaction. (Long transactions might span several database transactions.)<br> * <br> * The main function of the <tt>Session</tt> is to offer create, read and delete operations * for instances of mapped entity classes. Instances may exist in one of three states:<br> * <br> * <i>transient:</i> never persistent, not associated with any <tt>Session</tt><br> * <i>persistent:</i> associated with a unique <tt>Session</tt><br> * <i>detached:</i> previously persistent, not associated with any <tt>Session</tt><br> * <br> * Transient instances may be made persistent by calling <tt>save()</tt>, * <tt>persist()</tt> or <tt>saveOrUpdate()</tt>. Persistent instances may be made transient * by calling<tt> delete()</tt>. Any instance returned by a <tt>get()</tt> or * <tt>load()</tt> method is persistent. Detached instances may be made persistent * by calling <tt>update()</tt>, <tt>saveOrUpdate()</tt>, <tt>lock()</tt> or <tt>replicate()</tt>. * The state of a transient or detached instance may also be made persistent as a new * persistent instance by calling <tt>merge()</tt>.<br> * <br> * <tt>save()</tt> and <tt>persist()</tt> result in an SQL <tt>INSERT</tt>, <tt>delete()</tt> * in an SQL <tt>DELETE</tt> and <tt>update()</tt> or <tt>merge()</tt> in an SQL <tt>UPDATE</tt>. * Changes to <i>persistent</i> instances are detected at flush time and also result in an SQL * <tt>UPDATE</tt>. <tt>saveOrUpdate()</tt> and <tt>replicate()</tt> result in either an * <tt>INSERT</tt> or an <tt>UPDATE</tt>.<br> * <br> * It is not intended that implementors be threadsafe. Instead each thread/transaction * should obtain its own instance from a <tt>SessionFactory</tt>.<br> * <br> * A <tt>Session</tt> instance is serializable if its persistent classes are serializable.<br> * <br> * A typical transaction should use the following idiom: * <pre> * Session sess = factory.openSession(); * Transaction tx; * try { * tx = sess.beginTransaction(); * //do some work * ... * tx.commit(); * } * catch (Exception e) { * if (tx!=null) tx.rollback(); * throw e; * } * finally { * sess.close(); * } * </pre> * <br> * If the <tt>Session</tt> throws an exception, the transaction must be rolled back * and the session discarded. The internal state of the <tt>Session</tt> might not * be consistent with the database after the exception occurs. * * @see SessionFactory * @author Gavin King */ public interface Session extends Serializable { /** * Persist the given transient instance, first assigning a generated identifier. (Or * using the current value of the identifier property if the <tt>assigned</tt> * generator is used.) This operation cascades to associated instances if the * association is mapped with <tt>cascade="save-update"</tt>. * * @param object a transient instance of a persistent class * @return the generated identifier * @throws HibernateException */ public Serializable save(Object object) throws HibernateException; /** * Update the persistent instance with the identifier of the given detached * instance. If there is a persistent instance with the same identifier, * an exception is thrown. This operation cascades to associated instances * if the association is mapped with <tt>cascade="save-update"</tt>. * * @param object a detached instance containing updated state * @throws HibernateException */ public void update(Object object) throws HibernateException; /** * Either {@link #save(Object)} or {@link #update(Object)} the given * instance, depending upon resolution of the unsaved-value checks (see the * manual for discussion of unsaved-value checking). * <p/> * This operation cascades to associated instances if the association is mapped * with <tt>cascade="save-update"</tt>. * * @see Session#save(java.lang.Object) * @see Session#update(Object object) * @param object a transient or detached instance containing new or updated state * @throws HibernateException */ public void saveOrUpdate(Object object) throws HibernateException; /** * Return the persistent instance of the given entity class with the given identifier, * or null if there is no such persistent instance. (If the instance is already associated * with the session, return that instance. This method never returns an uninitialized instance.) * * @param clazz a persistent class * @param id an identifier * @return a persistent instance or null * @throws HibernateException */ public Object get(Class clazz, Serializable id) throws HibernateException; /** * Return the persistent instance of the given entity class with the given identifier, * assuming that the instance exists. This method might return a proxied instance that * is initialized on-demand, when a non-identifier method is accessed. * <br><br> * You should not use this method to determine if an instance exists (use <tt>get()</tt> * instead). Use this only to retrieve an instance that you assume exists, where non-existence * would be an actual error. * * @param theClass a persistent class * @param id a valid identifier of an existing persistent instance of the class * @return the persistent instance or proxy * @throws HibernateException */ public Object load(Class theClass, Serializable id) throws HibernateException; }
org.hibernate.Session
session對象維護了一個連接(Connection), 代表了與數據庫連接的會話。
Hibernate最重要的對象: 只用使用hibernate與數據庫操作,都用到這個對象
beginTransaction()開啟一個事務; hibernate要求所有的與數據庫的操作必須有事務的環境,否則報錯!
save(Object object) 保存一個對象
update(Object object) 更新一個對象
saveOrUpdate(Object object) 保存或者更新的方法:沒有設置主鍵,執行保存;有設置主鍵,執行更新操作; 如果設置主鍵不存在報錯!
示例代碼:
package com.rk.hibernate.a_hello; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; public class App2 { private static SessionFactory sessionFactory; static { /* * //1. 創建配置管理類對象 Configuration config = new Configuration(); // 加載配置文件 * (默認加載src/hibernate.cfg.xml) config.configure(); //2. * 根據加載的配置管理類對象,創建SessionFactory對象 sessionFactory = * config.buildSessionFactory(); */ // 創建SessionFactory對象 sessionFactory = new Configuration().configure().buildSessionFactory(); } // 1. 保存對象 @Test public void testSave() { // 對象 Employee emp = new Employee(); emp.setEmpName("張三"); emp.setWorkDate(new Date()); // 根據session的工廠,創建session對象 Session session = sessionFactory.openSession(); // 開啟事務 Transaction transaction = session.beginTransaction(); // -----執行操作----- session.save(emp); // 提交事務 transaction.commit(); // 關閉 session.close(); System.out.println("執行結束!"); } // 2. 更新對象 @Test public void testUpdate() { // 對象 Employee emp = new Employee(); emp.setEmpId(20); emp.setEmpName("小明"); // 創建session Session session = sessionFactory.openSession(); // 開啟事務 Transaction tx = session.beginTransaction(); // 更新。如果不提供id,則報錯;如果提供的id不存在,也報錯 session.update(emp); // 提交事務 tx.commit(); // 關閉 session.close(); System.out.println("執行結束!"); } // 3. 保存或更新對象 @Test public void testSaveOrUpdate() { // 對象 Employee emp = new Employee(); emp.setEmpId(3); emp.setEmpName("小紅"); // 創建session Session session = sessionFactory.openSession(); // 開啟事務 Transaction tx = session.beginTransaction(); // -------執行操作------- // 沒有設置主鍵,執行保存。 //有設置主鍵,執行更新操作; 如果設置主鍵不存在,則報錯! session.saveOrUpdate(emp); // 提交事務 tx.commit(); // 關閉 session.close(); System.out.println("執行結束!"); } }
get(Class clazz, Serializable id) 主鍵查詢
load(Class theClass, Serializable id) 主鍵查詢 (支持懶加載)
示例代碼:
@Test public void testQuery() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // get主鍵查詢 Employee emp1 = (Employee) session.get(Employee.class, 2); System.out.println(emp1); // load主鍵查詢 Employee emp2 = (Employee) session.load(Employee.class, 3); System.out.println(emp2); tx.commit(); session.close(); System.out.println("執行結束!"); }
HQL查詢與SQL查詢區別:
SQL: (結構化查詢語句)查詢的是表(table)以及字段(column); 不區分大小寫。
HQL: hibernate query language 即hibernate提供的面向對象的查詢語言,查詢的是對象以及對象的屬性(property),區分大小寫。
示例代碼:
// HQL查詢 【適合有數據庫基礎的】 @Test public void testHQL() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // HQL查詢 Query q = session.createQuery("From Employee where empId=2 or empId=3"); List<Employee> list = q.list(); System.out.println(list); tx.commit(); session.close(); System.out.println("執行結束!"); }
完全面向對象的查詢
示例代碼:
//QBC查詢 , query by criteria 完全面向對象的查詢 @Test public void testQBC() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(Employee.class); // 條件 criteria.add(Restrictions.eq("empId", 2)); List<Employee> list = criteria.list(); System.out.println(list); tx.commit(); session.close(); System.out.println("執行結束!"); }
復雜的查詢,就要使用原生態的sql查詢也可以,就是本地sql查詢的支持!缺點: 不能跨數據庫平臺!
示例代碼:
//SQL @Test public void testSQL() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // 把每一行記錄封裝為對象數組,再添加到list集合 //SQLQuery sqlQuery = session.createSQLQuery("select * from employee"); // 把每一行記錄封裝為 指定的對象類型 SQLQuery sqlQuery = session.createSQLQuery("select * from employee").addEntity(Employee.class); List<Employee> list = sqlQuery.list(); System.out.println(list); tx.commit(); session.close(); System.out.println("執行結束!"); }
完整示例代碼:
package com.rk.hibernate.a_hello; import java.util.LinkedList; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import org.hibernate.criterion.Restrictions; import org.junit.Test; public class App3 { private static SessionFactory sessionFactory; static { // 創建SessionFactory對象 sessionFactory = new Configuration().configure().buildSessionFactory(); } @Test public void testQuery() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // get主鍵查詢 Employee emp1 = (Employee) session.get(Employee.class, 2); System.out.println(emp1); // load主鍵查詢 Employee emp2 = (Employee) session.load(Employee.class, 3); System.out.println(emp2); tx.commit(); session.close(); System.out.println("執行結束!"); } // HQL查詢 【適合有數據庫基礎的】 @Test public void testHQL() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // HQL查詢 Query q = session.createQuery("From Employee where empId=2 or empId=3"); List<Employee> list = q.list(); System.out.println(list); tx.commit(); session.close(); System.out.println("執行結束!"); } //QBC查詢 , query by criteria 完全面向對象的查詢 @Test public void testQBC() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Criteria criteria = session.createCriteria(Employee.class); // 條件 criteria.add(Restrictions.eq("empId", 2)); List<Employee> list = criteria.list(); System.out.println(list); tx.commit(); session.close(); System.out.println("執行結束!"); } //SQL @Test public void testSQL() { Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // 把每一行記錄封裝為對象數組,再添加到list集合 //SQLQuery sqlQuery = session.createSQLQuery("select * from employee"); // 把每一行記錄封裝為 指定的對象類型 SQLQuery sqlQuery = session.createSQLQuery("select * from employee").addEntity(Employee.class); List<Employee> list = sqlQuery.list(); System.out.println(list); tx.commit(); session.close(); System.out.println("執行結束!"); } }
org.hibernate.Transaction是hibernate事務對象
A transaction is associated with a Session and is usually instantiated by a call to Session.beginTransaction().
transaction與Session相關聯,通常由Session.beginTransaction()方法創建。
A single session might span multiple transactions since the notion of a session (a conversation between the application and the datastore) is of coarser granularity than the notion of a transaction. However, it is intended that there be at most one uncommitted Transaction associated with a particular Session at any time.
session可以理解為application和datastore之間一次conversation。在一個session產生多個transactions,但是在同一時間內,只只能有一個未提交的transaction。
package org.hibernate; import javax.transaction.Synchronization; /** * Allows the application to define units of work, while * maintaining abstraction from the underlying transaction * implementation (eg. JTA, JDBC).<br> * <br> * A transaction is associated with a <tt>Session</tt> and is * usually instantiated by a call to <tt>Session.beginTransaction()</tt>. * A single session might span multiple transactions since * the notion of a session (a conversation between the application * and the datastore) is of coarser granularity than the notion of * a transaction. However, it is intended that there be at most one * uncommitted <tt>Transaction</tt> associated with a particular * <tt>Session</tt> at any time.<br> * <br> * Implementors are not intended to be threadsafe. * * @see Session#beginTransaction() * @see org.hibernate.transaction.TransactionFactory * @author Anton van Straaten */ public interface Transaction { /** * Begin a new transaction. */ public void begin() throws HibernateException; /** * Flush the associated <tt>Session</tt> and end the unit of work (unless * we are in {@link FlushMode#MANUAL}. * </p> * This method will commit the underlying transaction if and only * if the underlying transaction was initiated by this object. * * @throws HibernateException */ public void commit() throws HibernateException; /** * Force the underlying transaction to roll back. * * @throws HibernateException */ public void rollback() throws HibernateException; /** * Was this transaction rolled back or set to rollback only? * <p/> * This only accounts for actions initiated from this local transaction. * If, for example, the underlying transaction is forced to rollback via * some other means, this method still reports false because the rollback * was not initiated from here. * * @return boolean True if the transaction was rolled back via this * local transaction; false otherwise. * @throws HibernateException */ public boolean wasRolledBack() throws HibernateException; /** * Check if this transaction was successfully committed. * <p/> * This method could return <tt>false</tt> even after successful invocation * of {@link #commit}. As an example, JTA based strategies no-op on * {@link #commit} calls if they did not start the transaction; in that case, * they also report {@link #wasCommitted} as false. * * @return boolean True if the transaction was (unequivocally) committed * via this local transaction; false otherwise. * @throws HibernateException */ public boolean wasCommitted() throws HibernateException; /** * Is this transaction still active? * <p/> * Again, this only returns information in relation to the * local transaction, not the actual underlying transaction. * * @return boolean Treu if this local transaction is still active. */ public boolean isActive() throws HibernateException; /** * Register a user synchronization callback for this transaction. * * @param synchronization The Synchronization callback to register. * @throws HibernateException */ public void registerSynchronization(Synchronization synchronization) throws HibernateException; /** * Set the transaction timeout for any transaction started by * a subsequent call to <tt>begin()</tt> on this instance. * * @param seconds The number of seconds before a timeout. */ public void setTimeout(int seconds); }
(1)ClassNotFoundException…., 缺少jar文件!
(2)如果程序執行程序,hibernate也有生成sql語句,但數據沒有結果影響。問題一般是事務忘記提交…….遇到問題,一定看錯誤提示!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。