`
kevin_wanwei
  • 浏览: 117682 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JDBC模板类实现(version1.1)

阅读更多
package daoUtil.daoTemplate;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import jdbcUtil.JdbcUtil;
import daoUtil.PrimaryKeyer;
import daoUtil.RowMapper;
/**
 * 在写jdbc程序是可以清楚的知道
 * 在程序中只有sql语句和其参数值是变化
 * 其余程序代码几乎类似(获得连接,关闭连接)
 * 在这里我对以前所写jdbc程序进行了一下改进
 * 将获得连接和关闭连接的程序代码交给一个模板类去做
 * 再写jdbc程序时,调用模板类中相应的方法,传入sql语句和其参数值
 * 这样大大简化jdbc程序,给我们带来方便
 * 程序新版本往后日子会不断更新,渴望javaeye里面高手多多给我指点
 * @author kevin.wangwei
 * Email:wanwei.234@163.com
 * 2010-1-30
 */
public class DAOTemplate{
	/**jdbc工具类*/
	private JdbcUtil jdbcUtil=JdbcUtil.getInstance();
	/**
	 * 数据库删除操作
	 * @param sql 删除操作sql语句
	 * @param args 删除操作sql语句参数值数组
	 * @return 删除记录条数
	 * @throws SQLException
	 */
	public  int delete(String sql, Object[] args) throws SQLException {
		if(args==null||args.length==0){
			return 0;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1,args[i]);//在这里我们应该调用下面的PreparedStatementSetValue方法,
				                          //不过这样写亦可以,但它不可以处理null值
			}
			return ps.executeUpdate();
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
	}
	/**
	 * 数据库更新操作
	 * @param sql 更新操作sql语句
	 * @param args sql语句参数值数组
	 * @return 更新记录条数
	 * @throws SQLException
	 */
	public int update(String sql, Object[] args) throws SQLException {
		if(args==null||args.length==0){
			return 0;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1,args[i]);
			}
			return ps.executeUpdate();
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
	}
	/**
	 * 数据库查询操作 采用反射来给包装sql语句参数赋值
	 * @param sql 查询操作sql语句
	 * @param args 删除操作sql语句数组数值
	 * @return 结果对象
	 * @throws SQLException
	 */
	public Object find(String sql, Object[] args,RowMapper rowMapper) throws SQLException {
		if(args==null||args.length==0){
			return 0;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				try {
					PreparedStatementSetValue(ps,args[i],i+1);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			rs=ps.executeQuery();
			Object obj=null;
			while(rs.next()){
				obj=rowMapper.rowMapping(rs);
			}
			return obj;
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
	}

	/**
	 * 获得表中记录数
	 * @param sql sql语句
	 * @param args 参数数组
	 * @return 表中记录数
	 * @throws SQLException
	 */
	public int getRecordCount(String sql, Object[] args) throws SQLException {
		if(args==null||args.length==0){
			return 0;
		}
		int count=0;
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1,args[i]);
			}
			if(rs.next()){
				count=rs.getInt(1);
			}
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
		return count;
	}
	/**
	 * 根据数据库表名,找到该表中所有记录数
	 * @param tableName 要查询的表
	 * @return 表中记录数
	 * @throws SQLException
	 */
	public int getRecordCount(String tableName) throws SQLException {
		if(tableName==null||tableName.equals("")){
			return 0;
		}
		int count=0;
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			String sql="select count(*) from "+tableName;
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			if(rs.next()){
				count=rs.getInt(1);
			}
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
		return count;
	}
	/**
	 * 数据库插入操作(这是采用接口回调技术,由调用程序来给主键赋值)
	 * @param sql 插入操作 sql语句
	 * @param args 插入数
	 * @param primaryIndex 主键在sql语句中位置(小于-1表示用数据自动生成主键不需要插入)
	 * @return 插入记录数
	 * @throws Exception 
	 */
	public int insert(String sql, Object[] args, int primaryKeyIndex,PrimaryKeyer primaryKeyer) throws Exception {
		if(args==null||args.length==0){
			return 0;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			if(primaryKeyIndex<=-1){
				for(int i=0;i<args.length;i++){
					try {
						PreparedStatementSetValue(ps,args[i],i+1);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}else if(primaryKeyIndex>-1&&primaryKeyIndex<args.length){
				for(int i=0;i<args.length;i++){
					if(i==primaryKeyIndex){
						PreparedStatementSetValue(ps,primaryKeyer.getPrimaryKey(),i+1);
						//ps.setObject(i+1,primaryKeyer.getPrimaryKey());
					}else{
						PreparedStatementSetValue(ps,args[i],i+1);
					}
				}
			}else{
				throw new IllegalArgumentException("设置主键位置不正确!");
			}
			return ps.executeUpdate();
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
	}
	/**
	 * 查找符合条件所有记录(这也是采用接口回调技术,由调用程序来决定结果set到什么对象中)
	 * @param sql 查询sql语句
	 * @param args 查询参数
	 * @param rowMapper 结果集映射器
	 * @return Collection 记录集
	 * @throws SQLException
	 */	
	public Collection ObjectList(String sql, Object[] args,RowMapper rowMapper) throws SQLException {
		if(args==null||args.length==0){
			return null;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		Collection list=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1,args[i]);
			}
			list=new ArrayList();
			rs=ps.executeQuery();
			while(rs.next()){
				Object obj=rowMapper.rowMapping(rs);
				list.add(obj);
			}
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
		return list;
	}
	/**
	 * 依据与表对应的JavaBean的Class(采用反射技术将结果集set到JavaBean对象中)
	 * 将查询结果封装为一个JavaBean的对象返回
	 * @param sql 查询sql语句
	 * @param args 查询参数
	 * @param javaBeanClass JavaBean的Class
	 * @return 返回获得JavaBean对象
	 * @throws Exception
	 */
	public Object find(String sql, Object[] args,Class javaBeanClass) throws Exception {
		if(args==null||args.length==0){
			return 0;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1,args[i]);
			}
			rs=ps.executeQuery();
			String[] names=jdbcUtil.getResultSetFieldName(rs);
			Object obj=null;
			while(rs.next()){
				obj=rowMapper(javaBeanClass,rs,names);
			}
			return obj;
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
	}	
	/**
	 * 依据与表对应的JavaBean的Class(上面方法重载方法,采用了不同实现机制)
	 * 将查询结果封装为一个包含JavaBean的集合对象返回
	 * @param sql 查询sql语句
	 * @param args 查询参数
	 * @param javaBeanClass javaBeanClass JavaBean的Class
	 * @return 记录集
	 * @throws Exception
	 */
	public Collection ObjectList(String sql, Object[] args,Class javaBeanClass) throws Exception {
		if(args==null||args.length==0){
			return null;
		}
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		Collection list=null;
		try {
			conn=jdbcUtil.getConnection();
			ps=jdbcUtil.scrollReadOnlyResultSet(sql,conn);
			for(int i=0;i<args.length;i++){
				ps.setObject(i+1,args[i]);
			}
			list=new ArrayList();
			rs=ps.executeQuery();
			String[] names=jdbcUtil.getResultSetFieldName(rs);
			while(rs.next()){
				Object obj=rowMapper(javaBeanClass,rs,names);
				list.add(obj);
			}
		}finally{
			jdbcUtil.free(rs,ps,conn);
		}
		return list;
	}
	/**
	 * 这个方法是通过反射来将数据库表中对应的javaBean对象set值
	 * 该JavaBean对象必须有一个无参数的构造函数
	 * @param clazz javabean 超类
	 * @param rs 数据库结果集
	 * @return Object 对象
	 * @throws Exception
	 */
	private Object rowMapper(Class clazz,ResultSet rs,String[] names) throws Exception{
		Object obj=clazz.newInstance();
		for(int i=0;i<names.length;i++){
			String columnName=toUpperCaseFirstLetter(names[i]);
			Method[] m=clazz.getMethods();
		    for(int j=0;j<m.length;j++){
				String methodName=m[j].getName();
				if(columnName.equals(methodName)){
					m[j].invoke(obj,rs.getObject(i+1));
					break;
				}
			}
		}
		return obj;
	}
	/**
	 * 将字符串一个字母转换为大写
	 * @param name
	 * @return
	 */
	private String toUpperCaseFirstLetter(String name){
		if(name!=null&&name.length()>0){
			return "set"+name.substring(0,1).toUpperCase()+name.substring(1);
		}
		return "";
	}
	/**
	 * 这是采用反射的方法来给PreparedStatement包装sql 语句参数赋值
	 * @param ps 
	 * @param obj 数组中对象
	 * @param index 参数索引位置
	 * @throws Exception
	 */
	private void PreparedStatementSetValue(PreparedStatement ps,Object obj,int index) throws Exception{
		String name=getMethodName(obj);
		Method[] m=ps.getClass().getMethods();
		for(int i=0;i<m.length;i++){
			String methodName=m[i].getName();
			if(name.equals(methodName)){
				//System.out.println(methodName+"===========");
				m[i].invoke(ps,index,obj);
				break;
			}
		}
		
	}
	/**
	 * 通过反射获得数组中每个元素类型,
	 * 从而获得PreparedStatement对象setxxx方法名称
	 * @param obj  sql语句参数值
	 * @return PreparedStatement对象要调用setxxx方法名称
	 */
	private String getMethodName(Object obj){
		if(obj==null){
			return null;
		}
		String className=obj.getClass().getName();
		String[] names=className.split("\\.");
		className=names[names.length-1];
		if(className.equalsIgnoreCase("Integer")){
			className="Int";
		}
		className="set"+className;
		return className;
	}
}

 

1
0
分享到:
评论

相关推荐

    玩转模板--自动代码生成工程

    通过修改VelocityUtils类实现.可以自由用户自定义工具,丰富模板参数的处理,如在日期输出时对其进行格式化输出 例如: VelocityContext context = new VelocityContext(map); context.put("dateTool", new DateTool...

    Spring笔记之整合JdbcTemplate.doc

    其中`PersonRowMapper`是一个自定义的`RowMapper`实现类,用于将`ResultSet`对象映射到`Person`对象: ```java private static class PersonRowMapper implements RowMapper&lt;Person&gt; { @Override public Person ...

    ssh 整合案例及所需jar包

    - `jta-1.1.jar`: Java Transaction API,支持分布式事务。 - `dom4j-1.6.1.jar`: XML解析库。 - `commons-logging-1.1.1.jar`: 日志框架。 4. **其他相关库** - `commons-collections-3.1.jar`: 常用集合工具...

    mybatis学习笔记LBY.pdf

    - **SQL 语句易于管理和维护**:将 SQL 语句放在 XML 文件中,便于集中管理,并且可以使用模板引擎进行动态 SQL 的生成。 - **高度灵活**:Mybatis 支持动态 SQL,可以根据条件生成不同的 SQL 语句,满足复杂的需求...

    mybatis 英文文档

    #### 1.1 MyBatis简介 ##### 1.1.1 MyBatis是什么? MyBatis是一款顶级的持久层框架,支持自定义SQL、存储过程以及高级映射。MyBatis极大地简化了JDBC代码,消除了手动设置参数和获取结果集的需求。它可以通过简单...

    JasperReport+IReport开发Java报表入门级教程.pdf

    ##### 1.1 前言 JasperReport 是一款非常强大的开源报表工具,广泛应用于Java应用程序中。iReport 则是 JasperReport 的图形化设计工具,简化了报表设计的过程。本部分将详细介绍如何使用 iReport 在 Windows 环境下...

    hibernate 帮助文档

    ##### 1.1 第一部分 - 第一个Hibernate应用程序 **1.1.1 设置** - **环境准备**:安装Java环境,配置好Maven。 - **项目创建**:使用Maven创建一个新的项目,并添加Hibernate及相关依赖。 **1.1.2 第一个class** ...

    ssh(structs,spring,hibernate)框架中的上传下载

    对于那些仅封装了Connection而未包括Statement的简单数据连接池,SimpleNativeJdbcExtractor是效率最高的抽取器实现类,但具体到apache的BasicDataSource连接池,它封装了所有JDBC的对象,这时就需要使用...

    cms后台管理

    持久层实现类 @Repository//持久层 public class MyContentDaoImpl extends HibernateBaseDao, Integer&gt; implements MyContentDao { @SuppressWarnings("unchecked") public List&lt;MyContent&gt; getList(){ ...

    IReport报表开发教程

    ##### 1.1 前言 iReport是一款强大的报表设计工具,它可以帮助开发者快速地设计并生成复杂的报表。本章节将详细介绍如何使用iReport在Windows环境下制作报表。 ##### 1.2 准备 **1.2.1 下载JDK** - **地址:** [Sun...

    测试培训教材

    The VAPI-XP testing tool enables you to create new testing scripts using Microsoft VBScript, Microsoft JavaScript (JScript version), PerlScript, and PythonScript, and integrate these scripts into your...

Global site tag (gtag.js) - Google Analytics