SSH实战OA 03:设计BaseDAo
来源:互联网 发布:哪个软件有天九牌游戏 编辑:程序博客网 时间:2024/06/05 19:15
上一节已经把项目的框架环境搭建起来了。并且做了简单的测试,这一节我们主要来设计Dao共用类的。在做这项工作之前我们先来看一个问题:在开发的过程中,我们发现DAO层的主要作用就是对数据库进行增删改查。例如有用户管理、部门管理、角色管理、文章管理这四个模块:
他们各自具有方法如下:
这四个Dao类的主要作用是对数据中相对应的表进行增删改查操作,这时候为了避免重复操作,可以将他们的基本操作方法提取出来作为一个基础类的共有方法。
类的模型如图:
基于Java的单继承多现实原理,我们可以设计一个通用的BaseDao接口,他包含了save(),delete(),updae(),getById(),getByIds(),findAll()等共用的方法,这个Dao有一个基本的实现类BaseDaoImpl,对这个共用接口所有的方法实现。User对应的dao实现类可以继承BaseDaoImpl也同时实现了UserDao接口,Role对应的Dao实现类可以也可以继承BaseDaoImpl同时可以实现了RoleDao的接口。共用的方法放在BaseDao接口里面,实体对应的个体的独特方法放在自己的接口里面,这样便减少重复工作量!
BaseDao:
import java.util.List;/** * 泛型接口 * @author shizongger * @param <T> */public interface BaseDao<T> { public void add(T entity); public void delete(Long id); public void update(T entity); public T selectById(Long id); public List<T> selectAll();}
BaseDaoImpl:
import java.lang.reflect.ParameterizedType;import java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import com.shizongger.oa.domain.User;/** * @author shizongger * @param <T> 实际操作的daomain实体 */public abstract class BaseDaoImpl<T> implements BaseDao<T> { private Log log = LogFactory.getLog(this.getClass()); /** * sessionFactory工厂 */ @Autowired private SessionFactory sessionFactory; private Class<T> clazz; @SuppressWarnings("unchecked") public BaseDaoImpl() { // 使用反射技术得到T的真实类型 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型 this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型 } /** * 增加 */ @Override public void add(T entity) { log.info("add:" + entity.toString()); getSession().save(entity); } /** * 删除 */ @Override public void delete(Long id) { Object object = selectById(id); if(object != null) { getSession().delete(object); } } /** * 修改 */ @Override public void update(T entity) { getSession().update(entity); } /** * 根据id查询 */ @Override public T selectById(Long id) { return (T) getSession().get(this.clazz, id); } /** * 根据id数组查询 */ @Override public List<T> selectAll() { List<T> list = getSession().createQuery("FROM " + this.clazz.getSimpleName()).list(); return list; } protected Session getSession() { return sessionFactory.getCurrentSession(); }}
由于共有类无法判断具体的实体,只能使用泛型,在调用过程中具体传递进来的实体类型是什么类型需要用java反射机制来实现。关键代码在我们的构造方法中的这两行代码:
// 使用反射技术得到T的真实类型ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取当前new的对象的 泛型的父类 类型this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; // 获取第一个类型参数的真实类型
本类中多次用到hibernate的session,所以直接把获取session做成一个protected级别的方法。为了更好的给子类继承使用该方法,不宜写为private私有级别。
protected Session getSession() { return sessionFactory.getCurrentSession(); }
这里需要注意的是:基础实现类不能new,只能new他的子类,所以这里要写abstract抽象类型。
如此便可以在不同模块的Dao调用这个公共类了。
用户增删改查对应的UserDao接口
import com.shizongger.oa.base.BaseDao;import com.shizongger.oa.domain.User;public interface UserDao extends BaseDao<User> { public User getUserByNamdAndPasswd(String username, String password);}
userDaoImpl实现类
import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;import com.shizongger.oa.base.BaseDaoImpl;import com.shizongger.oa.dao.UserDao;import com.shizongger.oa.domain.User;@Repositorypublic class UserDaoImpl extends BaseDaoImpl<User> implements UserDao { private Log log = LogFactory.getLog(this.getClass()); /** * sessionFactory工厂 */ @Autowired private SessionFactory sessionFactory; /** * 检测用户的合法性 */ @Override public User getUserByNamdAndPasswd(String username, String password) { Session session = sessionFactory.getCurrentSession(); String hql = "FROM User WHERE loginName = ? AND password = ?"; User user = (User) session.createQuery(hql).setString(0, username) .setString(1, password).uniqueResult(); return user; }}
部门管理增删改查对应的接口DepartmentDao
import java.util.List;import com.shizongger.oa.base.BaseDao;import com.shizongger.oa.domain.Department;public interface DepartmentDao extends BaseDao<Department> { List<Department> findTopDept(); List<Department> findChildren(String parentId);}
DepartmentDaoImpl实现类
import java.util.List;import com.shizongger.oa.base.BaseDao;import com.shizongger.oa.domain.Department;public interface DepartmentDao extends BaseDao<Department> { List<Department> findTopDept(); List<Department> findChildren(String parentId);}
下面我们来进行junit测试:
BaseJunitTest
import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath*:*.xml"}) public class BaseJunitTest { }
UserDaoImplTest
import static org.junit.Assert.*;import java.util.List;import org.junit.Ignore;import org.junit.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.annotation.Rollback;import org.springframework.transaction.annotation.Transactional;import com.shizongger.oa.base.BaseJunitTest;import com.shizongger.oa.dao.UserDao;import com.shizongger.oa.domain.User;public class UserDaoImplTest extends BaseJunitTest { @Autowired private UserDao userDao; @Test @Ignore public void testGetUserByNamdAndPasswd() throws Exception { //TODO } @Transactional @Test @Rollback(false) public void testAddUser() throws Exception { User user = new User(); user.setName("shizongger"); userDao.add(user); } @Transactional @Test @Rollback(false) public void testDelete() throws Exception { userDao.delete(6L); } @Transactional @Test @Rollback(false) public void testUpdate() throws Exception { User user = (User) userDao.selectById(7L); if(user != null) { user.setName("admin"); userDao.update(user); } } @Transactional @Test public void testSelectAll() throws Exception { List<User> list = userDao.selectAll(); for(final User user : list) { System.out.println("id:" + user.getId() + ", name:" + user.getName()); } }}
我们发现调用到BaseDaoImpl的构造方法是,正确的输出了我们传递过去的javaBean类型。
项目代码托管到了GitHub,OA
- SSH实战OA 03:设计BaseDAo
- OA中BaseDao抽象设计思路梳理
- SSH实战OA 02:SSH框架搭建
- SSH实战OA 01:项目说明
- SSH实战OA 05:Struts2标签
- SSH实战OA 11:BBS模块
- BaseDao设计
- SSH BaseDao代码
- ssh框架中的basedao
- SSH抽取BaseDao
- SSH实战OA 04:Struts2的OGNL表达式
- 通用BaseDao设计
- BaseDao接口设计
- BaseDao的设计思路
- 万能的BaseDao设计
- BaseDao设计思路
- SSH中baseDao的写法
- ssh中的BaseDao与BaseAction
- 趁着我还清醒的时候来一发感想
- 2
- saltstack 数据系统——Grains和pillar
- java与javascript语法区别
- citymaker学习资源
- SSH实战OA 03:设计BaseDAo
- php学习笔记
- L1-042日期格式化
- 解决Discus!x3.1论坛安装插件提示无法运行通过zend加密应用
- QT SQL总结-----/*自己编写*/
- PDO数据连接持久化性能测试
- springMVC + easyui + $.ajaxFileUpload实现文件上传注意事项
- Handler的运行机制
- Pandas——ix vs loc vs iloc区别