`
yifeng
  • 浏览: 51479 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用Java Generics简化数据库存取类DAO开发

阅读更多

本文介绍怎么样使用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特性的情况要复杂多了。

分享到:
评论

相关推荐

    毕业设计MATLAB_执行一维相同大小矩阵的QR分解.zip

    毕业设计matlab

    ipython-7.9.0.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    debugpy-1.0.0b3-cp37-cp37m-manylinux2010_x86_64.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    libaacs-devel-0.10.0-1.mga8.i586.rpm

    rpm -i xx.rpm 只要报错遇到aacs的可以看看架构是否一致

    几个ACM算法pdf.zip

    [ACM国际大学生程序设计竞赛题解].pdf ACM模板-清华大学.pdf ACM算法模板(吉林大学).pdf

    MATLAB设计_计算局部曲率半径,累积弧长和曲率矢量.zip

    毕业设计MATLAB

    毕业设计MATLAB_井字游戏.zip

    毕业设计MATLAB

    libaacs0-0.6.0-1.fc20.x86_64.rpm

    aacs0报错安装 rpm -i xx.rpm 注意架构是否正确

    tmp_19b6232387278d59a1d3d17a373e5c87ee48ea636933c4e400aab98fb353f32d.unknown

    tmp_19b6232387278d59a1d3d17a373e5c87ee48ea636933c4e400aab98fb353f32d.unknown

    2024年软考软件设计师的复习资料

    2024软考软件设计师

    grpcio-1.60.1-cp37-cp37m-manylinux_2_17_aarch64.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    毕业设计MATLAB_线性和非线性方程的迭代方法.zip.temp

    毕业设计matlab

    grpcio-1.60.0-cp38-cp38-manylinux_2_17_aarch64.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    mysql8.0.11驱动包,兼容支持MySQL 5.5, 5.6, 5.7,8.0各个版本.zip

    mysql8.0.11驱动包,兼容支持MySQL 5.5, 5.6, 5.7,8.0各个版本

    基于vant, vue, axios, vuex的移动端项目开发仿小米商场移动端项目软件源代码.zip

    基于vant, vue, axios, vuex的移动端项目开发,仿小米商场移动端项目软件源代码,较为简单的基于vant, vue, axios, vuex的移动端项目, 仿小米商场移动端项目, 有基本的页面和假数据, 适合作为电商项目的启动模板或者用作学生毕设学习使用。

    grpcio-1.48.2-cp36-cp36m-musllinux_1_1_i686.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    grpcio-1.3.5-cp36-cp36m-manylinux1_i686.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    前端项目《基于Uni-app + Node的音乐听歌系统设计与实现》

    ### 基于 Uni-app + Node 的音乐听歌系统设计与实现 #### 资源概述 本资源提供了一份完整的前端项目设计与实现文档,详细介绍了基于 Uni-app 和 Node.js 构建的音乐听歌系统的设计思路、技术实现和项目源码。该资源包含项目背景、需求分析、系统设计、技术栈选型、核心功能实现、测试与部署等方面的内容,旨在帮助开发者快速掌握 Uni-app 和 Node.js 的开发技巧,打造一个功能完备、体验流畅的音乐听歌平台。 #### 资源内容 1. **项目背景与需求分析**: - 介绍音乐听歌系统的行业背景和用户需求,分析当前市场上音乐应用的特点和痛点。 - 详细描述系统的功能需求,包括用户管理、音乐搜索、播放控制、播放列表管理、用户收藏、音乐推荐等。 2. **系统设计**: - **总体架构设计**:介绍系统的整体架构,包括前端(Uni-app)、后端(Node.js)和数据库(MongoDB)部分,采用前后端分离的开发模式。 - **功能模块设计**:详细描述各个功能模块的设计,包括用户模块、音乐模块、播放模块、推荐模块等。每个

    libaacs-devel-0.11.0-5.el9.ppc64le.rpm

    rpm -i xx.rpm 只要报错遇到aacs的可以看看架构是否一致

    MATLAB设计_对多维数据执行多项式回归.zip

    毕业设计MATLAB

Global site tag (gtag.js) - Google Analytics