zoukankan      html  css  js  c++  java
  • 利用JAVA反射机制设计通用的DAO

    利用JAVA反射机制设计一个通用的DAO

    反射机制

       反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,    
    那么就可以通过反射机制来获得类的所有信息。

       反射机制创建类对象

        Class c=Class.forName("className");注明:className必须为全名,也就是得包含包名,比如,com.cnblog.Bean;   
        Object obj=c.newInstance();//创建对象的实例

        有了类对象就可以对该类的方法及属性进行操作   

    通用DAO

        可以对所有单表的增删查改,无需新建对应的DAO文件,即新增表操作的的时候,只需要建立表的对应的javabean即可,无需新建表的DAO文件

    代码结构也比较简单

    连接数据库的类 DBConnection.java

    DAO的实现类 DAOImpl.java

    DAO的代理类 DAOProxy.java

    各个表的bean

    DBConnection.java 连接数据库的类

    package Utils;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    
    public class DBConnection {
    	private Connection conn;
    	private String url;
    	private String user;
    	private String password;
    	private String driver;
    	
    	
    	public String getUrl() {
    		return url;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    
    	public String getUser() {
    		return user;
    	}
    
    	public void setUser(String user) {
    		this.user = user;
    	}
    
    	public String getPassword() {
    		return password;
    	}
    
    	public void setPassword(String password) {
    		this.password = password;
    	}
    
    	public String getDriver() {
    		return driver;
    	}
    
    	public void setDriver(String driver) {
    		this.driver = driver;
    	}
    
    	public Connection connection()throws Exception{
    		try{
    			Class.forName(driver);
    		}catch(Exception e){
    			System.out.println("Load error!");
    			e.printStackTrace();
    		}
    	
    	    
    	    try{
    	    	conn=DriverManager.getConnection(url, user, password);
    	    }catch(Exception e){
    	    	System.out.println("Login error ,please check your login information");
    	    	e.printStackTrace();
    	    }
    	    
    	    return conn;
    		
    	}
    	
    	public void close() throws Exception{
    	
    		this.conn.close();
    		
    	}
    
    }
    

    DAOImpl.java  增删查改的实现类,所有的bean都作为Object进来,然后通过反射机制拼装数据库操作的sql

    query() 传入的bean不需要每个属性都赋值,筛选已赋值的属性拼装sql,筛选的时候利用反射机制中的反射属性Field[] fields =object.getClass().getFields()

    insert() 拼装sql时无需筛选未赋值的属性,未赋值的直接插入null

    update() 传入两个bean,第一个是更新前的记录,第二个是更新后的记录

    delete() 传入的bean不需要每个属性都赋值,筛选已赋值的属性拼装sql,筛选的时候利用反射机制中的反射属性Field[] fields =object.getClass().getFields()

    package DAO;
    
    import java.lang.reflect.Field;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    
    import Bean.*;
    import Utils.DBConnection;
    
    public class DAOImpl {
        
        private DBConnection dataSource;
        DAOImpl(DBConnection dataSource) throws Exception{
            this.dataSource=dataSource;    
        }
    
    
        
        public ArrayList<Object> query(Object object) throws Exception{
            Connection conn=null;
            PreparedStatement ps=null;
            ResultSet rs=null;
            ArrayList result=new ArrayList();
            //记录非空的属性值,用于SQL的变量绑定
            ArrayList args=new ArrayList();
            
            StringBuilder condition=new StringBuilder();
            String sql="select * from "+object.getClass().getSimpleName()+" where 1=1 ";
            
            //取出对象中的值作为条件,如果值为null则不加入查询条件中
            Field[] fields=object.getClass().getFields();
            for(Field field:fields){
                field.setAccessible(true);
                if(this.isBlank(field.get(object))==false){
                        condition.append(" and ").append(field.getName()).append("=").append("?");    
                        args.add(field.get(object));
                }
                
            }
            sql=sql+condition.toString();
    
            //访问数据库返回查询结果
            try{
            conn=dataSource.connection();
            ps=conn.prepareStatement(sql);
            for(int i=0;i<args.size();i++){
                //绑定变量下标从1开始
                ps.setObject(i+1, args.get(i));
            }
            rs=ps.executeQuery();
            
            //将查询结果放到bean中
            while(rs.next()){
                //利用反射机制新建bean实例
                String className=object.getClass().getName();
                Class<?> obj=Class.forName(className);
                Object resultBean=obj.newInstance();
                Field[] resultFields=resultBean.getClass().getFields();
                for(Field resultField:resultFields){
                    resultField.setAccessible(true);
                    resultField.set(resultBean, rs.getObject(resultField.getName()));
                }
                
                result.add(resultBean);
            }
            
            
            }catch(Exception e){
                System.out.println("Operation in database fail");
                e.printStackTrace();
            }finally{ 
                if(rs != null){   // 关闭记录集    
                try{    
                    rs.close() ;    
                }catch(SQLException e){    
                    e.printStackTrace() ;    
                }    
                  }    
                  if(ps != null){   // 关闭声明    
                try{    
                    ps.close() ;    
                }catch(SQLException e){    
                    e.printStackTrace() ;    
                }    
                  }    
                  if(conn != null){  // 关闭连接对象    
                 try{    
                    conn.close() ;    
                 }catch(SQLException e){    
                    e.printStackTrace() ;                
                 }                  
                  } }
            return result;
        }
        
        public boolean insert(Object object) throws Exception{
            boolean flag=false;
            Connection conn=null;
            PreparedStatement ps=null;
    
                    
            StringBuilder area=new StringBuilder("(");
            StringBuilder value=new StringBuilder("(");
            //获取Bean下所有的fields
            Field[] fields=object.getClass().getFields();
            //组装Sql
            String sql="insert into "+object.getClass().getSimpleName();
            
            for(int i=0 ;i<fields.length;i++){
                area.append(fields[i].getName());
                value.append("?");
                if(i<fields.length-1){
                    area.append(",");
                    value.append(",");
                }
            }
            
            area.append(")");
            value.append(")");
            
            sql=sql+area.toString()+" values "+value.toString();
            System.out.println(sql);
            
            try{
                conn=dataSource.connection();
                ps = conn.prepareStatement(sql);
            for(int i=0;i<fields.length;i++){
                fields[i].setAccessible(true);
                //setObject 下标 从1开始
                ps.setObject(i+1,fields[i].get(object));
                System.out.println(fields[i]);
            }
           if(ps.executeUpdate()>0){
               flag=true;
           }
           
            }catch(Exception e){
                System.out.println("Operation in database fail");
                e.printStackTrace();
            }finally{
                if(ps != null){   // 关闭声明    
                    try{    
                        ps.close() ;    
                    }catch(SQLException e){    
                        e.printStackTrace() ;    
                    }    
                      }    
                      if(conn != null){  // 关闭连接对象    
                     try{    
                        conn.close() ;    
                     }catch(SQLException e){    
                        e.printStackTrace() ;                
                     }                  
                      }
            }
          
         return flag;
        }
        
        public boolean update(Object previous,Object follow) throws Exception{
            boolean flag=false;
            Connection conn=null;
            PreparedStatement ps=null;
            ArrayList preArgs=new ArrayList();
            ArrayList folArgs=new ArrayList();
            
            
            //获取where条件的字段值
            Field[] preFields=previous.getClass().getFields();
            
            //获取set的字段值
            Field[] folFields=follow.getClass().getFields();
            
            StringBuilder set=new StringBuilder("");
            StringBuilder where=new StringBuilder("");
            
            String sql="update "+previous.getClass().getSimpleName()+" set 1=1";
            
            //组装sql语句
            for(Field folField:folFields){
                //如果bean中的属性值没有被set方法赋值过则不添加到sql语句的条件中
                if(this.isBlank(folField.get(follow))==false){
                        set.append(",").append(folField.getName()).append(" = ").append("?");
                        folArgs.add(folField.get(follow));
                
                }
            }
            
            sql=sql+set.toString()+" where 1=1 ";
            
            for(Field preField:preFields){
                if(this.isBlank(preField.get(previous))==false){
                    
                        where.append(" and ").append(preField.getName()).append(" = ").append("?");
                        preArgs.add(preField.get(previous));
                }
            }
            
            sql=sql+where.toString();
            System.out.println(sql);
            
            try{
                
                conn=dataSource.connection();
                ps=conn.prepareStatement(sql);
                //先绑定set部分的变量,然后再绑定where部分的变量
                for(int i=0;i<(folArgs.size()+preArgs.size());i++){
                    if(i<folArgs.size()){
                        ps.setObject(i+1, folArgs.get(i));
                    }else{
                        ps.setObject(i+1, preArgs.get(i-folArgs.size()));
                    }
                                    
                }
                if(ps.executeUpdate()>0){
                    flag=true;
                }
            }catch(Exception e){
                System.out.println("Operation in database fail");
                e.printStackTrace();
            }finally{
                if(ps != null){   // 关闭声明    
                    try{    
                        ps.close() ;    
                    }catch(SQLException e){    
                        e.printStackTrace() ;    
                    }    
                      }    
                      if(conn != null){  // 关闭连接对象    
                     try{    
                        conn.close() ;    
                     }catch(SQLException e){    
                        e.printStackTrace() ;                
                     }                  
                      }
            }
    
        return flag;
        }
        
        public boolean delete(Object object) throws Exception{
            boolean flag=false;
            Connection conn=null;
            PreparedStatement ps=null;
            ArrayList args=new ArrayList();
            
            
            //获取where条件的字段值
            Field[] fields=object.getClass().getFields();
            StringBuilder where=new StringBuilder("");
            
            //拼装sql
            String sql="delect from "+object.getClass().getSimpleName()+" where 1=1";
            
            for(Field field:fields){
                //如果属性值没有被set方法设置过,则不添加到条件进去
                if(this.isBlank(field.get(object))==false){
                    
                        where.append(" and ").append(field.getName()).append("=").append("?");
                        args.add(field.get(object));                
                }
            }
            
            sql=sql+where.toString();
            System.out.println(sql);
            
            try{
                conn=dataSource.connection();
                ps=conn.prepareStatement(sql);
                for(int i=0;i>args.size();i++){
                    //绑定变量下标从1开始
                    ps.setObject(i+1, args.get(i));
                }
                if(ps.executeUpdate()>0){
                    flag=true;
                }
            }catch(Exception e){
                System.out.println("Operation in database fail");
                e.printStackTrace();
            }finally{
                if(ps != null){   // 关闭声明    
                    try{    
                        ps.close() ;    
                    }catch(SQLException e){    
                        e.printStackTrace() ;    
                    }    
                      }    
                      if(conn != null){  // 关闭连接对象    
                     try{    
                        conn.close() ;    
                     }catch(SQLException e){    
                        e.printStackTrace() ;                
                     }                  
                      }
            }
            return flag;
        }
        
        /*
         * @description 判断bean属性值是否为空
         */
        public boolean isBlank(Object object){
            
            boolean flag;
            if(null==object||"".equals(object)){
                flag=true;
            }else{
                flag=false;
            }
                    
            return flag;
        }
        
        
    }
    View Code

    DAOProxy.java DAO的代理,DBConnection和DAOImpl的连接桥梁

    package DAO;
    
    import java.util.ArrayList;
    
    import Utils.DBConnection;
    
    public class DAOProxy {
        private DBConnection dataSource;
        DAOProxy(DBConnection dataSource){
            this.dataSource=dataSource;
            
        }
        
        public ArrayList doQuery(Object object)throws Exception{
            ArrayList result=new ArrayList();
            DAOImpl dao=new DAOImpl(dataSource);
            result=dao.query(object);
            return result;
        }
        
        public boolean doInsert(Object object)throws Exception{
            boolean result;
            DAOImpl dao=new DAOImpl(dataSource);
            result=dao.insert(object);
            return result;
        }
        
        public boolean doUpdate(Object previous,Object follow)throws Exception{
            boolean result;
            DAOImpl dao=new DAOImpl(dataSource);
            result=dao.update(previous,follow);
            return result;
            
        }
        
        public boolean doDelete(Object object)throws Exception{
            boolean result;
            DAOImpl dao=new DAOImpl(dataSource);
            result=dao.delete(object);
            return result;
        }
    
    }
    View Code

    Bean.java 数据库表对应的javabean

    建立对应的javabean时需要注意,属性类型最好不要用基本数据类型,因为这些数据类型会自动初始化,即int类型的属性默认是0,如果没有给该属性赋值,即插入到数据库的时候是0而不是空

    其中一个bean的例子

    package Bean;
    
    import java.math.BigDecimal;
    import java.util.Date;
    
    public class Employee {
        public BigDecimal emp_id;
        public String emp_name;
        public String emp_dep;
        public Date entry_time;
        public BigDecimal getEmp_id() {
            return emp_id;
        }
        public void setEmp_id(BigDecimal emp_id) {
            this.emp_id = emp_id;
        }
        public String getEmp_name() {
            return emp_name;
        }
        public void setEmp_name(String emp_name) {
            this.emp_name = emp_name;
        }
        public String getEmp_dep() {
            return emp_dep;
        }
        public void setEmp_dep(String emp_dep) {
            this.emp_dep = emp_dep;
        }
        public Date getEntry_time() {
            return entry_time;
        }
        public void setEntry_time(Date entry_time) {
            this.entry_time = entry_time;
        }
        
            
    
    }
    View Code

    测试代码

    public static void main(String[] args){

        //设置数据库连接
         DBConnection dbSource=new DBConnection();
        dbSource.setDriver(driver);
        dbSource.setUser(user);
        dbSource.setPassword(password);
        dbSource.setUrl(url);


        DAOProxy testDAO=new DAOProxy(dbSource)
        Employee jack=new Employee();
        jack.setEmp_id(123);
        jack.setEmp_name("jack");
        jack.setEmp_dep("dev");
        testDAO.doInsert(jack);
      
        Employee jack2=new Employee();
        jack2.setEmp_id(123);
        jack2.setEmp_name("jack");
        jack2.setEmp_dep("test");
        testDAO.doUpdate(jack, jack2);

    }

  • 相关阅读:
    关于Android的布局
    一个新的开端
    Flux的基础概念和实战入门
    在Redux中使用插件createAction之后
    学习
    Object.assign() 对象的扩展
    Redux 中的CombineReducer的函数详解
    React组件的防呆机制(propTypes)
    css的新特性 calc () 使用
    shim和polyfill有什么区别
  • 原文地址:https://www.cnblogs.com/wuqm/p/6808821.html
Copyright © 2011-2022 走看看