web工程中DAO层CRUD的简化操作

在ssh框架中,在dao层一些简单重复的操作一般都要让接口的实现类去继承HibernateDaoSupport这个类,然后去做相应的CRUD操作,这样就会使代码看起来很臃肿.

例如下面的代码:

package ssh.DAO;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import ssh.domain.User;
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

	
	@Override
	public void add(User user) {
		this.getHibernateTemplate().save(user);
		
	}

	@Override
	public void update(User user) {
		this.getHibernateTemplate().update(user);
		
	}

	@Override
	public void del(User user) {
		this.getHibernateTemplate().delete(user);
		
	}

	@Override
	public User findById(int id) {
		return this.getHibernateTemplate().get(User.class, id);
		
	}

}

下面介绍一种简化的操作,让代码看起来更优雅一点:

第一步:我们可以定义一个BaseDao接口:

在这个接口里就可以去定义一些基本的CRUD的操作.

package ssh.DAO;

import java.io.Serializable;

public interface BaseDao<T> {
	public void add(T o);

	public void update(T o);

	public void delete(T o);

	public T findById(Serializable id);

}

第二步:写一个BaseDao的实现类,让实现类去重写里面的方法,并且让他去继承HibernateDaoSupport,然后这里面完成CRUD等对数据的简单的操作.

package ssh.DAO;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

@SuppressWarnings("all")
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {

    //这个地方把clazz写成成员变量,是为了下面方法在传递参数的时候不用写calzz,可以少写一个参数.
    private Class<T> clazz;
    
    
    public BaseDaoImpl() {
        ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        clazz = (Class<T>) type.getActualTypeArguments()[0];
    }


    @Override
    public void add(T o) {
        this.getHibernateTemplate().save(o);
    }

    @Override
    public void delete(T o) {
        this.getHibernateTemplate().delete(o);
    }

    @Override
    public void update(T o) {
        this.getHibernateTemplate().update(o);
    }

    @Override
    public T findById(Serializable id) {
        return this.getHibernateTemplate().get(clazz, id);
    }

}

/*
	 * 1:关于this :this表示谁去调用本类,例如,下面的UserDaoImpl就继承了这个类,那么这个this指的就是UserDaoImpl.
	 * 2:关于getGenericSuperclass : getGenericSuperclass是获取带有泛型的父类,例如:this是UserDaoImpl,
	 * 那么他就继承了BaseDaoImpl<User>这个类,那么得到的就是BaseDaoImpl<User>.这个方法返回的是Type.
	 * 3:关于Type :Type是 Java编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型.
	 * 4:关于ParameterizedType :他是指参数化类型,也就是泛型.
	 * 5:关于getActualTypeArguments :是用来获取参数化类型的数组,因为泛型可能会有多个,例如Map<XXX,XXX>.这个地方[0]表示获取第一个.
	 * 
	 * */
解释说明: 在这里引用泛型是为了解决通用性的问题.如果在参数上面写的是Object,那么每一个方法调取时都要去写参数,而引入泛型以后在调方法的时候就可以不用写参数,只用在类名后面加上需要查找的信息的泛型就可以了.如果我有很多的模块都需要去做CRUD的相关操作,那么我只用让该模块去继承这个类,然后加上泛型,下面的CRUD等简单的操作就不用去管了.

第三步:让具体的模块去继承这个类

package ssh.DAO;

import ssh.domain.User;

public interface UserDao extends BaseDao<User> {

}	
package ssh.DAO;

import ssh.domain.User;

public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {

}

这样写的好处在于,如果你有多个模块,那么只用做上面两个代码块里面的内容就可以了,需要修改的仅仅只是泛型,减少了很大的工作量.

如果增加一个模块:

package ssh.dao;


import com.itheima.domain.Product;


public interface ProductDao extends BaseDao<Product> {


}
package ssh.dao;

import com.itheima.domain.Product;

public class ProductDaoImpl extends BaseDaoImpl<Product> implements ProductDao {

}

对于上面的代码内容只修改了泛型,别的基本都相同.

第四步:编写测试类

package ssh.test;

import javax.annotation.Resource;

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

import ssh.DAO.UserDao;
import ssh.domain.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserServiceImplTest {	
	@Resource
	UserDao userDao;

	
	@Test
	public void test1() {
		User user = userDao.findById(1);
		System.out.println(user);
	}
	
}

测试结果:

User [id=1, name=tom, age=19]

至此:dao层简单的CRUD等操作的抽取就已经完成.需要理解的是泛型的用处以及这种抽取的思想.

很大程度上简化了我们代码的重复性.







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值