利用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);

}

 

posted @ 2017-05-04 18:21  老乌鸡  阅读(471)  评论(0编辑  收藏  举报