从数据库中检索一行作为Hibernate中的Map
表Players
:
ID | name | email | age | ... 1 | 'bob' | null | 23 | ...
此表是持久化Player
类的实例的位置(每个实例一行,没有组合等)。
有了Hibernate Session
, 我如何将行 (比如id – PK – 等于1) 作为Java Map (key =列名,值=单元格值)?
用法示例:
Map row = getPlayerByIdAsMap(1);
使用AliasToEntityMapResultTransformer
的查询; 是详细的,但应该与Hibernate属性定义一起使用,而不是与JavaBean定义(它们可以不同)。
Map aliasToValueMap = session.createCriteria(User.class) .add(Restrictions.idEq(userID)) .setProjection(Projections.projectionList() .add(Projections.id().as("id")) // Add others properties ) .setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE) .uniqueResult();
更糟糕的approch可以编写一个自定义的ResultTransformer,它内省ClassMetadata并尝试提取值…
class IntrospectClassMetadata extends BasicTransformerAdapter { PassThroughResultTransformer rt = PassThroughResultTransformer.INSTANCE; public Object transformTuple(Object[] tuple, String[] aliases) { final Object o = rt.transformTuple(tuple, aliases); ClassMetadata cm = sf.getClassMetadata(o.getClass()); List pns = new ArrayList (Arrays.asList(cm.getPropertyNames())); Map m = new HashMap(); for(String pn : pns) { m.put(pn, cm.getPropertyValue(o, pn)); } m.put(cm.getIdentifierPropertyName(), cm.getIdentifier(o)); return m; } }
并使用
Map aliasToValueMap = session.createCriteria(User.class) .add(Restrictions.idEq(userID)) .setResultTransformer(new IntrospectClassMetadata()) .uniqueResult();
最后的机会:
Map map = (Map)s.createSQLQuery("select * from user where id = :id") .setParameter("id",p.id) .setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE) .uniqueResult();
但这不会映射列表,包和其他映射对象,而只是原始列名和值…
您可以使用HQL并执行查询以选择结果作为新Map
select new Map(p.id as ID, p.name as name, p.email as email, p.age as age) from Player p
它将返回一组地图,每个地图都是查询结果中的一行。
您可以使用BeanUtils并执行以下操作:
User user = (User) session.get(User.class, userID); Map map = BeanUtils.describe(user);