实施 ORM 的两项要旨:泛型和反射

鄙人认为,实施 ORM 的两项要旨乃泛型和反射。下面开始看看怎么为 DAO 层添砖加瓦。

首先,在 DBAccess 基础上扩展 DBAccessORM 接口,形成基于 ORM 的数据调用。

/**
 * 数据访问对象
 *
 * @author Frank Cheung
 *
 */
public interface DBAccessORM extends DBAccess {

	/**
	 * 查询单笔记录,返回实体
	 *
	 * @param sql
	 *            原生 SQL 语句
	 * @param clazz
	 *            POJO 类
	 * @return 包含值的实体类
	 */
	<T> T queryOne(String sql, Class<T> clazz);

	/**
	 * 查询单笔记录,返回实体
	 *
	 * @param qr
	 *            拼凑 sql
	 * @param clazz
	 *            POJO 类
	 * @return 包含值的实体类
	 */
	<T> T queryOne(QueryRunner qr, Class<T> clazz);

	/**
	 * 查询多行记录
	 *
	 * @param sql
	 *            原生 SQL 语句
	 * @return 如果没有找到记录返回 null
	 */
	<T> T[] queryList(String sql, Class<T> clazz);

	/**
	 * 查询多行记录
	 *
	 * @param qr
	 *            拼凑 sql
	 * @return 如果没有找到记录返回 null
	 */
	<T> T[] queryList(QueryRunner qr, Class<T> clazz);

	/**
	 * 查询多行记录并分页
	 *
	 * @param qr
	 *            拼凑 sql
	 * @param start
	 *            起始行数
	 * @param limit
	 *            读取的行数
	 * @return 如果没有找到记录返回 null
	 */
	<T> T[] queryList(QueryRunner qr, int start, int limit, Class<T> clazz);

	/**
	 * 插入记录
	 *
	 * @param tablename
	 *            表名
	 * @param data
	 *            Map 结构数据
	 * @return 结果信息对象
	 */
	// Result<CreateAction> insert(String tablename, IRecord data);

	/**
	 * 更新记录
	 *
	 * @param tablename
	 *            表名
	 * @param data
	 *            Map 结构数据
	 * @param uid
	 *            UUID
	 * @return 结果信息对象
	 */
	// Result<UpdateAction> update(String tablename, IRecord data, String uid);

	/**
	 * 指定表名和 id,删除一条记录
	 *
	 * @param tablename
	 *            表名
	 * @param uid
	 *            UUID
	 * @return 结果信息对象
	 */
	// boolean delete(String tablename, String uid);
}

当前先完成读操作,写操作留待有时间再完成。

使用方法:

public static class News{
	private String name;
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name;
	}
}

// 查询一条记录
DBAccessORM dao = new DBAccessImpl_ORM(conn);
News news = dao.queryOne("SELECT * FROM news WHERE uid = ‘2ccccd21-b89c-416b-a511-59103fd0b1cc‘", News.class);

可见,实体类只需要传入目标 Class.class 即可定义泛型的具体类型,无须强类型转换。

能理解了泛型,使用起来就比较方便了。下面接着说说反射的运用。

试举一个例子,查询单行数据返回实体。

public <T> T queryOne(String sql, Class<T> clazz) {
	Result<Record> result = queryOne(sql); // 查询结果
	if(result != null) {
		T obj = Reflect.newInstance(clazz); // 通过反射创建 POJO 实例

		for (String name : result.result.keySet())
			Reflect.setProperty(obj, name, result.result.get(name));

		return obj;
	} else return null;
}

Reflect.newInstance(clazz); 是通过反射创建 POJO 的实例,即 Bean。光有 Bean 空实例没用,还要往里面塞数据。我们使用反射包的 Reflect.setProperty() 调用 setter 塞数据。当然,前提要求是 Map 的 key 是与 Bean 的 setXXX 中的 XXX 能够对上号。

关于 Java 反射的运用,可以看看我之前的文章《反射(Reflection)备忘 》

至此,通过泛型和反射就可以简单的创建 ORM 方式调用数据。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-01 03:22:49

实施 ORM 的两项要旨:泛型和反射的相关文章

为什么Fibonacci数列相邻两项之比会趋于0.618

转帖: http://www.matrix67.com/blog/archives/5221 你或许熟知一个非常经典的结论: Fibonacci 数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … (头两项都是 1 ,此后每一项都是前两项之和)的相邻两项之比将会越来越接近黄金比例 0.618 ,不信请看: 1 / 1 = 1.0000000... 1 / 2 = 0.50000000... 2 / 3 = 0.66666667... 3 / 5 = 0.60000000

求斐波那契数列的相邻两项的比值,精确到小数后三位。

未完成,只能假设知道是9和10代入. 代码如下: package zuoye; import java.math.BigDecimal; /* * 求斐波那契数列的相邻两项的比值,精确到小数后三位. * p1,p2,p3......pi,pj,...求pi/pj * 1 1 2 3 5 8 13 * 5/8,8/13,...收敛 */ public class Test { static double feibo(int x){ if(x==1||x==2) return 1; return f

两项基于网络的“黑客”技术

两项基于网络的“黑客”技术 软件开发和测试中网络环境迁移和数据分析 1   导读 关于智能路由器的这两项技术的介绍,想想还是搞个比较有噱头的标题才能吸引人进来细看的.本文确实是介绍的两个关于智能路由器的hack技术,但是却是将这两项技术用于软件开发过程中的正途中的.当然如果有悟性,也可以将此技术用于不违法的恶作剧玩一下也无妨. 本文提到的两个基于网络的hack技术: DNS劫持 数据抓包 基本本质上就是路由器设备的两个主要网络功能: 网关配置功能 网关数据中转功能 但是用于软件开发的正途,就变换

突破两项吉尼斯世界纪录浙江商帮全体高层应邀参观阿里巴巴

淘宝安全交易平台 www.xunjie36.com 淘宝店铺出售www.360feiyue.com 淘宝店铺交易www.360feiyue.com[关键词]淘宝安全交易平台 www.xunjie36.com 淘宝店铺出售www.360feiyue.com 淘宝店铺交易www.360feiyue.com淘宝小号信誉查询 此次阿里上市后的第一个"双十一",销售破百亿仅用38分钟:13个小时,成交额便已超过去年全天的销售总额362亿元:最终的成交额定格在571亿: 突破两项吉尼斯世界纪录,分

C# 两个List泛型用 Linq去重复数据 或者 得到重复数据

1, 两个List泛型用Linq去重复数据 Code: List<string> lstA = new List<string> { "E00401501B652563", "E00401501B652564", "E00401501B652565", "E00401501B652566", "E00401501B652567", "E00401501B652568&quo

罗森伯格再次荣获《2017年度综合布线十大品牌》以及《2017年度数据中心解决方案优秀供应商》两项大

"中国智能建筑品牌奖"由千家品牌实验室评选并颁发,综合了千家智客全年品牌监测数据.市场调查分析.用户反馈.专家评议以及用户投票等因素,评选出十大综合布线品牌等多项大奖.罗森伯格再次荣获<2017年度综合布线十大品牌>以及<2017年度数据中心解决方案优秀供应商>两项大奖. "中国智能建筑品牌奖"是智能建筑领域极具含金量的年度大奖,自2002年首次颁发,至今已有十五年的历史.由于评选客观.公正.权威,"中国智能建筑品牌奖"也

checkbox 最多选两项

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>久信臻氏</title></head><body><form action="index.php" method="post"> <div> <label for=&q

阿里巴巴AI夺肝结节诊断两项世界冠军,至今无人超越

在澳门用人工智能预测流感趋势后,阿里巴巴还在继续探索如何用科技保障人类健康,这一次是更准确地测量肝结节. 12月28日消息,在全球LiTS(Liver Tumor Segmentation Challenge,肝脏肿瘤病灶区CT图像分割挑战)上,阿里巴巴从近百支科学家队伍中脱颖而出,已获得两项第一,至今无人超越. 肝病是困扰人类的重大公共卫生威胁,考古显示4500年前的人类骨骼中甚至就有最古老的乙肝病毒.在我国,目前肝癌的死亡率在恶性肿瘤中位居第二,仅次于肺癌. 肝结节尽管不致命,却可能是一些恶

【APIO2018】铁人两项

[APIO2018]铁人两项 题目描述 大意就是给定一张无向图,询问三元组\((s,c,f)\)中满足\(s\neq c\neq f\)且存在\((s\to c\to f)\)的简单路径(每个点最多经过一次)的数量. \(1\leq n,\leq 10^5,1\leq m\leq 2*10^5\) 我们考虑枚举\(s,f\)然后计算中间\(c\)的数量.我们发现对于一张图上统计两点之间路径上的点数量很好做.于是我们考虑建圆方树. 我们将圆点的权值定为\(-1\),将方点的权值定为与其直接相连的圆