反射机制指的是程序在运行时可以获取自身的信息。在java中,只要给定类的名字,
那么就能够经过反射机制来得到类的全部信息。java
反射机制建立类对象sql
Class c=Class.forName("className");注明:className必须为全名,也就是得包含包名,好比,com.cnblog.Bean;
Object obj=c.newInstance();//建立对象的实例数据库
有了类对象就能够对该类的方法及属性进行操做 app
能够对全部单表的增删查改,无需新建对应的DAO文件,即新增表操做的的时候,只须要创建表的对应的javabean便可,无需新建表的DAO文件ide
链接数据库的类 DBConnection.java测试
DAO的实现类 DAOImpl.javaui
DAO的代理类 DAOProxy.javathis
各个表的beanurl
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(); } }
query() 传入的bean不须要每一个属性都赋值,筛选已赋值的属性拼装sql,筛选的时候利用反射机制中的反射属性Field[] fields =object.getClass().getFields()spa
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; } }
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; } }
创建对应的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; } }
测试代码
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);
}