使用域超级管理员打开Exchange 2010发现没有权限
2012-03-28 23:33
417 查看
在项目中有这个一个需求,查询一个表,显示为datagrid,但是需要显示的一列是个关联表中的信息,是一对多的,但是需要把这个‘多’以逗号分隔显示在这一列上。
举例:
A1表 A2表
id name id A1_id name
1 name1 1 1 A2_name1
2 name2 2 1 A2_name2
3 2 A2_name3
查询后得到的显示在页面上的datagrid 应该为:
id name A2_name
1 name1 A2_name1, A2_name2
2 name2 A2_name3
如果用hibernate你会怎么做呢? 写sql语句,一个sql能直接写出这样的结果的sql吗? 我想了一下,很难,因为显示结果需要改变 A2表的维度,需要将关联的多条记录转化为 一条记录上的一列的值。有人说实话存储过程吧, 如果用存储过程了,那hibernate就失去了使用它的意义,在数据库移植上就会有问题。我们的原则是指做基本的sql处理,其他的都是业务逻辑代替。有人说,用hibernate查询A1表,然后得到结果的List,然后遍历这个List,拿到A1的id,关联查询A2表,或者A2的结果集,然后遍历A2,将A2的那么拼成字符串,然后构建新的Map对象,将A1的结果集的数据全都加入,然后将构建好的A2关联信息的以逗号分隔的字符串,加入到Map的一个列中去。 嗯,这样可以实现我们最终要的结果,但是,hibernate获得的结果集List,hibernate本身就需要循环jdbc的Resultset,然后将数据填充到实体对象或者Map对象当中去,然后组织成一个List对象。 然后你又需要再次遍历这个List对象,讲所有的数据取出来,关联查询,再重新组织成一个新的Map对象。 数据量小,列比较少,还可以将就,但是数据量大,列大,又该如何? 研究了一上午hibernate的方法,好像就没有这么干的。不知道hibernate是否本来就可以支持。 如果hibernate本身就有办法支持的话,请知道的朋友告知。 最后没招,就研究了hibernate的Transformers 并读了AliasedTupleSubsetResultTransformer的源代码,于是有了点子。我重写了AliasedTupleSubsetResultTransformer,代码如下:
上面“关键代码”的地方,原来的代码,只是resultClass.newInstance(); 我的修改其实很简单,就是使用spring的Context获取的bean而已,这样bean就可以被增强了,可以注入,可以支持事务了。于是,我们就可以在hibernate像实体对象填充数据的时机做任何的事情,包括我上面的需求,一旦hibernate像实体对象填充数据,就要调用set方法,在调用setId这个方法的时候,我们就能获得每条记录的id,然后可以查询关联表,组织处以逗号分隔的关联表多条记录的名称,然后填充到实体对象的某一个属性上。这样,查询完毕,我们获得的List中的实体对象,就已经包含了我们要的多表合并出的那列的值,我们只用json一下,返回前台,轻松的就可以在datagrid上显示出我们要的结果。
这样做的坏处,目前看只有一条,就是无法应对hibernate的升级,如果升级变动大,就需要修改调整代码了。
如果有朋友有更好的办法,可以提出交流,我的这种办法,有点简单粗暴,但是可以应对一切不可能完成的任务。 其实说白了,相当于在hibernate给实体对象填充数据的过程中拦截。
本文出自 “My Joy is my joy ~” 博客,转载请与作者联系!
举例:
A1表 A2表
id name id A1_id name
1 name1 1 1 A2_name1
2 name2 2 1 A2_name2
3 2 A2_name3
查询后得到的显示在页面上的datagrid 应该为:
id name A2_name
1 name1 A2_name1, A2_name2
2 name2 A2_name3
如果用hibernate你会怎么做呢? 写sql语句,一个sql能直接写出这样的结果的sql吗? 我想了一下,很难,因为显示结果需要改变 A2表的维度,需要将关联的多条记录转化为 一条记录上的一列的值。有人说实话存储过程吧, 如果用存储过程了,那hibernate就失去了使用它的意义,在数据库移植上就会有问题。我们的原则是指做基本的sql处理,其他的都是业务逻辑代替。有人说,用hibernate查询A1表,然后得到结果的List,然后遍历这个List,拿到A1的id,关联查询A2表,或者A2的结果集,然后遍历A2,将A2的那么拼成字符串,然后构建新的Map对象,将A1的结果集的数据全都加入,然后将构建好的A2关联信息的以逗号分隔的字符串,加入到Map的一个列中去。 嗯,这样可以实现我们最终要的结果,但是,hibernate获得的结果集List,hibernate本身就需要循环jdbc的Resultset,然后将数据填充到实体对象或者Map对象当中去,然后组织成一个List对象。 然后你又需要再次遍历这个List对象,讲所有的数据取出来,关联查询,再重新组织成一个新的Map对象。 数据量小,列比较少,还可以将就,但是数据量大,列大,又该如何? 研究了一上午hibernate的方法,好像就没有这么干的。不知道hibernate是否本来就可以支持。 如果hibernate本身就有办法支持的话,请知道的朋友告知。 最后没招,就研究了hibernate的Transformers 并读了AliasedTupleSubsetResultTransformer的源代码,于是有了点子。我重写了AliasedTupleSubsetResultTransformer,代码如下:
public class XKAliasToBeanResultTransformer extends AliasedTupleSubsetResultTransformer { /** * */ private static final long serialVersionUID = 5967847763983844234L; private final Class<?> resultClass; private boolean isInitialized; private String[] aliases; private Setter[] setters; public XKAliasToBeanResultTransformer(Class<?> resultClass) { if (resultClass == null) { throw new IllegalArgumentException("resultClass cannot be null"); } isInitialized = false; this.resultClass = resultClass; } /** * {@inheritDoc} */ public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) { return false; } public Object transformTuple(Object[] tuple, String[] aliases) { Object result; if (!isInitialized) { initialize(aliases); } else { check(aliases); } // 关键代码 result = Initialization.getInstance().getApplicationContext().getBean(resultClass); for (int i = 0; i < aliases.length; i++) { if (setters[i] != null) { setters[i].set(result, tuple[i], null); } } return result; } private void initialize(String[] aliases) { PropertyAccessor propertyAccessor = new ChainedPropertyAccessor(new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor(resultClass, null), PropertyAccessorFactory.getPropertyAccessor("field") }); this.aliases = new String[aliases.length]; setters = new Setter[aliases.length]; for (int i = 0; i < aliases.length; i++) { String alias = aliases[i]; if (alias != null) { this.aliases[i] = alias; setters[i] = propertyAccessor.getSetter(resultClass, alias); } } isInitialized = true; } private void check(String[] aliases) { if (!Arrays.equals(aliases, this.aliases)) { throw new IllegalStateException("aliases are different from what is cached; aliases=" + Arrays.asList(aliases) + " cached=" + Arrays.asList(this.aliases)); } } public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } XKAliasToBeanResultTransformer that = (XKAliasToBeanResultTransformer) o; if (!resultClass.equals(that.resultClass)) { return false; } if (!Arrays.equals(aliases, that.aliases)) { return false; } return true; } public int hashCode() { int result = resultClass.hashCode(); result = 31 * result + (aliases != null ? Arrays.hashCode(aliases) : 0); return result; } }
上面“关键代码”的地方,原来的代码,只是resultClass.newInstance(); 我的修改其实很简单,就是使用spring的Context获取的bean而已,这样bean就可以被增强了,可以注入,可以支持事务了。于是,我们就可以在hibernate像实体对象填充数据的时机做任何的事情,包括我上面的需求,一旦hibernate像实体对象填充数据,就要调用set方法,在调用setId这个方法的时候,我们就能获得每条记录的id,然后可以查询关联表,组织处以逗号分隔的关联表多条记录的名称,然后填充到实体对象的某一个属性上。这样,查询完毕,我们获得的List中的实体对象,就已经包含了我们要的多表合并出的那列的值,我们只用json一下,返回前台,轻松的就可以在datagrid上显示出我们要的结果。
这样做的坏处,目前看只有一条,就是无法应对hibernate的升级,如果升级变动大,就需要修改调整代码了。
如果有朋友有更好的办法,可以提出交流,我的这种办法,有点简单粗暴,但是可以应对一切不可能完成的任务。 其实说白了,相当于在hibernate给实体对象填充数据的过程中拦截。
本文出自 “My Joy is my joy ~” 博客,转载请与作者联系!
相关文章推荐
- 解决客户一例:使用域超级管理员打开Exchange 2010发现没有权限
- Windows Server 2008中用管理员的权限使用命令行来打开程序
- udev的使用-minicom没有权限打开串口,更改 ttyUSB0 的权限
- udev的使用-minicom没有权限打开串口,更改 ttyUSB0 的权限
- administrator内置账户“ 网络无法访问,你可能没有权限使用网络资源,请与管理员联系...” 解决办法
- 计算机无法访问,您可能没有权限使用网络资源.请与这台服务器的管理员联系以查明您
- 打开Exchange 2010 管理控制台(EMC)出现“你的权限不足,无法访问该数据”错误
- Win10系统打开共享文件提示没有权限使用网络资源怎么处理?
- 转:WORKGROUP无法访问,您可能没有权限使用网络资源,请与这台服务器的管理员联系以查明您是否有访问权限。
- 计算机无法访问,您可能没有权限使用网络资源.请与这台服务器的管理员联系以查明您
- 【转】您可能没有权限使用网络资源,请与这台服务器的管理员联系以查明您是否有访问权限" 的解决办法
- xxx无法访问 你可能没有权限使用网络资源.请与这台服务器的管理员联系以查明你是否有访问权限.
- WORKGROUP无法访问,您可能没有权限使用网络资源,请与这台服务器的管理员联系以查明您是否有访问权限。
- 今天在Mac机器上使用了Flex Builder编辑了一个源代码文件,保存后使用vim命令去打开时发现系统自动在每一行的结尾添加了^M符号,其实^M在Linux/Unix中是非常常见的,也就是我们在Win中见过的/r回车符号。由于编辑软件的编码问题,某些IDE的编辑器在编辑完文件之后会自动加上这个^M符号。看起来对我们的源代码没有任何影响,其实并不然,当我们把源代码文件Check In到svn之类
- "计算机无法访问,您可能没有权限使用网络资源.请与这台服务器的管理员联系"的解决办法
- 解决“**无法访问,你可能没有权限使用网络资源,请与管理员联系,拒绝访问!"
- 您可能没有权限使用网络资源。请与这台服务器的管理员联系以查明您是否有访问权限,拒绝访问
- 打开Access 提示没有使用对象的必要权限
- 计算机无法访问,没有权限使用网络资源。请与这台服务器的管理员联系
- 无法访问,您可能没有权限使用网络资源。请与这台服务器的管理员联系以查明您是否有访问权限。拒绝访问