??xml version="1.0" encoding="utf-8" standalone="yes"?> 当出?/span>net.sf.hibernate.MappingException: Error reading resource:…异常时一般是因ؓ(f)映射文g出现错误?/span> 当出?/span>net.sf.hibernate.MappingException: Resource: … not found是因?/span>XML配置文g没找到所_(d)有可能是攄目录不正,或者没其加入hibernate.cfg.xml中?/span> 当出?/span>net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property name in class …Ӟ原因一般是因ؓ(f)XML映射文g中的属性与对应?/span>JavacM的属性的getter?/span>setterҎ(gu)不一致?/span> 当出?/span>org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():异常Ӟ一般是因ؓ(f)<id>元素配置不正,<id>元素~少其子元素<generator></generator>的配|引赗?/span> 解决Ҏ(gu)Q?/span><id>元素映射?jin)相应数据库表的主键字段Q对其子元素<generator class="">,其中class的取值可以ؓ(f)increment?/span>identity?/span>sequence?/span>hilo?/span>native……{,更多的可参?/span>hibernate参考文档,一般取其gؓ(f)native 。具体可参?/span>2.2.2.1节?/span> 当出?/span>a different object with the same identifier value was already associated with the sessionӞ一般是因ؓ(f)?/span>hibernate中同一?/span>session里面有了(jin)两个相同标识但是是不同实体?/span> 有如下几U解x案:(x) Q?/span>1Q?/span>session.clean()Q如果在clean操作后面又进行了(jin)saveOrUpdate(object){改变数据状态的操作Q有可能?x)报?/span>"Found two representations of same collection"异常?/span> Q?/span>2Q?/span>session.refresh(object)Q当object不是数据库中已有数据的对象的时候,不能使用session.refresh(object)因ؓ(f)该方法是?/span>hibernate?/span>session中去重新?/span>objectQ如?/span>session中没有这个对象,则会(x)报错所以当你?/span>saveOrUpdate(object)之前q需要判断一下?/span> Q?/span>3Q?/span>session.merge(object)Q?/span>Hibernate里面自带的方法,推荐使用?/span> 当出?/span>SQL Grammer Exception,Could not execute JDBC batch update异常Ӟ一般是由如下问题引P(x) Q?/span>1Q?/span>SQL语句中存在语法错误或是传入的数据有误; Q?/span>2Q数据库的配|不合法Q或者说是配|有误。较Ҏ(gu)出现的有数据表的映射文g(,hbm.xml文g)配置有误Q?/span>Hibernate.cfg.xml文g配置有误; Q?/span>3Q?/span> 当前的数据库用户权限不Q不能操作数据库。以是以Oracle 数据库ؓ(f)例,q种情况下在错误提示中会(x)昄java.sql.BatchUpdateException: ORA-01031: insufficient privilegesq样的信息?/span> 针对上面的各U原因,开发h员可以找出对应的解决Ҏ(gu)?/span>
]]>
试时候用的两个cd别如下:(x)
丄例子是部门和员工的关pR一个部门可以有多个员工。然后把部门删掉的时候,员工的部门属性就为null?jin),不过Q按照严谨来_(d)q是JPA的严谨一些。这样可以防止误操作Q呵c(din)?br />
部门的实体对?br />
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.hadeslee.jpaentity;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
*
* @author hadeslee
*/
@Entity
@Table(name = "JPADepartment")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy = "department")
private Set<Person> persons = new HashSet<Person>();
private String deptName;
private String description;
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Person> getPersons() {
return persons;
}
public void setPersons(Set<Person> persons) {
this.persons = persons;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Department)) {
return false;
}
Department other = (Department) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.hadeslee.jpaentity.Department[id=" + id + "]";
}
}
人员的实体对?br />
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.hadeslee.jpaentity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
*
* @author hadeslee
*/
@Entity
@Table(name = "JPAPerson")
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
private int age;
@ManyToOne
private Department department;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Person)) {
return false;
}
Person other = (Person) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.hadeslee.jpaentity.Person[id=" + id + "]";
}
}
׃JPA是不需要配|的Q代码里面已l包括了(jin)注释Q所以下面附上Hibernate的映文ӞZ(jin)使数据库里面更清楚一些,所以两者用的表不是同一张表QJPA的表是带JPA前缀的,用@Tableq个注释声明?jin)这一炏V?br />
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hadeslee.jpaentity">
<class name="Department" table="Department">
<id name="id" column="departId" type="long">
<generator class="native"/>
</id>
<property name="deptName"/>
<property name="description"/>
<set name="persons">
<key column="deptId"/>
<one-to-many class="Person"/>
</set>
</class>
<class name="Person" table="Person">
<id name="id" column="personId" type="long">
<generator class="native"/>
</id>
<property name="name"/>
<property name="age"/>
<many-to-one name="department" column="deptId" class="Department"/>
</class>
</hibernate-mapping>
调用JPA的代码如下:(x)
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
com.hadeslee.jpaentity.Person p = new com.hadeslee.jpaentity.Person();
p.setAge(26);
p.setName("千里冰封");
com.hadeslee.jpaentity.Department dept = em.find(com.hadeslee.jpaentity.Department.class, Long.valueOf("3"));
System.out.println("扑ֈ的dept=" + dept);
em.remove(dept);
em.getTransaction().commit();
调用hibernate的代码如下:(x)
session.getTransaction().begin();
Department dept = (Department) session.load(Department.class, 2);
session.delete(dept);
session.getTransaction().commit();
最后发现是JPA是不能删除的Q而hibernateq边的调用可以删除,一开始我q以为是toplink的实现问题,后来Ҏ(gu)把实现改成hibernate的实玎ͼ也同栗所以有可能是JPA的要求必dq样做,不能替我们自动完成一些东西,是利于安全。这可能是标准和流行的差别吧。呵c(din)?/div>
]]>1. net.sf.hibernate.MappingException
2. net.sf.hibernate.PropertyNotFoundException
3. org.hibernate.id.IdentifierGenerationException
4. a different object with the same identifier value was already associated with the session
5. SQL Grammer Exception,Could not execute JDBC batch update
]]>
?/span>Hibernate中用查询时Q一般?/span>Hql查询语句?/span>
HQLQ?/span>Hibernate Query LanguageQ,?/span>Hibernate的查询语a?/span>SQL非常相像。不q?/span>HQL?/span>SQL的最Ҏ(gu)的区别,是它是面向对象的?/span>
使用HQL旉要注意以下几点:(x)
l 大小写敏?/span>
因ؓ(f)HQL是面向对象的Q而对象类的名U和属性都是大写敏感的,所?/span>HQL是大写敏感的?/span>
Eg.
HQL语句Q?/span>from Cat as cat where cat.id > 1;?/span>from Cat as cat where cat.ID > 1;是不一L(fng)Q这点与SQL不同?/span>
l from子句
Eg. from CatQ该句返?/span>Cat对象实例Q开发h员也可以l其加上别名Q?/span>eg. from Cat as catQ对于多表查询的情况Q可参考如下:(x)
from Cat as cat, Dog as dog
其它斚w都与SQLcMQ在此不再赘q?/span>
接下来讲一个在Hibernate中查询的例子?/span>
List list = session.createQuery("from User as user order by user.loginName").list();
List list = session.find("from User as user where user.loginName=?",
loginName,
Hibernate.STRING);
Eg1. 此例采用“?”占位W的方式
String hql = "from User as user where user.loginName=? and user.orgId=? ";
Query query = session.createQuery(hql);
query.setParameter(1, 'amigo');
query.setParameter(2, new Long(1)) ;
List list = query .list();
Eg2. 此例采用“:paramName”的方?/span>
String hql = "from User as user where user.loginName=:loginName and user.orgId=:orgId ";
Query query = session.createQuery(hql);
query.setParameter('loginName', 'amigo');
query.setParameter('orgId', new Long(1)) ;
List list = query .list();
int count = (Integer) session.createQuery("select count(*) from User").uniqueResult().intValue();
q种一般是在记录需要分늚时候需要用刎ͼ例如Q在如下的代码中Q限制查询的开始记录的位置?/span>50Q最大查询条Cؓ(f)50?/span>
String hql = "from User as user order by user.loginName";
int firstResult= 50;
int maxResults = 50;
Query query = session.createQuery(hql);
query = query.setFirstResult(firstResult);
query.setMaxResults(maxResults);
在某些情况下Q也需要用到子查询Q例如在下面的例子中Q?/span>User为用户对象,UserRole为用户与角色兌对象。如?/span>HQL语句没有分配角色的用户对象查找出来?/span>
String hql = "from User user where user.loginName"
+ " not in(select ur.user.loginName from UserRole ur) ";
List list = (session.createQuery(hql)).list();
对于某些复杂的查询语句,需要调用某U特定的数据库的特定函数才能解决Q?/span>Hibernate虽然不推荐用原?/span>SQL语句来查询,因ؓ(f)q将破坏数据库的易移植性,但是Hibernate中也提供?jin)用原?/span>SQLq行查询的方法,只需要获得连接即可?/span>
Eg. 在下面的例子中,用到?/span>Sql Server数据库中的原?/span>sql语句Q如下所C:(x)
String timeUnit = "13";
String sql = "select count(*) count, CONVERT(VARCHAR(" + timeUnit +"), log.gen_datetime,121) timeUnit " + "from Log log";
SQLQuery query = session.createSQLQuery(sql)
.addScalar("count", Hibernate.INTEGER)
.addScalar("timeUnit", Hibernate.STRING);
List list = query.list();
在数据库中新增记录在Hibernate中不需要?/span>insert命o(h)Q只需要构造新增的对象后,调用Session对象?/span>save(…)Ҏ(gu)卛_?/span>
新增单个对象的实例如下,该实例将在用戯中新增一条记录?/span>
Session session = HibernateSessionFactory.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
User user = new User();
user.setLoginName("amigo");
user.setFullName("阿蜜?/span>");
……
session.save(user) ;
ts.commit();
} catch (Exception e) {
if (ts != null) {
ts.rollback();
}
} finally {
HibernateSessionFactory.closeSession();
}
对于扚w新增对象的情况,需要在新增一部分对象?/span>flush?/span>clear一ơ,例如Q没扚w新增20个对象时手动?/span>flush一ơ,假设?/span>listZ个用户列表,里面包含很多User对象Q那么要实现这些对象的扚w新增Q可采用如下Ҏ(gu)Q?/span>
Session session = HibernateSessionFactory.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
for (int i = 0; i < list.size(); i++) {
User user = (User) list.get(i);
session.save(user) ;
if (i % 20 == 0) {
session.flush();
session.clear();
}
}
ts.commit();
} catch (Exception e) {
if (ts != null) {
ts.rollback();
}
} finally {
HibernateSessionFactory.closeSession();
}
?/span>hibernate中,更新对象前不需要用查询语句:(x)update…Q一般需要在取得需要更新的持久化对象后Q执?/span>Session对象?/span>update(…)Ҏ(gu)。例如:(x)
Session session = HibernateSessionFactory.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
//取得持久化对?/span>
User user = session.get(User.class, "amigo");
//寚w要修改的属性进行修?/span>
user.setFullName("阿蜜?/span>");
……
session.update(user) ;
ts.commit();
} catch (Exception e) {
if (ts != null) {
ts.rollback();
}
} finally {
HibernateSessionFactory.closeSession();
}
一般在取得某对象后Q开发h员可以调?/span>Session对象?/span>delete(…)Ҏ(gu)删除该对象?/span>
Eg. 下面的实例中取得loginNameQ主键)(j)?#8220;amigo”?/span>User对象后,它删除?/span>
Session session = HibernateSessionFactory.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
//取得持久化对?/span>
User user = session.get(User.class, "amigo");
session.delete(user) ;
ts.commit();
} catch (Exception e) {
if (ts != null) {
ts.rollback();
}
} finally {
HibernateSessionFactory.closeSession();
}
对于扚w删除对象的情况,开发h员可以在取得待删除的对象列表后,一个一个的对象删除,对于每个对象的删除方法,?/span>3.4.1节。开发h员还可以hql语句来做扚w删除?/span>
Eg. 该实例通过delete语句来删除记录,除了(jin)loginName?#8220;amigo”的对象ؓ(f)Q其余都删除Q代码如下所C:(x)
Session session = HibernateSessionFactory.getSession();
Transaction ts = null;
try {
ts = session.beginTransaction();
String hql = "delete User as user where user.loginName != 'amigo'";
Query query = session.createQuery(hql);
int count = query.executeUpdate();
ts.commit();
System.out.println("delete count : " + count); //删除条数
} catch (Exception e) {
if (ts != null) {
ts.rollback();
}
} finally {
HibernateSessionFactory.closeSession();
}
?/span>Hibernate.cfg.xml中既可以配置JDBCQ也可以配置JNDI。在本小节中讲述数据源如何配|?/span>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 各属性的配置-->
<!?/span>?/span>true表示?/span>Hibernate发送给数据库的sql昄出来 -->
<property name="show_sql">true</property>
<!-- SQL方言Q这边设定的?/span>MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!-- 一ơ读的数据库记录?/span> -->
<property name="jdbc.fetch_size">50</property>
<!-- 讑֮Ҏ(gu)据库q行扚w删除 -->
<property name="jdbc.batch_size">30</property>
<!?/span>下面?/span>JNDI的配|?/span> -->
<!-- 数据源的名称 -->
<property name="connection.datasource">java:comp/env/jdbc/datasourcename</property>
<!-- Hibernate的连接加载类 -->
<property name="connection.provider_class">net.sf.hibernate.connection.DatasourceConnectionProvider</property>
<property name="dialect">net.sf.hibernate.dialect.SQLServerDialect</property>
<!?/span>映射文g -->
<mapping resource="com/amigo/pojo/User.hbm.xml"/>
<mapping resource="com/amigo/pojo/Org.hbm.xml"/>
</session-factory>
</hibernate-configuration>
c3p0q接池是Hibernate推荐使用的连接池Q若需要用该q接池时Q需要将c3p0?/span>jar包加入到classpath中?/span>c3p0q接池的配置CZ如下Q?/span>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 昄实际操作数据库时?/span>SQL -->
<property name="show_sql">true</property>
<!-- SQL方言Q这边设定的?/span>MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!--驱动E序Q在后箋的章节中讲q?/span>mysql?/span>sqlserver?/span>Oracle数据库的配置 -->
<property name="connection.driver_class">……</property>
<!-- JDBC URL -->
<property name="connection.url">……</property>
<!-- 数据库用户名 -->
<property name="connection.username">user</property>
<!-- 数据库密?/span> -->
<property name="connection.password">pass</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.max_size">20</property>
<property name="c3p0.timeout">1800</property>
<property name="c3p0.max_statements">50</property>
<!-- 对象与数据库表格映像文g -->
<mapping resource="com/amigo/pojo/User.hbm.xml"/>
<mapping resource="com/amigo/pojo/Org.hbm.xml"/>
</session-factory>
</hibernate-configuration>
在上q配|中Q?/span>HibernateҎ(gu)配置文g生成q接Q再交给c3p0理?/span>
proxool?/span>c3p0以及(qing)dbcp不一P它是自己生成q接的,因此q接信息攑֜proxool配置文g中。用它Ӟ需要将proxool-0.8.3.jar加入?/span>classespath中?/span>配置举例如下Q?/span>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 昄实际操作数据库时?/span>SQL -->
<property name="show_sql">true</property>
<!-- SQL方言Q这边设定的?/span>MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!—proxool的配|?/span> -->
<property name="proxool.pool_alias">pool1</property>
<property name="proxool.xml">ProxoolConf.xml</property>
<property name="connection.provider_class">net.sf.hibernate.connection.ProxoolConnectionProvider</property>
<!-- 对象与数据库表格映像文g -->
<mapping resource="com/amigo/pojo/User.hbm.xml"/>
<mapping resource="com/amigo/pojo/Org.hbm.xml"/>
</session-factory>
</hibernate-configuration>
?/span>hibernate.cfg.xml的同目录下编?/span>proxool的配|文Ӟ(x)ProxoolConf.xmlQ该文g的配|实例如下:(x)
ProxoolConf.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
<proxool>
<alias>pool1</alias>
<!--proxool只能理p׃生的q接-->
<!-- 驱动?/span>url-->
<!-- jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=GBK-->
<driver-url>… </driver-url>
<!-- 驱动c,eg. com.mysql.jdbc.Driver-->
<driver-class>… </driver-class>
<driver-properties>
<!-- 数据库用户名Q?/span>eg. value?/span>root-->
<property name="user" value="…"/>
<!-- 数据库密码,eg. value?/span>root-->
<property name="password" value="…."/>
</driver-properties>
<!-- proxool自动侦察各个q接状态的旉间隔(毫秒),侦察到空闲的q接马上回?/span>,时的销?/span>-->
<house-keeping-sleep-time>90000</house-keeping-sleep-time>
<!-- 指因未有I闲q接可以分配而在队列中等候的最大请求数,过q个h数的用户q接׃?x)被接?/span>-->
<maximum-new-connections>20</maximum-new-connections>
<!-- 最保持的I闲q接?/span>-->
<prototype-count>5</prototype-count>
<!-- 允许最大连接数,过?jin)这个连接,再有hӞ排在队列中{候,最大的{待h数由maximum-new-connections军_-->
<maximum-connection-count>100</maximum-connection-count>
<!-- 最连接数-->
<minimum-connection-count>10</minimum-connection-count>
</proxool>
</something-else-entirely>
?/span>hibernate3.0中,已经不再支持dbcp?jin)?/span>hibernate的作者在hibernate.org中,明确指出在实践中发现dbcp?/span> BUG,在某些种情会(x)产生很多I接不能释放,所以抛弃了(jin)?/span>dbcp的支持。若需要?/span>dbcpQ开发h员还需要将commons-pool-1.2.jar ?/span>commons-dbcp-1.2.1.jar两个jar包加入到classpath中?/span>dbcp?/span>c3p0一P都是?/span>hibernate建立q接的?/span>
?/span>hibernate2.0中的配置建立如下Q?/span>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 昄实际操作数据库时?/span>SQL -->
<property name="show_sql">true</property>
<!-- SQL方言Q这边设定的?/span>MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!--驱动E序Q在后箋的章节中讲q?/span>mysql?/span>sqlserver?/span>Oracle数据库的配置 -->
<property name="connection.driver_class">……</property>
<!-- JDBC URL -->
<property name="connection.url">……</property>
<!-- 数据库用户名,eg. root -->
<property name="connection.username">…</property>
<!-- 数据库密?/span>, eg. root-->
<property name="connection.password">…</property>
<property name="dbcp.maxActive">100</property>
<property name="dbcp.whenExhaustedAction">1</property>
<property name="dbcp.maxWait">60000</property>
<property name="dbcp.maxIdle">10</property>
<property name="dbcp.ps.maxActive">100</property>
<property name="dbcp.ps.whenExhaustedAction">1</property>
<property name="dbcp.ps.maxWait">60000</property>
<property name="dbcp.ps.maxIdle">10</property>
<!-- 对象与数据库表格映像文g -->
<mapping resource="com/amigo/pojo/User.hbm.xml"/>
<mapping resource="com/amigo/pojo/Org.hbm.xml"/>
</session-factory>
</hibernate-configuration>
?/span>hibernate中,可以配置很多U数据库Q例?/span>MySql?/span>Sql Server?/span>OracleQ?/span>MySql的配|D例如下:(x)
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 各属性的配置-->
<!?/span>?/span>true表示?/span>Hibernate发送给数据库的sql昄出来 -->
<property name="show_sql">true</property>
<!-- SQL方言Q这边设定的?/span>MySQL -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!-- 一ơ读的数据库记录?/span> -->
<property name="jdbc.fetch_size">50</property>
<!-- 讑֮Ҏ(gu)据库q行扚w删除 -->
<property name="jdbc.batch_size">30</property>
<!--驱动E序-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:mysql://localhost/dbname?characterEncoding=gb2312</property>
<!-- 数据库用户名-->
<property name="connection.username">root</property>
<!-- 数据库密?/span>-->
<property name="connection.password">root</property>
<!?/span>映射文g -->
<mapping resource="com/amigo/pojo/User.hbm.xml"/>
<mapping resource="com/amigo/pojo/Org.hbm.xml"/>
</session-factory>
</hibernate-configuration>
上面使用的驱动类?/span>com.mysql.jdbc.Driver。需要将MySql的连接器jar?/span>(eg. mysql-connector-java-5.0.4-bin.jar)加入?/span>classpath中?/span>
本小节讲qC?/span>Sql Server数据库的hibernateq接讄Q在此只l出q接部分的内容,其余部分?/span>2.2.1.5一P在此不再赘述。内容如下:(x)
<!--驱动E序-->
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:jtds:sqlserver://localhost:1433;DatabaseName=dbname</property>
<!-- 数据库用户名-->
<property name="connection.username">sa</property>
<!-- 数据库密?/span>-->
<property name="connection.password"></property>
上例的驱动类使用的是jtds的驱动类Q因此读者需要将jtds?/span>jar?/span>(eg. jtds-1.2.jar)加入?/span>classpath中?/span>
本小节讲qC?/span>Sql Server数据库的hibernateq接讄Q在此只l出q接部分的内容,其余部分?/span>2.2.1.5一P在此不再赘述。内容如下:(x)
<!--驱动E序-->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!-- JDBC URL -->
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:dbname</property>
<!-- 数据库用户名-->
<property name="connection.username">test</property>
<!-- 数据库密?/span>-->
<property name="connection.password">test</property>
上例使用的驱动类为:(x)oracle.jdbc.driver.OracleDriverQ开发h员需要将相关?/span>jar包(ojdbc14.jarQ加入到classpath中?/span>1Q它是线E安全的Q这意味着它的同一个实例可以被应用的各个线E共享?/p>
2Q它是重量的,q意味着不能随意创徏或销毁它的实例。如果应用只讉K一个数据库Q只需创徏一个SessionFactory实例Q在应用初始化的时候创实例。如果应用同时访问多个数据库Q则需要ؓ(f)每个数据库创Z个单独的SessionFactory实例?/p>
之所以说SessionFactory是重量的,是因为它需要一个很大的~存Q用来存N定义的SQL语句以及(qing)映射元数据等。用戯可以为SessionFactory配置一个缓存插Ӟq个~存插g被称为Hibernate的第二~存Q该~存用来存放被工作单元读q的数据Q将来其它工作单元可能会(x)重用q些数据Q因此这个缓存中的数据能够被所有工作单元共享,一个工作单元通常对应一个数据库事务?/p>
1Q不是线E安全的Q因此在设计软g架构Ӟ应该避免多个U程׃n同一个Session实例Q?/p>
2QSession实例是轻量的,所谓轻量Q是指它的创建和销毁不需要消耗太多的资源。这意味着在程序中可以l常创徏和销毁Session对象Q例如ؓ(f)每个客户h分配单独的Session实例Q或者ؓ(f)每个工作单元分配单独的Session实例?/p>
Session有一个缓存,被称为Hibernate的第一U缓存,它存放被当前工作单元加蝲的对象。每个Session实例都有自己的缓存,q个Session实例的缓存,q个Session实例的缓存只能被当前工作单元讉K?/p>
Hibernate应用可通过一致的Transaction接口来声明事务边界,q有助于应用在不同环境或容器中移植?/p>
由new命o(h)开辟内存空间的java对象Q?/p>
eg. Person person = new Person("amigo", "?);
如果没有变量对该对象q行引用Q它?yu)被java虚拟机回收?/p>
瞬时对象在内存孤立存在,它是携带信息的蝲体,不和数据库的数据有Q何关联关p,在Hibernate中,可通过session的save()或saveOrUpdate()Ҏ(gu)瞬时对象与数据库相兌Qƈ数据对应的插入数据库中Q此时该瞬时对象转变成持久化对象?/p>
处于该状态的对象在数据库中具有对应的记录Qƈ拥有一个持久化标识。如果是用hibernate的delete()Ҏ(gu)Q对应的持久对象变成瞬时对象,因数据库中的对应数据已被删除Q该对象不再与数据库的记录关联?/p>
当一个session执行close()或clear()、evict()之后Q持久对象变成脱对象,此时持久对象?x)变成脱对象,此时该对象虽然具有数据库识别|但它已不在HIbernate持久层的理之下?/p>
持久对象h如下特点Q?/p>
1. 和session实例兌Q?/p>
2. 在数据库中有与之兌的记录?/p>
当与某持久对象关联的session被关闭后Q该持久对象转变对象。当q对象被重新关联到session上时Qƈ再次转变成持久对象?/p>
q对象拥有数据库的识别|可通过update()、saveOrUpdate(){方法,转变成持久对象?/p>
q对象h如下特点Q?/p>
1. 本质上与瞬时对象相同Q在没有M变量引用它时QJVM?x)在适当的时候将它回Ӟ
2. 比瞬时对象多?jin)一个数据库记录标识倹{?/p>