本文介绍怎么样使用Java Generics来简化数据库存取类DAO的开发,并给出了一个完整的例子,大家可以把代码用在实际的开发应用中。 在系统开发中,为了降低耦合性,一般把跟数据库有关的操作封装在被叫做DAO(Dao Access Object)的类里。一般DAO的封装有以下几个原则: 1、一个表操作封装成一个DAO。例如:操作表User的DAO封装为UserDao.java,操作UserRole的DAO封装为UserRole.java等 2、具有良好的接口定义。为了使用简单以及不至于被错误调用,DAO接口必须有具体的型定义。例如:可以直接 User user = userDao.get(userId);取得指定userId的User,而不必进行强制类型转换 User user = (User)userDao.get(userId); [X] 为了避免误操作,userDao.delete(UserRole);应该在编译期就报错。 为了对DAO进行良好的封装,JDK1.5之前,DAO开发是一个大量重复代码的体力过程;JDK1.5开始引入了Generics概念,我们可以利用JDK1.5的Generics特性大大简化DAO开发。 Generics概念 Java的Generics就是Java的泛型,类似于C++的模板概念,Generics介绍起来比较复杂,简单说来,泛型从语言特性的底层上支持,可以让你为某些相似功能定义一个具有统一接口的通用模板,该模板可以接收任意类型并应用到类成员变量的类型,方法的参数类型,方法的返回值类型等;并可以在编译期支持类型的安全转换。举例说: java.util.List是一个泛型,一个定义为List<User> userList;的变量userList,可以通过User user = userList.get(0);便可直接得到User,不用经过类型的强制转换了。 Generics更详细的介绍请参考相关文章,这里不做详述。 下面举例我们给出2种DAO的封装方法,一种是不使用Java Generics特性的一般封装方法;一种是使用泛型的封装方法。通过比较,我们会发现Java的Generics特性到底为我们简化了哪些工作。 使用Java Generics特性封装DAO文件名 | 说明 |
---|
IDao.java | dao的顶层抽象接口 | AbstractDao.java | IDao的实现类,实现了get/update/delete等基本操作 | User.java | USER表对应的entity定义 | IUserDao.java | USER表操作DAO接口定义 | UserDao.java | USER表操作DAO实现 | HelloGenerics.java | 测试类 |
IDao.java // super dao interface public interface IDao <T, PK extends Serializable> { public T get(PK pk); public List <T>getAll(); public PK save(T entity); public void update(T entity); public void saveOrUpdate(T entity); public void delete(T entity); } |
AbstractDao.java //super abstract dao class public abstract class AbstractDao <T, PK extends Serializable>implements IDao<T, PK> { private Class clz; public AbstractDao(Class clz) { this.clz = clz; } public T get(PK pk) { return (T)getSession().get(clz, pk); } public List <T>getAll() { return getSession().createCriteria(clz).list(); } public PK save(T entity) { return (PK)getSession().save(entity); } public void update(T entity) { getSession().update(entity); } public void saveOrUpdate(T entity) { getSession().saveOrUpdate(entity); } public void delete(T entity) { getSession().delete(entity); } private Session session; protected Session getSession() { //wrap session in a class such as HibernateUtils, then you can use HibernateUtils.getCurrentSession() for getting a session. return session; } } |
User.java //persist entity public class User { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } //... setter/getter HERE } |
IUserDao.java //User Dao interface public interface IUserDao extends IDao <User, String> { // all are empty } |
UserDao.java //UserDao Implementation public class UserDao extends AbstractDao <User, String> implements IUserDao { public UserDao() { super(User.class); } // or use the following constructor //public UserDao(Class<User> type) { // super(type); //} } |
HelloGenerics.java public class HelloGenerics {
public static void main(String[] args) { IUserDao userDao = new UserDao(); User user = userDao.get("1"); if (user != null) { System.out.println(user.getName()); } List<User> userList = userDao.getAll(); for (User u:userList) { System.out.println(user.getName()); } } } |
我们可以看到IUserDao.java与UserDao.java非常简单。 不使用Java Generics特性DAO的封装同样,我们给出不使用Java Generics特性DAO的封装。该封装也是一个具有良好结构性的封装。 文件列表2: 文件名 | 说明 |
---|
DaoUtils.java | dao通用工具类,提供get/update/delete等基本操作 | User.java | USER表对应的entity定义 | IUserDao.java | USER表操作DAO接口定义 | UserDao.java | USER表操作DAO实现 | HelloGenerics.java | 测试类 |
DaoUtils.java public class DaoUtils { public static Object get(Class clz, Serializable pk) { return getSession().get(clz, pk); } public static List getAll(Class clz) { return getSession().createCriteria(clz).list(); } public static Serializable save(Object entity) { return getSession().save(entity); } public static void update(Object entity) { getSession().update(entity); } public static void saveOrUpdate(Object entity) { getSession().saveOrUpdate(entity); } public static void delete(Object entity) { getSession().delete(entity); } private static Session session; protected static Session getSession() { //wrap session in a class such as HibernateUtils, then you can use HibernateUtils.getCurrentSession() for getting a session. return session; } } |
User.java //persist entity public class User { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } //... setter/getter HERE } |
IUserDao.java //User Dao interface public interface IUserDao { public User get(String pk); public List getAll(); public String save(User entity); public void update(User entity); public void saveOrUpdate(User entity); public void delete(User entity); } |
UserDao.java //UserDao Implementation public class UserDao implements IUserDao {
public User get(String pk) { return (User)DaoUtils.get(User.class, pk); } public List getAll() { return DaoUtils.getAll(User.class); }
public String save(User entity) { return (String)DaoUtils.save(entity); }
public void update(User entity) { DaoUtils.update(entity); }
public void saveOrUpdate(User entity) { DaoUtils.saveOrUpdate(entity); }
public void delete(User entity) { DaoUtils.delete(entity); } } |
HelloGenerics.java public class HelloGenerics {
public static void main(String[] args) { IUserDao userDao = new UserDao(); User user = userDao.get("1"); if (user != null) { System.out.println(user.getName()); } List<User> userList = userDao.getAll(); for (User u:userList) { System.out.println(user.getName()); } } } |
|