手把手教你配置Spring+hibernate

项目一般都需要查询数据库,hibernate是一套比较好的解决方案。本文将手把手教你如何配置Spring+hibernate,为项目搭建好“数据库操作”的主要框架。


一、引入包

本例子使用Spring+Hibernate,连接mysql数据库,故需要下载hibernate、spring、apache common、mysql相关的包

下载地址:

1.Spring(3.2.0.M2)

https://repo.springsource.org/libs-milestone-local/org/springframework/spring/3.2.0.M2/spring-3.2.0.M2-dist.zip

2.hibernate(v 3.6.10.Final)

http://downloads.sourceforge.net/project/hibernate/hibernate3/3.6.10.Final/hibernate-distribution-3.6.10.Final-dist.zip?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fhibernate%2Ffiles%2Fhibernate3%2F3.6.10.Final%2F&ts=1362813076&use_mirror=nchc

3.commons-beanutils-1.8.3.jar

http://mirrors.cnnic.cn/apache//commons/beanutils/binaries/commons-beanutils-1.8.3-bin.zip

4.commons-logging-1.1.1.jar

http://www.fayea.com/apache-mirror//commons/logging/binaries/commons-logging-1.1.1-bin.zip

5.Mysql-connector

http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.0.8.zip/from/http://cdn.mysql.com/


创建工程并导入jar包现在你工程的libs目录,应该如下图一样



二、配置文件

1.info.hbm.xml,hibernate映射配置文件,这个文件告诉项目,你的javabean类,和数据库的各个表,是存在怎样的映射关系

例如,我创建了一个名为AccountInfo的类,位于com.giantray.bean这个package下面,这个类的数据,想保存到t_account这张数据表,其中,属性logingId对应到数据库表中的login_id字段。那么,配置文件应如下:

<?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">

<hibernate-mapping package="com.giantray.bean">


    <class name="AccoutInfo" table="t_account">
        <id name="id" column="id" >  
         </id>  
        <property name="accountName" column="account_name" />
        <property name="loginId" column="login_id" />
        <property name="loginPassword" column="login_password" />
    </class>

</hibernate-mapping>


2.beans.xml,spring配置文件,这个文件告诉项目,你的项目是怎么连接数据库的

你需要在url、username、password中指定连接数据库的url、帐号和密码,在mappingResources中指定哪个文件定义了hibernate映射关系,例如本文就是info.hbm.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" 
"http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
    <bean id="dataSource" 
          class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
        <property name="driverClassName"> 
            <value>com.mysql.jdbc.Driver</value> 
        </property> 
        <property name="url"> 
            <value>jdbc:mysql://10.111.21.233:8809/db_test?useUnicode=true&characterEncoding=utf8</value> 
        </property> 
        <property name="username"> 
            <value>name</value> 
        </property> 
        <property name="password"> 
            <value>psword</value> 
        </property> 
 
    </bean> 

    <bean id="sessionFactory" 
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 
          > 
        <property name="dataSource"> 
            <ref bean="dataSource"/> 
        </property> 
        <property name="mappingResources"> 
            <list> 
                <value>com/giantray/bean/info.hbm.xml</value> 
            </list> 
        </property> 
        <property name="hibernateProperties"> 
            <props> 
                <prop key="hibernate.dialect"> 
                    org.hibernate.dialect.MySQLDialect 
                </prop> 
                <prop key="hibernate.show_sql">true
                </prop> 
            	<prop key="hibernate.format_sql">true
            	</prop>
            </props> 
        </property> 
          
    </bean> 


    <bean id="GenericHibernateDao" class="com.giantray.dao.GenericHibernateDao"> 
        <property name="sessionFactory"> 
            <ref bean="sessionFactory"/> 
        </property> 
    </bean> 
</beans>

3.log4j.properties,log4j配置文件,因为spring会输出log,需要用户配置log4j

#log4j.properties start

log4j.rootLogger=INFO,myLogFile,myConsoler
log4j.appender.myConsole=org.apache.log4j.ConsoleAppender
log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.myConsole.layout.ConversionPattern=%5p [%t] (%F:%L) %m%n
log4j.appender.myLogFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.myLogFile.File=E:/test/log/debug.log
log4j.appender.myLogFile.Append=true
log4j.appender.myLogFile.layout=org.apache.log4j.PatternLayout
log4j.appender.myLogFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} : %-5p | %-.50c | %X{userId},%m%n


三、DAO代码

1.GenericHibernateDao.java

package com.giantray.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;
import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class GenericHibernateDao<T extends Serializable, PK extends Serializable> extends HibernateDaoSupport implements
		GenericDao<T, PK>
{
	// 实体类类型(由构造方法自动赋值)
	private Class<T> entityClass;

	// 构造方法,根据实例类自动获取实体类类型
	public GenericHibernateDao()
	{
		this.entityClass = null;
		Class c = getClass();
		Type t = c.getGenericSuperclass();
		if (t instanceof ParameterizedType)
		{
			Type[] p = ((ParameterizedType) t).getActualTypeArguments();
			this.entityClass = (Class<T>) p[0];
		}
	}

	// -------------------- 基本检索、增加、修改、删除操作 --------------------

	// 根据主键获取实体。如果没有相应的实体,返回 null。
	public T get(PK id)
	{
		return (T) getHibernateTemplate().get(entityClass, id);
	}

	// 根据主键获取实体并加锁。如果没有相应的实体,返回 null。
	public T getWithLock(PK id, LockMode lock)
	{
		T t = (T) getHibernateTemplate().get(entityClass, id, lock);
		if (t != null)
		{
			this.flush(); // 立即刷新,否则锁不会生效。
		}
		return t;
	}

	// 根据主键获取实体。如果没有相应的实体,抛出异常。
	public T load(PK id)
	{
		return (T) getHibernateTemplate().load(entityClass, id);
	}

	// 根据主键获取实体并加锁。如果没有相应的实体,抛出异常。
	public T loadWithLock(PK id, LockMode lock)
	{
		T t = (T) getHibernateTemplate().load(entityClass, id, lock);
		if (t != null)
		{
			this.flush(); // 立即刷新,否则锁不会生效。
		}
		return t;
	}

	// 获取全部实体。
	public List<T> loadAll()
	{
		return (List<T>) getHibernateTemplate().loadAll(entityClass);
	}

	// loadAllWithLock() ?

	// 更新实体
	public void update(T entity)
	{
		getHibernateTemplate().update(entity);
	}

	// 更新实体并加锁
	public void updateWithLock(T entity, LockMode lock)
	{
		getHibernateTemplate().update(entity, lock);
		this.flush(); // 立即刷新,否则锁不会生效。
	}

	// 存储实体到数据库
	public void save(T entity)
	{
		getHibernateTemplate().save(entity);
	}

	// saveWithLock()?

	// 增加或更新实体
	public void saveOrUpdate(T entity)
	{
		getHibernateTemplate().saveOrUpdate(entity);
	}

	// 增加或更新集合中的全部实体
	public void saveOrUpdateAll(Collection<T> entities)
	{
		getHibernateTemplate().saveOrUpdateAll(entities);
	}

	// 删除指定的实体
	public void delete(T entity)
	{
		getHibernateTemplate().delete(entity);
	}

	// 加锁并删除指定的实体
	public void deleteWithLock(T entity, LockMode lock)
	{
		getHibernateTemplate().delete(entity, lock);
		this.flush(); // 立即刷新,否则锁不会生效。
	}

	// 根据主键删除指定实体
	public void deleteByKey(PK id)
	{
		this.delete(this.load(id));
	}

	// 根据主键加锁并删除指定的实体
	public void deleteByKeyWithLock(PK id, LockMode lock)
	{
		this.deleteWithLock(this.load(id), lock);
	}

	// 删除集合中的全部实体
	public void deleteAll(Collection<T> entities)
	{
		getHibernateTemplate().deleteAll(entities);
	}

	// -------------------- HSQL ----------------------------------------------

	// 使用HSQL语句直接增加、更新、删除实体
	public int bulkUpdate(String queryString)
	{
		return getHibernateTemplate().bulkUpdate(queryString);
	}

	// 使用带参数的HSQL语句增加、更新、删除实体
	public int bulkUpdate(String queryString, Object[] values)
	{
		return getHibernateTemplate().bulkUpdate(queryString, values);
	}

	// 使用HSQL语句检索数据
	public List find(String queryString)
	{
		return getHibernateTemplate().find(queryString);
	}

	// 使用带参数的HSQL语句检索数据
	public List find(String queryString, Object[] values)
	{
		return getHibernateTemplate().find(queryString, values);
	}

	// 使用带命名的参数的HSQL语句检索数据
	public List findByNamedParam(String queryString, String[] paramNames, Object[] values)
	{
		return getHibernateTemplate().findByNamedParam(queryString, paramNames, values);
	}

	// 使用命名的HSQL语句检索数据
	public List findByNamedQuery(String queryName)
	{
		return getHibernateTemplate().findByNamedQuery(queryName);
	}

	// 使用带参数的命名HSQL语句检索数据
	public List findByNamedQuery(String queryName, Object[] values)
	{
		return getHibernateTemplate().findByNamedQuery(queryName, values);
	}

	// 使用带命名参数的命名HSQL语句检索数据
	public List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values)
	{
		return getHibernateTemplate().findByNamedQueryAndNamedParam(queryName, paramNames, values);
	}

	// 使用HSQL语句检索数据,返回 Iterator
	public Iterator iterate(String queryString)
	{
		return getHibernateTemplate().iterate(queryString);
	}

	// 使用带参数HSQL语句检索数据,返回 Iterator
	public Iterator iterate(String queryString, Object[] values)
	{
		return getHibernateTemplate().iterate(queryString, values);
	}

	// 关闭检索返回的 Iterator
	public void closeIterator(Iterator it)
	{
		getHibernateTemplate().closeIterator(it);
	}

	// -------------------------------- Criteria ------------------------------

	// 创建与会话无关的检索标准
	public DetachedCriteria createDetachedCriteria()
	{
		return DetachedCriteria.forClass(this.entityClass);
	}

	// 创建与会话绑定的检索标准
	public Criteria createCriteria()
	{
		return this.createDetachedCriteria().getExecutableCriteria(this.getSession());
	}

	// 检索满足标准的数据
	public List findByCriteria(DetachedCriteria criteria)
	{
		return getHibernateTemplate().findByCriteria(criteria);
	}

	// 检索满足标准的数据,返回指定范围的记录
	public List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults)
	{
		return getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
	}

	// 使用指定的实体及属性检索(满足除主键外属性=实体值)数据
	public List<T> findEqualByEntity(T entity, String[] propertyNames)
	{
		Criteria criteria = this.createCriteria();
		Example exam = Example.create(entity);
		exam.excludeZeroes();
		String[] defPropertys = getSessionFactory().getClassMetadata(entityClass).getPropertyNames();
		for (String defProperty : defPropertys)
		{
			int ii = 0;
			for (ii = 0; ii < propertyNames.length; ++ii)
			{
				if (defProperty.equals(propertyNames[ii]))
				{
					criteria.addOrder(Order.asc(defProperty));
					break;
				}
			}
			if (ii == propertyNames.length)
			{
				exam.excludeProperty(defProperty);
			}
		}
		criteria.add(exam);
		return (List<T>) criteria.list();
	}

	// 使用指定的实体及属性检索(满足属性 like 串实体值)数据
	public List<T> findLikeByEntity(T entity, String[] propertyNames)
	{
		Criteria criteria = this.createCriteria();
		for (String property : propertyNames)
		{
			try
			{
				Object value = PropertyUtils.getProperty(entity, property);
				if (value instanceof String)
				{
					criteria.add(Restrictions.like(property, (String) value, MatchMode.ANYWHERE));
					criteria.addOrder(Order.asc(property));
				}
				else
				{
					criteria.add(Restrictions.eq(property, value));
					criteria.addOrder(Order.asc(property));
				}
			}
			catch (Exception ex)
			{
				// 忽略无效的检索参考数据。
			}
		}
		return (List<T>) criteria.list();
	}

	// 使用指定的检索标准获取满足标准的记录数
	public Integer getRowCount(DetachedCriteria criteria)
	{
		criteria.setProjection(Projections.rowCount());
		List list = this.findByCriteria(criteria, 0, 1);
		return (Integer) list.get(0);
	}

	// 使用指定的检索标准检索数据,返回指定统计值(max,min,avg,sum)
	public Object getStatValue(DetachedCriteria criteria, String propertyName, String StatName)
	{
		if (StatName.toLowerCase().equals("max"))
			criteria.setProjection(Projections.max(propertyName));
		else if (StatName.toLowerCase().equals("min"))
			criteria.setProjection(Projections.min(propertyName));
		else if (StatName.toLowerCase().equals("avg"))
			criteria.setProjection(Projections.avg(propertyName));
		else if (StatName.toLowerCase().equals("sum"))
			criteria.setProjection(Projections.sum(propertyName));
		else
			return null;
		List list = this.findByCriteria(criteria, 0, 1);
		return list.get(0);
	}

	// -------------------------------- Others --------------------------------

	// 加锁指定的实体
	public void lock(T entity, LockMode lock)
	{
		getHibernateTemplate().lock(entity, lock);
	}

	// 强制初始化指定的实体
	public void initialize(Object proxy)
	{
		getHibernateTemplate().initialize(proxy);
	}

	// 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
	public void flush()
	{
		getHibernateTemplate().flush();
	}
}


2.GenericDao.java

package com.giantray.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.LockMode;
import org.hibernate.criterion.DetachedCriteria;

public interface GenericDao<T extends Serializable, PK extends Serializable>
{
	// -------------------- 基本检索、增加、修改、删除操作 --------------------

	// 根据主键获取实体。如果没有相应的实体,返回 null。
	public T get(PK id);

	// 根据主键获取实体并加锁。如果没有相应的实体,返回 null。
	public T getWithLock(PK id, LockMode lock);

	// 根据主键获取实体。如果没有相应的实体,抛出异常。
	public T load(PK id);

	// 根据主键获取实体并加锁。如果没有相应的实体,抛出异常。
	public T loadWithLock(PK id, LockMode lock);

	// 获取全部实体。
	public List<T> loadAll();

	// loadAllWithLock() ?

	// 更新实体
	public void update(T entity);

	// 更新实体并加锁
	public void updateWithLock(T entity, LockMode lock);

	// 存储实体到数据库
	public void save(T entity);

	// saveWithLock()

	// 增加或更新实体
	public void saveOrUpdate(T entity);

	// 增加或更新集合中的全部实体
	public void saveOrUpdateAll(Collection<T> entities);

	// 删除指定的实体
	public void delete(T entity);

	// 加锁并删除指定的实体
	public void deleteWithLock(T entity, LockMode lock);

	// 根据主键删除指定实体
	public void deleteByKey(PK id);

	// 根据主键加锁并删除指定的实体
	public void deleteByKeyWithLock(PK id, LockMode lock);

	// 删除集合中的全部实体
	public void deleteAll(Collection<T> entities);

	// -------------------- HSQL ----------------------------------------------

	// 使用HSQL语句直接增加、更新、删除实体
	public int bulkUpdate(String queryString);

	// 使用带参数的HSQL语句增加、更新、删除实体
	public int bulkUpdate(String queryString, Object[] values);

	// 使用HSQL语句检索数据
	public List find(String queryString);

	// 使用带参数的HSQL语句检索数据
	public List find(String queryString, Object[] values);

	// 使用带命名的参数的HSQL语句检索数据
	public List findByNamedParam(String queryString, String[] paramNames, Object[] values);

	// 使用命名的HSQL语句检索数据
	public List findByNamedQuery(String queryName);

	// 使用带参数的命名HSQL语句检索数据
	public List findByNamedQuery(String queryName, Object[] values);

	// 使用带命名参数的命名HSQL语句检索数据
	public List findByNamedQueryAndNamedParam(String queryName, String[] paramNames, Object[] values);

	// 使用HSQL语句检索数据,返回 Iterator
	public Iterator iterate(String queryString);

	// 使用带参数HSQL语句检索数据,返回 Iterator
	public Iterator iterate(String queryString, Object[] values);

	// 关闭检索返回的 Iterator
	public void closeIterator(Iterator it);

	// -------------------------------- Criteria ------------------------------

	// 创建与会话无关的检索标准对象
	public DetachedCriteria createDetachedCriteria();

	// 创建与会话绑定的检索标准对象
	public Criteria createCriteria();

	// 使用指定的检索标准检索数据
	public List findByCriteria(DetachedCriteria criteria);

	// 使用指定的检索标准检索数据,返回部分记录
	public List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults);

	// 使用指定的实体及属性检索(满足除主键外属性=实体值)数据
	public List<T> findEqualByEntity(T entity, String[] propertyNames);

	// 使用指定的实体及属性(非主键)检索(满足属性 like 串实体值)数据
	public List<T> findLikeByEntity(T entity, String[] propertyNames);

	// 使用指定的检索标准检索数据,返回指定范围的记录
	public Integer getRowCount(DetachedCriteria criteria);

	// 使用指定的检索标准检索数据,返回指定统计值
	public Object getStatValue(DetachedCriteria criteria, String propertyName, String StatName);

	// -------------------------------- Others --------------------------------

	// 加锁指定的实体
	public void lock(T entity, LockMode lockMode);

	// 强制初始化指定的实体
	public void initialize(Object proxy);

	// 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新)
	public void flush();

}

3.DataCollectorDao

package com.giantray.dao;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.giantray.bean.AccoutInfo;

public class DataCollectorDao
{
	private Logger log = LoggerFactory.getLogger(this.getClass());

	private static ApplicationContext ctx = new FileSystemXmlApplicationContext("beans.xml");

	private static GenericDao dao = (GenericDao) ctx.getBean("GenericHibernateDao");

	
	public AccoutInfo getAccount(int accoutId)
	{
		AccoutInfo accoutInfo = null;
		List<Object> list = dao.find("FROM AccoutInfo as a WHERE a.id = ?", new Integer[] { accoutId });
		if(null != list && list.size() > 0)
		{
			accoutInfo = (AccoutInfo) list.get(0);
		}
		
		return accoutInfo;
	}



	public static void main(String[] args)
	{
		DataCollectorDao dao = new DataCollectorDao();
		dao.getAccount(1);
	}


}



总结:

最后工程结构如下,DataCollectorDao是我自己的查询DAO,查询逻辑都在这个类里,这个类本质上是调用了泛型DAO提供的接口进行查询:




声明:本文的泛型DAO来自于这篇文章:一个通用的泛型GenericHibernateDao(http://blog.csdn.net/aladdinty/article/details/4615946)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值