本文介紹怎么樣使用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());
}
}
} |
我們注意到IUserDao.java與UserDao.java的實現比使用Java Generics特性的情況要復雜多了。
posted on 2008-08-24 05:39
憶風 閱讀(412)
評論(0) 編輯 收藏 所屬分類:
Java SE