您的位置:首页 > 其它

85-002-8 在web项目中对service层的方法抽取

2016-06-29 12:25 316 查看
图文版:http://note.youdao.com/yws/public/redirect/share?id=abc20790e48da5130e227d9390e4df92&type=false
资源文件下载 https://yunpan.cn/OcRaTMHR3NWIIf  访问密码
4b2c

8.1 现在我们来分析一下service层的方法抽取,首先对于一些公共的方法肯定需要进行抽取的。下面在service层中再定义两个方法
    CategoryService.java
public void delete(int id) ;
public Category get(int id) ;

public List<Category> query(); 

8.2 然后实现上面的子类,并把 CategoryServiceImpl类中没有与spring整合的方法给改成整合后的方法
public void save(Category category) {
  getSession().save(category) ;
 }

public void delete(int id) {
        //没有延迟性的加载对象并且在删除对象之前还要查询一下数据库看是否有对应的对象
        //明显有降低性能方面的问题。
        /*Category category = (Category)getSession().get(Category.class,id) ;
        if(category != null)
            getSession().delete(category);*/
        //鉴于上面的问题,直接用HQL语句实现直截了当
        String qhl = "DELETE Category WHERE id=:id" ;
        getSession().createQuery(qhl).setInteger("id",id).executeUpdate() ;
    }

public Category get(int id) {
        return (Category)getSession().get(Category.class,id) ;
    }
    public List<Category> query() {
        String hql = "FROM category" ;
        return getSession().createQuery(hql).list();
    }

8.3 现在对这些公用方法实现抽取,一种是接口级别的抽取,一种是类级别的抽取。下面实现的是接口级别的抽取
    BaseService.java
public interface BaseService<T> {
    public void save(T t) ;    
    public void update(T t) ;
    public void delete(int id) ;
    public T get(int id) ;
    public List<T> query();
}
8.4 在实现以上接口的时候那么此时的CategoryService就需要修改了。
    CategoryService.java
public interface CategoryService extends BaseService<Category>{

}

8.5 在实现了公共方法的提取后,还可以对方法的具体操作实现进行抽取。此时就通过类级别的抽取实现了
    BaseServiceImpl.java

public class BaseServiceImpl<T> implements BaseService<T> {
    private Class clazz ; //当前操作的类型
    private SessionFactory sessionFactory ;    

    public BaseServiceImpl(){
        System.out.println("当前调用构造方法的对象:"+this) ;
        System.out.println("当前对象的父类信息:"+this.getClass().getSuperclass()) ;
        System.out.println("当前对象的父类信息(包括泛型信息):"+this.getClass().getGenericSuperclass()) ;
    }

    protected void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    protected Session getSession(){ 
        //从当前线程获取session,如果没有则创建一个session
        return sessionFactory.getCurrentSession() ;
    }
    public void save(T t) {
        getSession().save(t) ;
    }
    public void update(T t) {
        getSession().update(t);
    }
    public void delete(int id) {
        String qhl = "DELETE "+clazz.getSimpleName()+" WHERE id=:id" ;
        getSession().createQuery(qhl).setInteger("id",id).executeUpdate() ;
    }
    public T get(int id) {
        return (T)getSession().get(clazz,id) ;
    }
    public List<T> query() {
        String hql = "FROM "+clazz.getSimpleName();
        return getSession().createQuery(hql).list();
    }
}

8.6 现在重新定义
    CategoryServiceImpl.java
public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService {
 public CategoryServiceImpl(){
  super() ;
 }
 /*public static void main(String args[]){
  new CategoryServiceImpl() ;
 }*/
}
8.7 现在需要为BaseServiceImpl配置
    applicationService-service.xml
<bean id="baseService" class="cn.it.shop.service.impl.BaseServiceImpl">
            <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="categoryService" class="cn.it.shop.service.impl.CategoryServiceImpl" parent="baseService"/>

8.8 在SSHTest中再次启动JUnit测试,出现了一个异常
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseService' defined in file [G:\zz\undone_other\project\大头娃\shop\WebRoot\WEB-INF\classes\applicationContext-service.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [cn.it.shop.service.impl.BaseServiceImpl]: Constructor threw exception; nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

8.9 经过分析是BaseServiceImpl不能实例化,因为它是泛型,所以要修改 
    applicationService-service.xml
<bean id="baseService" class="cn.it.shop.service.impl.BaseServiceImpl" lazy-init="true">

8.10 再经过JUnit测试就可以通过了
8.11 完成以上步骤后,CategoryServiceImpl就基本完成了所需的功能,现在就在它上面建立一个测试类
8.12 
      CategoryServiceImplTest.java

package cn.it;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import cn.it.shop.service.CategoryService;

@RunWith(SpringJUnit4ClassRunner.class)    
@ContextConfiguration(locations="classpath:applicationContext-*.xml")    //找到spring的配置文件
public class CategoryServiceImplTest {
    @Resource 
    private CategoryService categoryService ;
    @Test
    public void testSave() {
        categoryService.save(new Category("测试一下",true));
    }

    @Test
    public void testUpdate() {
        categoryService.update(new Category(3,"测试3",true));
    }

    @Test
    public void testDelete() {
        categoryService.delete(2);
    }

    @Test
    public void testGet() {
        System.out.println(categoryService.get(3)); 
    }

    @Test
    public void testQuery() {

        for(Category c:categoryService.query()){
            System.out.println(c) ;
        }
    }

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: