TeaFramework——ORM框架的实现(二)

    SQL的绑定参数后就可以执行了,主要有三个方法,填充主键到对象、更新、查询。定义了一个接口如下: 

public interface DataBind {

	public Object fillPrimaryKey(Method method, Object object) throws Exception;

	public Object excuteUpdate(String sql, Object object, boolean isAutoIncrement) throws Exception;

	public List<CaseInsensitiveMap<String, Object>> excuteQuery(String sql, Object object) throws Exception;

}

    初始我们限定了数据访问层传递的参数只有一个,类型可以是一个实体对象、Map、八点基本类型+Stirng和java.util.Date、或者不传,对于不同的类型,参数的绑定都是不同,所以定义了几个不同的实现类来应对不同参数的场景。

    1、BeanDataBind处理传参为实体对象时的数据绑定

    2、MapDataBind处理传参为Map时的数据绑定

    3、NullDataBind处理不传参的场景

    4、PrimitiveDataBind处理传参为基本类型的场景

    类的UML图如下:

    224237_ggIj_1778239.png

    接下来看,SQL的执行过程都定义在AbstractDataBind中。

    1、主键的填充到对象,必须在insert之前执行

public Object fillPrimaryKey(Method method, Object object) throws Exception {
		PreparedStatement pst = null;
		ResultSet rs = null;
		try {
			GetPrimaryKey getPrimaryKey = method.getAnnotation(GetPrimaryKey.class);
			Connection connection = ConnectionThreadVariable.getConnetion();
			pst = connection.prepareStatement(getPrimaryKey.sql());
			rs = pst.executeQuery();
			rs.next();
			Object primaryKey = rs.getObject(1);
			fillPrimaryKeyToObject(object, getPrimaryKey.primaryKeyProperty(), primaryKey);
			logger.debug("执行:" + getPrimaryKey.sql() + ",执行结果:" + primaryKey);
			return primaryKey;
		} catch (Exception e) {
			throw new TeaOrmException(e);
		} finally {
			pst.close();
			rs.close();
		}
	}

    2、执行更新操作,更新操作中有一种特殊情况,执行insert语句,并且主键是数据自动生成,那么要获取生成的主键,必须带上Statement.RETURN_GENERATED_KEYS参数创建Statement

public Object excuteUpdate(String sql, Object object, boolean isAutoIncrement) throws Exception {
		SqlTransformResult sqlTransformResult = transformSql(sql, object);
		Connection connection = ConnectionThreadVariable.getConnetion();
		PreparedStatement pst = null;
		Object result = null;
		try {
			if (isAutoIncrement) {
				pst = connection.prepareStatement(sqlTransformResult.getSql(), Statement.RETURN_GENERATED_KEYS);
			} else {
				pst = connection.prepareStatement(sqlTransformResult.getSql());
			}
			logger.debug("执行:" + sqlTransformResult.getSql());
			bindPrepareStatement(sqlTransformResult.getNeedBindFields(), pst, object);
			if (isAutoIncrement) {
				pst.executeUpdate();
				ResultSet rs = pst.getGeneratedKeys();
				rs.next();
				result = rs.getObject(1);
				rs.close();
			} else {
				result = pst.executeUpdate();
			}
		} catch (Exception e) {
			throw new TeaOrmException(e);
		} finally {
			pst.close();
		}
		return result;
	}

    3、执行查询操作, 最终返回的是一个List,泛型是一个忽略大小写的Map    

public List<CaseInsensitiveMap<String, Object>> excuteQuery(String sql, Object object) throws Exception {
		List<CaseInsensitiveMap<String, Object>> result = new ArrayList<CaseInsensitiveMap<String, Object>>();
		SqlTransformResult sqlTransformResult = transformSql(sql, object);
		Connection connection = ConnectionThreadVariable.getConnetion();
		PreparedStatement pst = null;
		ResultSet rs = null;
		PreparedStatement countPst = null;
		ResultSet countRs = null;
		try {
			PageProcessor pageProcessor = PageProcessorManager.getPageProcessor();
			// 查询总数
			if (PageThreadVariable.isPaging()) {
				countPst = connection.prepareStatement(pageProcessor.countSql(sqlTransformResult.getSql()));
				bindPrepareStatement(sqlTransformResult.getNeedBindFields(), countPst, object);
				countRs = countPst.executeQuery();
				countRs.next();
				PageThreadVariable.setTotalRecordCount(countRs.getLong(1));
				logger.debug("执行:" + pageProcessor.countSql(sqlTransformResult.getSql()));
			}
			// 查询分页数据
			if (PageThreadVariable.isPaging()) {
				pst = connection.prepareStatement(pageProcessor.pageSql(sqlTransformResult.getSql()));
				logger.debug("执行:" + pageProcessor.pageSql(sqlTransformResult.getSql()));
			} else {
				pst = connection.prepareStatement(sqlTransformResult.getSql());
				logger.debug("执行:" + sqlTransformResult.getSql());
			}
			bindPrepareStatement(sqlTransformResult.getNeedBindFields(), pst, object);
			rs = pst.executeQuery();
			ResultSetMetaData resultSetMetaData = rs.getMetaData();
			int columnCount = resultSetMetaData.getColumnCount();
			if (rs != null) {
				while (rs.next()) {
					CaseInsensitiveMap<String, Object> map = new CaseInsensitiveMap<String, Object>();
					for (int i = 1; i <= columnCount; i++) {
						String columnName = resultSetMetaData.getColumnName(i);
						map.put(columnName, rs.getObject(columnName));
					}
					result.add(map);
				}
			}
		} catch (Exception e) {
			throw new TeaOrmException(e);
		} finally {
			if (rs != null)
				rs.close();
			if (countRs != null)
				countRs.close();
			if (pst != null)
				pst.close();
			if (countPst != null)
				countPst.close();
		}
		return result;
	}

           4、AbstractDataBind还有三个抽象方法,具体功能由之类去实现

            bindPrepareStatement绑定预编译的参数、 fillfixedValue填充非预编译的值到sql,如用$$包裹的变量,fillPrimaryKeyToObject把通过sql生成的主键写到对象里 。

        至此,SQL的预编译参数和非预编译参数可以绑定,并执行。分页的设计,将在下一篇中讲。                

     项目地址:https://git.oschina.net/lxkm/teaframework
     博客:https://blog.youkuaiyun.com/dong_lxkm

                   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值