配置hibernate数据库连接

第一步:右键项目->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
posted @ 2014-12-02 19:30  ciaos  阅读(1625)  评论(0编辑  收藏  举报