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

自定义的Native SQL Query返回强类型的Bean

阅读更多

问题:

在项目中,我们常常会实现Report功能,通常使用Native SQL Query返回查询的数据集,而这些数据集是Raw typed,Query的调用者获得这些原始的数据集后需要显示地将其转化成强类型的Java Bean类,如何减少这些繁琐的转换呢?

 

解决方案:

将原始数据集的每条记录根据一定的规则将其自动映射成Java Bean 对象,比如为Query 返回的列名在Java Bean类中查找匹配的字段(忽略_,空格,大小写,等), 使用反射将该列的值赋值到Java Bean的字段中。

 

Spring 中为我们提供了一个现成的类用来实现此功能的类-BeanPropertyRowMapper,该类就是使用反射依据列名在Java Bean类中查找匹配的属性,如下是其核心代码片段:

public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
		Assert.state(this.mappedClass != null, "Mapped class was not specified");
		T mappedObject = BeanUtils.instantiate(this.mappedClass);
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);
		initBeanWrapper(bw);

		ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = rsmd.getColumnCount();
		Set<String> populatedProperties = (isCheckFullyPopulated() ? new HashSet<String>() : null);

		for (int index = 1; index <= columnCount; index++) {
			String column = JdbcUtils.lookupColumnName(rsmd, index);
			PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase());
			if (pd != null) {
				try {
					Object value = getColumnValue(rs, index, pd);
					if (logger.isDebugEnabled() && rowNumber == 0) {
						logger.debug("Mapping column '" + column + "' to property '" +
								pd.getName() + "' of type " + pd.getPropertyType());
					}
					try {
						bw.setPropertyValue(pd.getName(), value);
					}
					catch (TypeMismatchException e) {
						if (value == null && primitivesDefaultedForNullValue) {
							logger.debug("Intercepted TypeMismatchException for row " + rowNumber +
									" and column '" + column + "' with value " + value +
									" when setting property '" + pd.getName() + "' of type " + pd.getPropertyType() +
									" on object: " + mappedObject);
						}
						else {
							throw e;
						}
					}
					if (populatedProperties != null) {
						populatedProperties.add(pd.getName());
					}
				}
				catch (NotWritablePropertyException ex) {
					throw new DataRetrievalFailureException(
							"Unable to map column " + column + " to property " + pd.getName(), ex);
				}
			}
		}

		if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
			throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " +
					"necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties);
		}

		return mappedObject;
	}

 

从上面可以看出 其输入的数据源,只是指出ResultSet,如过需要支持其他的数据源,则得自己实现了。如下为我自己实现的一个例子,输入源为CursoredStream(EclipseLink):

public T mapRow(CursoredStream cs) {

		DatabaseRecord row = (DatabaseRecord) cs.next();

		List<DatabaseField> fields = cs.getFields();

		Assert.state(this.mappedClass != null, "Mapped class was not specified");
		T mappedObject = BeanUtils.instantiate(this.mappedClass);
		BeanWrapper bw = PropertyAccessorFactory
				.forBeanPropertyAccess(mappedObject);
		initBeanWrapper(bw);

		// ResultSetMetaData rsmd = rs.getMetaData();
		int columnCount = fields.size();

		Set<String> populatedProperties = (isCheckFullyPopulated() ? new HashSet<String>()
				: null);

		for (DatabaseField field : fields) {
			String columnName = field.getName();// JdbcUtils.lookupColumnName(rsmd,
												// index);
			PropertyDescriptor pd = this.mappedFields.get(columnName
					.replaceAll(" ", "").toLowerCase());
			if (pd != null) {
				try {
					Object value = getColumnValue(row, field, pd);

					try {
						bw.setPropertyValue(pd.getName(), value);
					} catch (TypeMismatchException e) {
						if (value == null && primitivesDefaultedForNullValue) {
							logger.debug("Intercepted TypeMismatchException for row "
									+ cs.getPosition()
									+ " and column '"
									+ columnName
									+ "' with value "
									+ value
									+ " when setting property '"
									+ pd.getName()
									+ "' of type "
									+ pd.getPropertyType()
									+ " on object: " + mappedObject);
						} else {
							throw e;
						}
					}
					if (populatedProperties != null) {
						populatedProperties.add(pd.getName());
					}
				} catch (NotWritablePropertyException ex) {
					throw new DataRetrievalFailureException(
							"Unable to map column " + columnName
									+ " to property " + pd.getName(), ex);
				}
			}
		}

		if (populatedProperties != null
				&& !populatedProperties.equals(this.mappedProperties)) {
			throw new InvalidDataAccessApiUsageException(
					"Given ResultSet does not contain all fields "
							+ "necessary to populate object of class ["
							+ this.mappedClass + "]: " + this.mappedProperties);
		}

		return mappedObject;
	}

 

 

分享到:
评论

相关推荐

    Microsoft SQL Server 2008 R2 SP1 Native Client

    Microsoft SQL Server 2008 Native Client (SQL Server Native Client) 是单一动态链接库 (DLL),其中包含 SQL OLE DB 提供者和 SQL ODBC 驱动程序。此链接库针对使用机器码 API (ODBC、OLE DB 和 ADO) 的应用程序...

    SQL Server Native Client大全(官网下载整理9,10,11)

    SQL Server Native Client是微软开发的一款专门用于连接Microsoft SQL Server数据库的客户端库,它结合了ODBC(Open Database Connectivity)和OLE DB(Object Linking and Embedding, Database)接口的功能,为应用...

    SQL Server Native Client 9.0~11.0(32位和64位)

    SQL Server Native Client是微软开发的一款专门用于与SQL Server交互的客户端库,支持多种数据库访问接口,包括ODBC(Open Database Connectivity)和OLE DB(Object Linking and Embedding, Database)。...

    强类型_强类型_

    执行查询后,`ExecuteReader`方法返回一个`SqlDataReader`对象,该对象可以按强类型的方式读取数据库结果集中的每一行数据。 **四、强类型与数据库操作** 在ADO.NET中,强类型体现在与数据库交互时对数据的处理上...

    linq to datasets,通过linq访问强类型数据集

    **LINQ to Datasets:通过LINQ访问强类型数据集** LINQ(Language Integrated Query,语言集成查询)是.NET框架中的一个创新特性,它为在各种数据源上执行查询提供了统一且直观的方式。LINQ to Datasets是LINQ的一...

    MyBatisPlus 自定义sql语句的实现

    MyBatisPlus 自定义sql语句的实现 MyBatisPlus 是一个基于 MyBatis 的增强型 ORM 框架,它提供了强大的 CRUD 操作和条件构造器,但是在某些情况下,我们需要自定义 sql 语句来满足业务需求。本文将详细介绍如何在 ...

    让JPA的Query查询接口返回Map对象的方法

    然而,在JPA 2.0中,使用entityManager.createNativeQuery()执行原生的SQL语句时,query.getResultList()返回的是一个List[]&gt;,每行数据被作为一个对象数组返回。这使得代码不容易让人理解,且不灵活。因此,本文将...

    HeidiSQL9.5加强版

    强大的脚本编辑器支持自定义快捷键和代码折叠,让用户可以高效地编写和运行SQL脚本。 8. **导入导出工具** 支持多种格式的数据导入导出,如CSV、XML、Excel等,便于数据迁移和分析。 9. **安全与权限管理** ...

    SQL强化练习工具

    SQL(Structured Query Language)是用于管理和处理关系数据库的标准编程语言,它在数据查询、更新、插入和删除等方面具有广泛的应用。对于新手来说,熟练掌握SQL是进入数据分析、数据库管理等领域的重要一步。"SQL...

    强类型面向对象动态SQL生成器的设计与实现.pdf

    【标题】:“强类型面向对象动态SQL生成器的设计与实现” 【描述】:本文介绍了一种在Java开发环境中,利用SQL与关系数据库交互的工具,它基于JDBC和SQL,不依赖具体数据库,通过强类型高级面向对象语言特性,提高...

    Go-Go-SQLBuilder是一个用于创建SQL语句的工具函数库

    3. **动态构建**:由于Go语言的强类型特性,Go-SQLBuilder可以根据不同的条件或循环结构动态生成SQL,这在处理复杂查询逻辑时非常有用。 4. **支持多种操作**:除了基本的SELECT、INSERT、UPDATE和DELETE语句外,Go...

    T-SQL强化RAISERROR详解,SQL 注入,使用 OUTPUT 游标参数,使用 WITH RECOMPILE 选项,使用sp_addmessage添加自定义消息

    T-SQL强化RAISERROR详解,SQL 注入,使用 OUTPUT 游标参数,使用 WITH RECOMPILE 选项,使用sp_addmessage添加自定义消息 京华志&精华志出品 希望大家互相学习,互相进步 支持CSDN 支持微软 主要包括C# ASP.NET SQLDBA ...

    c#linq to sql

    LINQ(Language Integrated Query,语言集成查询)是.NET Framework 3.5引入的一个重要特性,它的目标是将查询表达式直接整合到编程语言中,提供了强类型、类型安全和编译时检查的查询能力。 在LINQ to SQL中,...

    NQuery(基于XML文件的数据库接口)

    NQuery是一款专为处理XML文件而设计的数据库接口,它提供了类似于SQL的查询语言,使得开发者可以方便地对XML数据进行检索、操作和管理。在本文中,我们将深入探讨NQuery的基本概念、功能特性以及如何使用它来处理XML...

    SQLServer2008R2

    "SConfig.ini"是配置文件,可能包含了安装过程中的自定义设置选项,例如安装类型、组件选择、服务账户等信息。 7. **管理工具**:虽然未在文件名列表中列出,但SQL Server 2008 R2通常会包含Management Studio,这...

    LINQ to SQL.pdf

    5. **存储过程与LINQ to SQL的结合**:LINQ to SQL也支持与存储过程的交互,你可以调用存储过程并获取返回结果,同样享受强类型和调试支持。 通过LINQ to SQL,开发者可以更加专注于业务逻辑,而不必过多地关注数据...

    sqljdbc41.jar

    sqljdbc41.jar属于类型4,即Direct (Native API) Driver,它通过TCP/IP协议直接与SQLServer通信,提高了效率和性能。 三、sqljdbc41.jar的工作原理 当Java应用程序加载sqljdbc41.jar并建立与SQLServer的连接时,它...

    SQL ToolBelt 2018最新版 分卷1

    SQL Compare Pro  比较和同步SQL Server数据库结构 SQL Data Compare Pro  比较和同步SQL Server...SQL Object Level Recovery Native 从SQL Server备份恢复数据库对象 SQL Search  在SQL Server数据库结构中搜索

    Oralce数据库SQL和pl_sql实例教程

    Oracle数据库是世界上最流行的数据库管理系统之一,SQL(Structured Query Language)是用于管理关系数据库的标准语言,而PL/SQL是Oracle数据库特有的编程语言,扩展了SQL的功能,使得能够编写复杂的存储过程和...

    SQL ToolBelt 2018最新版 分卷2

    SQL Compare Pro  比较和同步SQL Server数据库结构 SQL Data Compare Pro  比较和同步SQL Server...SQL Object Level Recovery Native 从SQL Server备份恢复数据库对象 SQL Search  在SQL Server数据库结构中搜索

Global site tag (gtag.js) - Google Analytics