基于JDBC封装的BaseDao(实例代码)

 更新时间:2016年07月15日 09:32:56   投稿:jingxian  
下面小编就为大家带来一篇基于JDBC封装的BaseDao(实例代码)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

最近闲暇时萌发写一写dao的封装的例子,就将以前写的整理一下。

public class BaseDao<T> {

	Connection conn;
	PreparedStatement st;
	ResultSet rs;
	
	JdbcUtil jdbcUtil = new JdbcUtil();
	
	int result = 0;
	
	private Class<T> persistentClass;
	
	@SuppressWarnings("unchecked")
	public BaseDaoUtil(){		
		conn = jdbcUtil.getConnection();
		ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
		persistentClass = (Class<T>) type.getActualTypeArguments()[0];		
	}
	
	
  /**
   * 保存
    * @param entity
   * @return
   */
	public int save(T entity) throws Exception{
		
		String sql = "INSERT INTO "+ entity.getClass().getSimpleName().toLowerCase() +" (";
		
		List<Method> list = this.matchPojoMethods(entity,"get");
		
		Iterator<Method> iter = list.iterator();
			
		Object obj[] = new Object[list.size()];
		int i = 0;
		//拼接字段顺序 insert into table name(id,name,email,
         while(iter.hasNext()) {
            Method method = iter.next();
            sql += method.getName().substring(3).toLowerCase() + ","; 
            if (method.getReturnType().getSimpleName().indexOf("Date") !=-1) {
				SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				obj[i] = sbf.format(method.invoke(entity, new Object[]{}));
		   }else {
				obj[i] = method.invoke(entity, new Object[]{});
		   }     
      i++;
    }
    
    //去掉最后一个,符号insert insert into table name(id,name,email) values(
    sql = sql.substring(0, sql.lastIndexOf(",")) + ") values(";
    
    //拼装预编译SQL语句insert insert into table name(id,name,email) values(?,?,?,
    for(int j = 0; j < list.size(); j++) {
    	sql += "?,"; 
    }

    //去掉SQL语句最后一个,符号insert insert into table name(id,name,email) values(?,?,?);
    sql = sql.substring(0, sql.lastIndexOf(",")) + ")";
    
    //到此SQL语句拼接完成,打印SQL语句
    System.out.println(sql);
    
    try {
    	st = conn.prepareStatement(sql);
    	for (int j = 0; j < obj.length; j++) {
				st.setObject(j+1, obj[j]);
			}
			result = st.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
    
		jdbcUtil.getClose(rs, st, conn);
		
		return result;	
	}
	
	/**
	 * 删除
	 * @param object
	 * @return
	 * @throws SQLException
	 */
	public int deleteId(Object object) throws Exception{
		
		String sql = "delete from "+ persistentClass.getSimpleName().toLowerCase() +" where ";
		
		//通过子类的构造函数,获得参数化类型的具体类型.比如BaseDAO<T>也就是获得T的具体类型
    T entity = persistentClass.newInstance();
    
    //存放Pojo(或被操作表)主键的方法对象
    Method idMethod = null;
    
    List<Method> list = this.matchPojoMethods(entity, "set");
    Iterator<Method> iter = list.iterator();
    
    //过滤取得Method对象
    while(iter.hasNext()) {
      Method tempMethod = iter.next();
      if(tempMethod.getName().indexOf("Id") != -1 && tempMethod.getName().substring(3).length() == 2) {
        idMethod = tempMethod;
      } else if((entity.getClass().getSimpleName() + "Id").equalsIgnoreCase(tempMethod.getName().substring(3))){
        idMethod = tempMethod;
      }
    }
    //第一个字母转为小写
    sql += idMethod.getName().substring(3,4).toLowerCase()+idMethod.getName().substring(4) + " = ?";
    	
		System.out.println(sql);
		
		st = conn.prepareStatement(sql);
		
		//判断id的类型
    if(object instanceof Integer) {
      st.setInt(1, (Integer)object);
    } else if(object instanceof String){
      st.setString(1, (String)object);
    }
		
		result = st.executeUpdate();
		
		jdbcUtil.getClose(rs, st, conn);
		
		return result;	
	}
	
	/**
	 * 修改
	 * @param entity
	 * @return
	 * @throws Exception
	 */
	public int update(T entity) throws Exception{
		
		String sql = "update "+ entity.getClass().getSimpleName().toLowerCase() +" set ";
		
		List<Method> list = this.matchPojoMethods(entity, "get");
		
		//装载参数
		Object obj[] = new Object[list.size()];
		int i = 0;
		
		//临时Method对象,负责迭代时装method对象.
    Method tempMethod = null;
    
    //由于修改时不需要修改ID,所以按顺序加参数则应该把Id移到最后.
    Method idMethod = null;
    Iterator<Method> iter = list.iterator();
    while(iter.hasNext()) {
      tempMethod = iter.next();
 
      //如果方法名中带有ID字符串并且长度为2,则视为ID.
      if(tempMethod.getName().lastIndexOf("Id") != -1 && tempMethod.getName().substring(3).length() == 2) {
      	obj[list.size()-1] = tempMethod.invoke(entity, new Object[]{});
        //把ID字段的对象存放到一个变量中,然后在集合中删掉.
        idMethod = tempMethod;
        iter.remove();
      //如果方法名去掉set/get字符串以后与pojo + "id"想符合(大小写不敏感),则视为ID
      } else if((entity.getClass().getSimpleName() + "Id").equalsIgnoreCase(tempMethod.getName().substring(3))) {
      	obj[list.size()-1] = tempMethod.invoke(entity, new Object[]{});
      	idMethod = tempMethod;
        iter.remove();        
      }
    }
		
    //把迭代指针移到第一位
    iter = list.iterator();
    while(iter.hasNext()) {
      tempMethod = iter.next();
      sql += tempMethod.getName().substring(3).toLowerCase() + "= ?,";
      obj[i] = tempMethod.invoke(entity, new Object[]{});
      i++;
    }
    
    //去掉最后一个,符号
    sql = sql.substring(0,sql.lastIndexOf(","));
    
    //添加条件
    sql += " where " + idMethod.getName().substring(3).toLowerCase() + " = ?";
    
    //SQL拼接完成,打印SQL语句
    System.out.println(sql);
		
    st = conn.prepareStatement(sql);
    
    for (int j = 0; j < obj.length; j++) {
			st.setObject(j+1, obj[j]);
		}
    
    result = st.executeUpdate();

    jdbcUtil.getClose(rs, st, conn);
    
		return result;

	}
	
	
	public T findById(Object object) throws Exception{
		
		String sql = "select * from "+ persistentClass.getSimpleName().toLowerCase() +" where ";
		
		//通过子类的构造函数,获得参数化类型的具体类型.比如BaseDAO<T>也就是获得T的具体类型
    T entity = persistentClass.newInstance();
    
    //存放Pojo(或被操作表)主键的方法对象
    Method idMethod = null;
    
    List<Method> list = this.matchPojoMethods(entity, "set");
    Iterator<Method> iter = list.iterator();
    
    //过滤取得Method对象
    while(iter.hasNext()) {
      Method tempMethod = iter.next();
      if(tempMethod.getName().indexOf("Id") != -1 && tempMethod.getName().substring(3).length() == 2) {
        idMethod = tempMethod;
      } else if((entity.getClass().getSimpleName() + "Id").equalsIgnoreCase(tempMethod.getName().substring(3))){
        idMethod = tempMethod;
      }
    }
    //第一个字母转为小写
    sql += idMethod.getName().substring(3,4).toLowerCase()+idMethod.getName().substring(4) + " = ?";
    	
		System.out.println(sql);
		
		st = conn.prepareStatement(sql);
		
		//判断id的类型
    if(object instanceof Integer) {
      st.setInt(1, (Integer)object);
    } else if(object instanceof String){
      st.setString(1, (String)object);
    }
		
    rs = st.executeQuery();
        
    //把指针指向迭代器第一行
    iter = list.iterator();
    
    //封装
    while(rs.next()) {
      while(iter.hasNext()) {
        Method method = iter.next();
        if(method.getParameterTypes()[0].getSimpleName().indexOf("String") != -1) {
          //由于list集合中,method对象取出的方法顺序与数据库字段顺序不一致(比如:list的第一个方法是setDate,而数据库按顺序取的是"123"值)
          //所以数据库字段采用名字对应的方式取.
          this.setString(method, entity, rs.getString(method.getName().substring(3).toLowerCase()));
        } else if(method.getParameterTypes()[0].getSimpleName().indexOf("Date") != -1){
          this.setDate(method, entity, rs.getDate(method.getName().substring(3).toLowerCase()));
        }else {
          this.setInt(method, entity, rs.getInt(method.getName().substring(3).toLowerCase()));
        }  
      }
    }
		
    jdbcUtil.getClose(rs, st, conn);
    
		return entity;
		
	}
	
	
	
	
	
	/**
   * 过滤当前Pojo类所有带传入字符串的Method对象,返回List集合.
   */
  private List<Method> matchPojoMethods(T entity,String methodName) {
    //获得当前Pojo所有方法对象
    Method[] methods = entity.getClass().getDeclaredMethods();
    
    //List容器存放所有带get字符串的Method对象
    List<Method> list = new ArrayList<Method>();
    
    //过滤当前Pojo类所有带get字符串的Method对象,存入List容器
    for(int index = 0; index < methods.length; index++) {
      if(methods[index].getName().indexOf(methodName) != -1) {
        list.add(methods[index]);
      }
    }    
    return list;
  }
  

  /**
   * 参数类型为String时,为entity字段设置参数,对应set
   */
  public String setString(Method method, T entity, String arg) throws Exception{
    return (String)method.invoke(entity, new Object[]{arg});
  }
  
  
  /**
   * 参数类型为Date时,为entity字段设置参数,对应set
   */
  public Date setDate(Method method, T entity, Date arg) throws Exception{
    return (Date)method.invoke(entity, new Object[]{arg});
  }
	
	
  /**
   * 参数类型为Integer或int时,为entity字段设置参数,对应set
   */
  public Integer setInt(Method method, T entity, Integer arg) throws Exception{
    return (Integer)method.invoke(entity, new Object[]{arg});
  }
 	
}

以上这篇基于JDBC封装的BaseDao(实例代码)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • idea使用pagehelper实现后端分页功能的步骤详解

    idea使用pagehelper实现后端分页功能的步骤详解

    这篇文章主要介绍了idea使用pagehelper实现后端分页功能的步骤,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 使用Spring底层组件实现Aware接口

    使用Spring底层组件实现Aware接口

    这篇文章主要介绍了使用Spring底层组件实现Aware接口,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Mybatis(ParameterType)传递多个不同类型的参数方式

    Mybatis(ParameterType)传递多个不同类型的参数方式

    这篇文章主要介绍了Mybatis(ParameterType)传递多个不同类型的参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 在Filter中不能注入bean的问题及解决

    在Filter中不能注入bean的问题及解决

    这篇文章主要介绍了在Filter中不能注入bean的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • maven安装与环境配置图文教程

    maven安装与环境配置图文教程

    这篇文章主要为大家详细介绍了maven安装与环境配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • Spring Boot中配置定时任务、线程池与多线程池执行的方法

    Spring Boot中配置定时任务、线程池与多线程池执行的方法

    这篇文章主要给大家介绍了关于Spring Boot中配置定时任务、线程池与多线程池执行的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • spring boot(四)之thymeleaf使用详解

    spring boot(四)之thymeleaf使用详解

    Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。接下来通过本文给大家介绍spring boot(四)之thymeleaf使用详解,需要的朋友可以参考下
    2017-05-05
  • java基础之反射和泛型以及注解

    java基础之反射和泛型以及注解

    这篇文章主要介绍了 java基础之反射和泛型以及注解的相关资料,需要的朋友可以参考下
    2017-07-07
  • Java8函数式编程应用小结

    Java8函数式编程应用小结

    Java8非常重要的就是引入了函数式编程的思想,使得这门经典的面向对象语言有了函数式的编程方式,弥补了很大程度上的不足,函数式思想在处理复杂问题上有着更为令人称赞的特性,本文给大家介绍Java8函数式编程应用小结,感兴趣的朋友一起看看吧
    2023-12-12
  • JVM回收跨代垃圾的方式详解

    JVM回收跨代垃圾的方式详解

    在Java堆内存中,年轻代和老年代之间存在的对象相互引用,假设现在要进行一次新生代的YGC,但新生代中的对象可能被老年代所引用的,为了找到新生代中的存活对象,不得不遍历整个老年代,这样明显效率很低下,那么如何快速识别并回收这种引用对象呢
    2024-02-02

最新评论