zoukankan      html  css  js  c++  java
  • Java通过代理类实现数据库DAO操作

    下面的所有代码示例都取自李兴华的《Java Web开发实战经典》的随书源码,因为觉得设计得很好,所以将代码摘录下来作成笔记。

    首先,我们在一个java文件中定义要存储的结构类型:

    import java.util.Date ;
    /**
     *
     * @author Nero
     */
    public class Emp {
        private int empno ;
        private String ename ;
        private String job ;
        private Date hiredate ;
        private float sal ;
        public void setEmpno(int empno){
            this.empno = empno ;
        }
        public void setEname(String ename){
            this.ename = ename ;
        }
        public void setJob(String job){
            this.job = job ;
        }
        public void setHiredate(Date hiredate){
            this.hiredate = hiredate ;
        }
        public void setSal(float sal){
            this.sal = sal ;
        }
        public int getEmpno(){
            return this.empno ;
        }
        public String getEname(){
            return this.ename ;
        }
        public String getJob(){
            return this.job ;
        }
        public Date getHiredate(){
            return this.hiredate ;
        }
        public float getSal(){
            return this.sal ;
        }
    }

    下面我们定义一个数据库连接类,负责向数据库发起连接。java连接数据库需要驱动包,我们可以自行下载,测试的时候我使用的是mysql-connector-java-5.0.5-bin.jar。在运行程序的时候Eclipse会提示需要加载的数据库驱动包,一些是类似于"org.gjt.mm.mysql.Driver" 之类的标准包,一般来说我们选择工作目录里的驱动包就可以了。

    import java.sql.Connection ;
    import java.sql.DriverManager ;
    /**
     *
     * @author Nero
     */
    public class DatabaseConnection {
        private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ; 
        private static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ;
        private static final String DBUSER = "root" ;
        private static final String DBPASSWORD = "root" ;
        private Connection conn ;
        public DatabaseConnection() throws Exception {
            Class.forName(DBDRIVER) ;
            this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;
        }
        public Connection getConnection(){
            return this.conn ;
        }
        public void close() throws Exception {
            if(this.conn != null){
                try{
                    this.conn.close() ;
                }catch(Exception e){
                    throw e ;
                }
            }
        }
    }

    接下来我们定义一个接口,这个接口能够帮助我们轻松地实现代理方法。接口内的方法只有三个:插入、查找全部和通过ID查找。

    import java.util.* ;
    
    /**
     *
     * @author Nero
     */
    public interface IEmpDAO {
        public boolean doCreate(Emp emp) throws Exception ;
        public List<Emp> findAll(String keyWord) throws Exception ;
        public Emp findById(int empno) throws Exception ;
    }

    然后呢,我们继承这个接口,实现具体数据库的操作类,都是一些很基本的数据库操作,没啥好说的。主要要注意的是构造函数那里,参数使用Connection对象,后面使用这个类的时候要传入前面定义的数据库连接类DatabaseConnection中的函数getConnection()返回的Connection对象。

    import java.sql.* ;
    /**
     *
     * @author Nero
     */
    public class EmpDAOImpl implements IEmpDAO{
        private Connection conn = null ;
        private PreparedStatement pstmt = null ;
        public EmpDAOImpl(Connection conn)
        {
            this.conn = conn;
        }
        public boolean doCreate(Emp emp) throws Exception{
            boolean flag = false;
            String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) VALUES(?,?,?,?,?)";
            this.pstmt = this.conn.prepareStatement(sql);
            this.pstmt.setInt(1, emp.getEmpno());
            this.pstmt.setString(2,emp.getEname()) ;
        this.pstmt.setString(3,emp.getJob()) ;
        this.pstmt.setDate(4,new java.sql.Date(emp.getHiredate().getTime())) ;
        this.pstmt.setFloat(5,emp.getSal()) ;
            if(this.pstmt.executeUpdate() > 0)
            {
                flag = true;
            }
            this.pstmt.close();
            return flag;
        }
        public List<Emp> findAll(String keyWord) throws Exception{
            List<Emp> all = new ArrayList<Emp>();
            String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE ename LIKE ? OR job LIKE ?";
            this.pstmt = this.conn.prepareStatement(sql);
            this.pstmt.setString(1,"%"+keyWord+"%"); //转义字符
            this.pstmt.setString(2,"%"+keyWord+"%");
            ResultSet rs = this.pstmt.executeQuery(sql);
            Emp emp = null;
            while(rs.next())
            {
                emp = new Emp();
                emp.setEmpno(rs.getInt(1));
                emp.setEname(rs.getString(2)) ;
            emp.setJob(rs.getString(3)) ;
            emp.setHiredate(rs.getDate(4)) ;
            emp.setSal(rs.getFloat(5)) ;
                all.add(emp);
            }
            this.pstmt.close();
            return all;
        }
        public Emp findById(int empno) throws Exception{
            Emp emp = null ;
            String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?" ;
            this.pstmt = this.conn.prepareStatement(sql) ;
            this.pstmt.setInt(1,empno) ;
            ResultSet rs = this.pstmt.executeQuery() ;
            if(rs.next()){
                emp = new Emp() ;
                emp.setEmpno(rs.getInt(1)) ;
                emp.setEname(rs.getString(2)) ;
                emp.setJob(rs.getString(3)) ;
                emp.setHiredate(rs.getDate(4)) ;
                emp.setSal(rs.getFloat(5)) ;
            }
            this.pstmt.close() ;
            return emp ;
        }    
    }

    下面我们看看代理类的实现,个人觉得到这里就比较有意思了。在这个类里面,声明了一个数据库连接类DatabaseConnection的对象,一个数据库应用类EmpDAOImpl对象,用DatabaseConnection对象初始化EmpDAOImpl对象,然后在代理类的每个函数中都使用EmpDAOImpl对象去调用从同一接口继承而来的方法,这样即对具体实现方法进行了一定程度的隐藏。

    import java.sql.* ;
    /**
     *
     * @author Nero
     */
    public class EmpDAOProxy implements IEmpDAO{
        private DatabaseConnection dbc = null ;
        private EmpDAOImpl dao = null ;
        public EmpDAOProxy() throws Exception{
            this.dbc = new DatabaseConnection();
            this.dao = new EmpDAOImpl(this.dbc.getConnection());
        }
        public boolean doCreate(Emp emp) throws Exception{
            boolean flag = false;
            try{
                if(this.dao.findById(emp.getEmpno()) == null)
                {
                    flag = this.dao.doCreate(emp);
                    
                }
            }catch(Exception e)
            {
                throw e;
            }finally{
                this.dbc.close();
            }
            return flag;
        }
        public List<Emp> findAll(String keyWord) throws Exception{
            List<Emp> all = null ;
            try{
                all = this.dao.findAll(keyWord) ;
            }catch(Exception e){
                throw e ;
            }finally{
                this.dbc.close() ;
            }
            return all ;
        }
        public Emp findById(int empno) throws Exception{
            Emp emp = null ;
            try{
                emp = this.dao.findById(empno) ;
            }catch(Exception e){
                throw e ;
            }finally{
                this.dbc.close() ;
            }
            return emp ;
        }
    }

    这还不是全部,我们可以再加一个工厂类来实现工厂模式:

    /**
     *
     * @author Nero
     */
    public class DAOFactory {
        public static IEmpDAO getIEmpDAOInstance() throws Exception{
            return new EmpDAOProxy() ;
        }
    }

    这个工厂类有什么用呢?最后我们在主类文件中进行调用,可以看看工厂类有什么作用:

    /**
     *
     * @author Nero
     */
    public class TestDAOInsert {
        public static void main(String args[]) throws Exception{
            Emp emp = null ;
            for(int x=0;x<5;x++){
                emp = new Emp() ;
                emp.setEmpno(1000 + x) ;
                emp.setEname("中文显示测试 - " + x) ;
                emp.setJob("程序员 - " + x) ;
                emp.setHiredate(new java.util.Date()) ;
                emp.setSal(500 * x) ;
                DAOFactory.getIEmpDAOInstance().doCreate(emp) ;
            }
        }
    }

    可见具体的实现方法隐藏得比较好,通过工厂类调用get方法获取代理类,代理类调用特定方法,然后由代理类内的具体操作对象去调用具体的操作方法。

    其实这些东西看起来会觉得很简单,但是自己设计的时候往往会忘记。主要是因为用得不多吧,一开始总是要强迫自己想起来去做,然后慢慢地才能变成一种习惯。

  • 相关阅读:
    ArcGIS Pro 简明教程(2)基础操作和简单制图
    ArcGIS Pro 简明教程(1)Pro简介
    ArcGIS Pro 简明教程(3)数据编辑
    LocaSpaceViewer深度讲解(一)瓦片服务与数据下载
    迭代最近点算法 Iterative Closest Points
    应用Fast ICP进行点集或曲面配准 算法解析
    八叉树-OcTree
    2016年10月校招体会
    静态代码块&非静态代码块&构造函数
    avtivity与view
  • 原文地址:https://www.cnblogs.com/nerohwang/p/3483707.html
Copyright © 2011-2022 走看看