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语句,但数据没有结果影响。问题一般是事务忘记提交…….遇到问题,一定看错误提示!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。