第一步:右键项目->MyEclipse->添加Hibernate组件,指定数据库连接配置如下(src/hibernate.cfg.xml)
MySQL对连接的有效期是28800s,一个连接8小时没任何操作就会自动断开;而hibernate的默认连接池不对链接的状态进行检查,所以超过8小时候链接就不在可用,从而导致查询出错;虽然可以增大MySQL的连接有效时间,但是不是终极解决办法。Hibernate共支持5种连接池,可以用c3p0替换默认的连接池可以有很好的效果,此外proxool也是不错的选择,在稳定性、易用性以效率方面都比较优越。
<?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"> <!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration> <session-factory>
<property name="hbm2ddl.auto">update</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://127.0.0.1:3306/test
</property>
<property name="hibernate.connection.provider_class">
org.hibernate.connection.C3P0ConnectionProvider
</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.timeout">120</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">1800</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.c3p0.timeout">3600</property>
<property name="hibernate.cache.use_second_level_cache">
false
</property> <property name="connection.autocommit">false</property>
<property name="connection.username">root</property>
<property name="connection.password">rootpwd</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">tiaowuban</property>
<mapping resource="com/tiaowuban/dao/Account.hbm.xml" /> </session-factory> </hibernate-configuration>
src/applicationContext.xml自动添加配置如下,需要将mysql-connector-{version}-java-bin.jar添加到项目的classpath中
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml">
</property>
</bean>
</beans>
第二步:创建ORM映射(可使用MyEclipse Hibernate Tool生成持久化类,工具可以自行处理表内自增主键,表间的外键关联,一对多/一对一/多对一/多对多等关系。,可参照这里),src/com/smartecs/dao里的文件如下
package com.smartecs.dao; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id; @Entity
public class Account {
@Id
@GeneratedValue
private int id; private String username; private String password; protected Account() {
}
public Account(String username, String password) {
super();
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Account.hbm.xml文件如下
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.smartecs.dao.Account" table="account">
<!-- 必须先定义<id>元素,后定义<property>元素 -->
<id name="id" type="java.lang.Integer">
<column name="id" />
<!-- 主键的生成方式 -->
<generator class="increment" />
</id>
<!-- name属性,类型为String,对应的数据库中的列为name,长度为20 -->
<property name="username" type="java.lang.String">
<column name="username" length="100" />
</property>
<property name="password" type="java.lang.String">
<column name="passwd" length="100" />
</property>
</class>
</hibernate-mapping>
第三步:测试代码:
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
Account account = new Account("ciaos", "ciaospwd");
try {
session.save(account);
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
}finally{
session.close();
}
附,Hibernate Tool反转设置如下(使用xml映射方式)
如果hibernate 3支持注解方式映射数据库,不需要维护xml文件,方便很多(Spring3.1.1+Hibernate3.3.2测试通过,Spring3.0.5未测试通过,提示AnnotationSessionFactoryBean的属性configurationClass配置错误,不过Hibernate4已经废弃掉此属性,就无所谓了)
src/applicationContext.xml配置如下(更换bean为annotation):
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml">
</property>
<property name="mappingResources">
<list></list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dbcp.whenExhaustedAction">1</prop>
<prop key="hibernate.dbcp.maxIdle">10</prop>
<prop key="hibernate.dbcp.maxWait">604800</prop>
</props>
</property>
</bean>
</beans>
src/hibernate.cfg.xml将<mapping resource>更换为<mapping class>
<mapping resource="com/tiaowuban/dao/Account.hbm.xml" />
-->
<mapping class="com.tiaowuban.api.dao.Account" />
添加依赖库(hibernate-annotations.jar,hibernate-commons-annotations.jar,ejb3-persistence.jar,hibernate-core.jar),反转后数据表实体映射关系直接在POJO里面组织了。注解方式的反转配置如下:
hibernate 3增加DAO层封装了实体类的基本操作(功能比较弱,可以通过泛型扩展增加功能),使用起来更加方便,反转时需要配置如下(注意选择默认DAO),代码中会生成BaseHibernateDAO父类封装连接获取方法。
TbAccountDAO adao = new TbAccountDAO();
TbAccount account = adao.findById(1);
BaseHibernateDAO及接口方法如下:
package com.tiaowuban.api.ndao; import org.hibernate.Session; /**
* Data access interface for domain model
* @author MyEclipse Persistence Tools
*/
public interface IBaseHibernateDAO {
public Session getSession();
} package com.tiaowuban.api.ndao; import com.tiaowuban.api.dao.HibernateSessionFactory;
import javax.persistence.Entity;
import org.hibernate.Session; /**
* Data access object (DAO) for domain model
* @author MyEclipse Persistence Tools
*/
@Entity
public class BaseHibernateDAO implements IBaseHibernateDAO { public Session getSession() {
return HibernateSessionFactory.getSession();
} }
如下可通过泛型扩展增加多个属性查询方法(可举一反三增加删除,搜索等更丰富的方法)
package com.tiaowuban.api.dao; import java.util.List; import org.hibernate.Session; /**
* Data access interface for domain model
* @author MyEclipse Persistence Tools
* @param <T>
*/
public interface IBaseHibernateDAO<T> {
public Session getSession(); public abstract List<T> findByPropertys(String[] propertyNames,Object[] values); /**
* 通过多个属性查找,并分页,
* 属性名称数组和属性值数组的序列要对应
*
* @param propertyNames 属性名称数组
* @param values 属性值数组
* @param page 页码
* @param pageSize 每页内容条数
* @return
*/
public List<T> findByPropertys(String[] propertyNames,Object[] values,int page,int pageSize); /**
* 通过属性查找,并分页,
* 属性名称数组和属性值数组的序列要对应
*
* @param propertyNames 属性名称
* @param values 属性值
* @param page 页码
* @param pageSize 每页内容条数
* @return
*/
public List<T> findByProperty(String propertyName,Object value,int page,int pageSize); } package com.tiaowuban.api.dao; import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.transaction.annotation.Transactional; /**
* Data access object (DAO) for domain model
* @author MyEclipse Persistence Tools
*/
@Transactional
public class BaseHibernateDAO<T> implements IBaseHibernateDAO<T> { public Session getSession() {
return HibernateSessionFactory.getSession();
} private Class<T> persistentClass;
@SuppressWarnings("unchecked")
public BaseHibernateDAO()
{
// 获取持久化对象的类型
this.persistentClass = (Class<T>)getClass();
} public Class<T> getPersistentClass()
{
return persistentClass;
} /**
* 通过多个属性组合查询
*
* @param propertyNames
* 属性名称数组
* @param values
* 对应于propertyNames的值 return 匹配的结果
*/
public List<T> findByPropertys(String[] propertyNames, Object[] values)
{
int i = 0;
StringBuffer strBuffer = new StringBuffer();
strBuffer.append("from " + getPersistentClass().getName().replaceAll("DAO$", ""));
strBuffer.append(" as model where");
for (i = 0; i < propertyNames.length; i++)
{
if (i != 0)
strBuffer.append(" and");
strBuffer.append(" model.");
strBuffer.append(propertyNames[i]);
strBuffer.append("=");
strBuffer.append("? ");
}
String queryString = strBuffer.toString();
System.err.println(queryString);
Query query = getSession().createQuery(queryString);
for (i = 0; i < values.length; i++)
{
query.setParameter(i, values[i]);
} return query.list();
} /**
* 通过属性查找并分页
*
* @param propertyName
* 属性名称
* @param value
* 属性值
* @param page
* 页数
* @param pageSize
* 每页显示条数
*/
public List<T> findByProperty(String propertyName, Object value, int page,
int pageSize)
{
return this.findByPropertys(new String[]
{
propertyName
}, new Object[]
{
value
}, page, pageSize);
} /**
* 通过多个属性组合查询
*
* @param propertyNames
* 属性名称数组
* @param values
* 对应于propertyNames的值
* @param page
* 页数
* @param pageSize
* 每页显示数 return 匹配的结果 return 匹配的结果
*/
public List<T> findByPropertys(String[] propertyNames, Object[] values,
int page, int pageSize)
{ StringBuffer strBuffer = new StringBuffer();
strBuffer.append("from " + getPersistentClass().getName());
strBuffer.append(" as model where");
for (int i = 0; i < propertyNames.length; i++)
{
if (i != 0)
strBuffer.append(" and");
strBuffer.append(" model.");
strBuffer.append(propertyNames[i]);
strBuffer.append("=");
strBuffer.append("? ");
}
String queryString = strBuffer.toString(); int firstResult = (page - 1) * pageSize; Query query = this.getSession().createQuery(queryString);
query.setFirstResult(firstResult);
query.setMaxResults(pageSize);
for (int i = 0; i < values.length; i++)
{
query.setParameter(i, values[i]);
} return query.list();
}
}
使用方法如下
TbAccountDAO adao = new TbAccountDAO();
List<TbAccount> accountlist = adao.findByPropertys(new String[]{"id","username"}, new Object[]{3,"ciaos"});
反转配置如下:
数据库中表结构如下:
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`passwd` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1