找了一些spring的文章看了下,有所启发,于是大概的总结了下,希望大家多提提意见
为了实现自己程序对spring和hibernate的过分依赖,因此自己写了一个接口,封装了8个常用的数据库操作
接口如下
- package com.pig.dao;
- import java.io.Serializable;
- import java.util.Collection;
- import java.util.List;
- import org.springframework.dao.DataAccessException;
- /**
- * 实现具体数据访问的接口,该接口将程序和框架进行了分离,提供了抽象出来的几个常用的方法 优点:减少了对spring,hibernate的依赖
- * 缺点:提供了有限的几个方法,可能造成提供的方法不全
- *
- * @author lizhihui
- * @see DAOInterfaceHibernate3Imp
- */
- public interface DAOInterface {
- /**
- * Persist the given transient instance.
- * @param entity the transient instance to persist
- * @return the generated identifier
- */
- public Serializable save(Object entity);
- /**
- * Save or update the given persistent instance,
- * according to its id (matching the configured "unsaved-value"?).
- * @param entity the persistent instance to save or update
- * (to be associated with the Hibernate Session)
- * @throws DataAccessException in case of Hibernate errors
- * @see net.sf.hibernate.Session#saveOrUpdate(Object)
- */
- public void saveOrUpdate(Object entity) throws DataAccessException;
- /**
- * Save or update all given persistent instances,
- * according to its id (matching the configured "unsaved-value"?).
- * @param entities the persistent instances to save or update
- * (to be associated with the Hibernate Session)
- * @throws DataAccessException in case of Hibernate errors
- * @see net.sf.hibernate.Session#saveOrUpdate(Object)
- */
- public void saveOrUpdate(Collection entities) throws DataAccessException;
- /**
- * Delete the given persistent instance.
- * @param entity the persistent instance to delete
- * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
- * @see net.sf.hibernate.Session#delete(Object)
- */
- public void delete(Object entity) throws DataAccessException;
- /**
- * Delete the instance according to identifier
- * @param c class of instance
- * @param id identifier
- * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
- */
- public void delete(Class c, Serializable id) throws DataAccessException;
- /**
- * Delete all given persistent instances.
- *
This can be combined with any of the find methods to delete by query
- * in two lines of code, similar to Session's delete by query methods.
- * @param entities the persistent instances to delete
- * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
- * @see net.sf.hibernate.Session#delete(String)
- */
- public void delete(Collection entities) throws DataAccessException;
- /**
- * Return the persistent instance of the given entity class
- * with the given identifier, throwing an exception if not found.
- *
This method is a thin wrapper around
- * {@link net.sf.hibernate.Session#load(Class, java.io.Serializable)} for convenience.
- * For an explanation of the exact semantics of this method, please do refer to
- * the Hibernate API documentation in the first instance.
- * @param entityClass a persistent class
- * @param id an identifier of the persistent instance
- * @return the persistent instance
- * @throws org.springframework.orm.ObjectRetrievalFailureException if not found
- * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
- * @see net.sf.hibernate.Session#load(Class, java.io.Serializable)
- */
- public Object load(Class entityClass, Serializable id) throws DataAccessException;
- /**
- * Execute an HQL query
- * @param queryString a query expressed in Hibernate's query language
- * @return a List containing the results of the query execution
- * @throws org.springframework.dao.DataAccessException in case of Hibernate errors
- * @see net.sf.hibernate.Session#find(String, Object[], net.sf.hibernate.type.Type[])
- * @see net.sf.hibernate.Session#createQuery
- */
- public List find(String queryString) throws DataAccessException;
- }
他的实现
- package com.pig.dao;
- import java.io.Serializable;
- import java.sql.SQLException;
- import java.util.Collection;
- import java.util.List;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.hibernate.HibernateException;
- import org.hibernate.Query;
- import org.hibernate.Session;
- import org.springframework.dao.DataAccessException;
- import org.springframework.orm.hibernate3.HibernateCallback;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- public class DAOInterfaceHibernate3Imp extends HibernateDaoSupport implements DAOInterface {
- private static Log log=LogFactory.getLog(DAOInterfaceHibernate3Imp.class);
- public void delete(Object entity) throws DataAccessException {
- getHibernateTemplate().delete(entity);
- }
- public void delete(Class c, Serializable id) throws DataAccessException {
- Object entiry = load(c, id);
- getHibernateTemplate().delete(entiry);
- }
- public void delete(Collection entities) throws DataAccessException {
- getHibernateTemplate().deleteAll(entities);
- }
- public List find(String queryString) throws DataAccessException {
- return getHibernateTemplate().find(queryString);
- }
- public Object load(Class entityClass, Serializable id) throws DataAccessException {
- return getHibernateTemplate().load(entityClass, id);
- }
- public Serializable save(Object entity) {
- return getHibernateTemplate().save(entity);
- }
- public void saveOrUpdate(Object entity) throws DataAccessException {
- getHibernateTemplate().saveOrUpdate(entity);
- }
- public void saveOrUpdate(Collection entities) throws DataAccessException {
- getHibernateTemplate().saveOrUpdateAll(entities);
- }
- }
这样如果 hibernate如果有了变得 只改变他的实现类就可以了,甚至可以改变成其他的中间件实现
在程序中只用了实现了一个DAO,感觉他可以对所以的类操作了,至于其他的和业务相关联的操作 例如用户登陆,修改秘密等操作 我把他们归结到了 service中,这样service的实现可能要好多的类和接口
大家看下我的DAO
- package com.pig.dao;
- import java.io.Serializable;
- import java.util.Collection;
- import java.util.List;
- import org.springframework.dao.DataAccessException;
- import com.pig.util.PropertyResource;
- public class BasicDAO {
- private DAOInterface dao;
- private PropertyResource sqlMapping;
- public BasicDAO(){
- }
- public void delete(Object entity) throws DataAccessException {
- dao.delete(entity);
- }
- public void delete(Class c, Serializable id) throws DataAccessException {
- dao.delete(c,id);
- }
- public void delete(Collection entities) throws DataAccessException {
- dao.delete(entities);
- }
- public List find(String queryStringKey,Object[] args) throws DataAccessException {
- return dao.find(sqlMapping.getFormattedString(queryStringKey, args));
- }
- public Object load(Class entityClass, Serializable id) throws DataAccessException {
- return dao.load(entityClass, id);
- }
- public Serializable save(Object entity) {
- return dao.save(entity);
- }
- public void saveOrUpdate(Object entity) throws DataAccessException {
- dao.saveOrUpdate(entity);
- }
- public void saveOrUpdate(Collection entities) throws DataAccessException {
- dao.saveOrUpdate(entities);
- }
- }
在这个DAO中注入了一个DAOInterface 和 一个properties 文件 这个文件可以根据key来找到对应的hql 或者sql语句 并将参数格式化进去,看下这个方法
- public List find(String queryStringKey,Object[] args) throws DataAccessException {
- return dao.find(sqlMapping.getFormattedString(queryStringKey, args));
- }
这个方法直接根据给定的hql语句 查询出结果集。本来还想给出一个根据hql来更新数据库的操作,但是发现hibernate好像没有提供这个接口(我对hibernate的了解还不是很多)
下面将读取hql文件的的类也一并给出 大家参考下把,这个hql文件应该放到classpath下
- package com.pig.util;
- import java.text.MessageFormat;
- import java.util.*;
- /**
- * read properties file in classpath
- * @author lzh
- * @version 1.0
- */
- public class PropertyResource {
- private String resourceName;
- private Locale locale;
- private Map<String, String> properties;
- public PropertyResource() {
- }
- private void init() {
- if (properties == null) {
- properties = new Hashtable<String, String>();
- ResourceBundle rb = null;
- if (locale == null) {
- rb = ResourceBundle.getBundle(resourceName);
- } else {
- rb = ResourceBundle.getBundle(resourceName, locale);
- }
- Enumeration<String> e = rb.getKeys();
- String key = null;
- String value = null;
- while (e.hasMoreElements()) {
- key = e.nextElement();
- value = rb.getString(key);
- properties.put(key, value);
- }
- }
- }
- public String getString(String key) {
- if (properties == null) {
- init();
- }
- return properties.get(key);
- }
- public String getString(String key, String defaultValue) {
- if (properties == null) {
- init();
- }
- String value = properties.get(key);
- return value == null ? defaultValue : value;
- }
- public String getFormattedString(String key, Object args[]) {
- String msg = MessageFormat.format(getString(key), args);
- return msg;
- }
- public Locale getLocale() {
- return locale;
- }
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
- public String getResourceName() {
- return resourceName;
- }
- public void setResourceName(String resourceName) {
- this.resourceName = resourceName;
- }
- }
最后大家看下我spring的配置文件把,这个配置文件还配置了对事务的管理(参考了他人的做法)
- <!-- Hibernate SessionFactory -->
- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="dataSource" ref="dataSource"/>
- <property name="mappingResources">
- <list>
- </list>
- </property>
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">${hibernate.dialect}</prop>
- <prop key="hibernate.show_sql">true</prop>
- <prop key="hibernate.generate_statistics">true</prop>
- </props>
- </property>
- <property name="eventListeners">
- <map>
- <entry key="merge">
- <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
- </entry>
- </map>
- </property>
- </bean>
- <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- <!--define bean of transaction interceptor -->
- <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <property name="transactionManager" ref="transactionManager" />
- <property name="transactionAttributes">
- <props>
- <prop key="insert*">PROPAGATION_REQUIRED</prop>
- <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- <!-- define BeanNameAutoProxyCreator-->
- <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property name="beanNames">
- <!-- 所有名字以DAO,Service结尾的bean,将由该"bean后处理器"为其创建事务代理;实际上应该在业务层进行事务管理,这里只是举一个简单例子 -->
- <value>*DAO,*Service</value>
- </property>
- <!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
- <property name="interceptorNames">
- <list>
- <!-- 可以增加其他的拦截器 -->
- <value>transactionInterceptor</value>
- </list>
- </property>
- </bean>
- <!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
- <bean id="daoInterface" class="com.pig.dao.DAOInterfaceHibernate3Imp">
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- <bean id="sqlPropertyResource" class="com.pig.util.PropertyResource">
- <property name="resourceName" value="com.pig.resource"/>
- </bean>
- <bean id="basicDAO" class="com.pig.dao.BasicDAO">
- <property name="dao" ref="daoInterface"/>
- <property name="sqlMapping" ref="sqlPropertyResource"/>
- </bean>
希望大家能多提意见,偶对spring才看了没几天,看了大家的贴子,可以说是照葫芦画瓢 见笑见笑