SSH--------持久层(dao)、Service和表现层(web)的设计---抽取避免重复代码

    1. 持久层接口设计(Dao)
      1. 持久层设计图解和原理
  • 这里以User表的数据库设计为例
  1. 每一张表都有共同的数据库操作,如增删改查,所以IBaseDao, BaseDaoImpl中可以放置公有的方法或者属性
  2. 每 一张表都有自己的特有的业务,所以IUserDao里的方法是属于特有的
  3. 这样做代码的扩展性,健壮性比较好

SSH--------持久层(dao)、Service和表现层(web)的设计---抽取避免重复代码

 

      1.  代码:IBaseDao

public interface IBaseDao<T> {

    /**

     * IBaseDao:公共的添加方法

     * */

    public void save(T entity);

    /**

     * IBaseDao:公共的更新方法

     * */

    public void update(T entity);

   

    /**

     * IBaseDao:公共的删除方法

     * */

    public void delete(T entity);

   

    /**

     * IBaseDao:公共的查找方法

     * */

    public List<T> findAll();

   

    /**

     * IBaseDao:公共的查找方法

     * */

    public T findById(Serializable id);

}

 

 

      1.  代码:BaseDaoImpl

public class BaseDaoImpl<T> implements IBaseDao<T> {

    @Override

    public void save(T entity) {}

    @Override

    public void update(T entity) {}

    @Override

    public void delete(T entity) {}

    @Override

    public List<T> findAll() {

       return null;

    }

    @Override

    public T findById(Serializable id) {

       return null;

    }

}

 

      1.  代码:IUserDao

public interface IUserDao extends IBaseDao<User> {

    //用户表特有的数据库操作方法,这里什么方法者不写,后面有需求再加

}

 

      1.  代码:UserDaoImpl

public class UserDaoImpl extends BaseDaoImpl<User>  implements IUserDao{

 

}

      1.  Dao层代码结构

SSH--------持久层(dao)、Service和表现层(web)的设计---抽取避免重复代码

 

      1. BaseDaoImpl的实现

import java.io.Serializable;

import java.lang.reflect.ParameterizedType;

import java.lang.reflect.Type;

import java.util.List;

 

public class BaseDaoImpl<T> implements IBaseDao<T> {

    private Class<T> entityClass;//泛型类

public HibernateTemplate hibernateTemplate;

    public BaseDaoImpl(){

      

       //1.获得父类【BaseDaoImpl<T>】的参数化类型

       ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();

      

       //2.获得父类的参数化类型的数组

       Type[] types = genericSuperclass.getActualTypeArguments();

      

       //3.获取泛型类第一个参数化的类型

       entityClass = (Class<T>) types[0];

      

    }

   

    @Override

    public void save(T entity) {

       // TODO Auto-generated method stub

       this.getHibernateTemplate().save(entity);

    }

 

    @Override

    public void update(T entity) {

       // TODO Auto-generated method stub

       this.getHibernateTemplate().update(entity);

    }

 

    @Override

    public void delete(T entity) {

       // TODO Auto-generated method stub

       this.getHibernateTemplate().delete(entity);

    }

 

    @Override

    public List<T> findAll() {

       // TODO Auto-generated method stub

       String hql = "FROM " + entityClass.getSimpleName();

       return this.getHibernateTemplate().find(hql);

    }

 

    @Override

    public T findById(Serializable id) {

       return this.getHibernateTemplate().get(entityClass, id);

    }

 

}

 

 

 

      1. 注入BaseDaoImpl的hibernateTemplate
  1. 知识补充
  1. Spring3.0版本不支持jdk1.8,如果要使用Jdk1.8,需要升级到Spring4.0
  2. 在使用Tomcat Debug时,会出现Server at localhost was unable to start within 45 seconds的错误,解决办法

workspace\.metadata\.plugins\org.eclipse.wst.server.core\servers.xml文件, 把其中的start-timeout="45" 改为  start-timeout="100" 或者更长,最后重启eclipse就可以了

  1. 项目中可以添加log4j.properties,这样可以看到Hibernate的启动日志等。。。

 

步骤:

1.添加通过注解,在BaseDaoImpl中添加下面代码

/**

     *@Resource JDK提供的注解,默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入

     *@Autowired @Qualifier spring提供注解,默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;

     * */

    @Autowired

    public HibernateTemplate hibernateTemplate;

 

    public HibernateTemplate getHibernateTemplate() {

       return hibernateTemplate;

    }

 

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {

       this.hibernateTemplate = hibernateTemplate;

    }

 

2.在application中要配置hibernateTemplatebean

<!-- hibernateTemplate -->

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">

       <property name="sessionFactory" ref="sessionFactory"></property> 

    </bean>

 

3.在UserDaoImpl中的类名上添加@Repository,(可以通过Debug调试,来测试程序运行后,会自动创建一个dao单例)

 

    1. 》Service接口设计
      1. Servie层设计图解和原理
  1. 以UserService为例来讲解
  2. 图解

SSH--------持久层(dao)、Service和表现层(web)的设计---抽取避免重复代码

  1. 原理:
    1. 与Dao设计一样,有些公共的属性或者方法可以放在BaseService中
    2. 但这里要注意,BaseServiceImpl我们使用抽象类设计,因为你不知道Dao的类型是哪一个
  2. 演示:
    1. 先根据service图解写好所有接口
    2. 在IBaseSerivce中写一个方法public List<T> list();
    3. 在UserServiceImpl中添加@service 和 userDao的自动装配注入,并添加事务

@Service

@Transactional

public class UserServiceImpl implements IUserService{

 

    @Autowired

    private IUserDao userDao;

   

    public IUserDao getUserDao() {

       return userDao;

    }

 

    public void setUserDao(IUserDao userDao) {

       this.userDao = userDao;

    }

}