基于SSH框架的多表联查DAO代码简化优化建议咨询
SSH框架多表联查DAO层代码优化方案
核心问题说明
你调用list()方法返回的res是List类型,本身就没有JDBC ResultSet的next()方法,用size()获取长度属于正常用法,无需调整。
优化方案1:通过字段名获取结果(满足row["name"]类需求)
给原生SQL查询设置ALIAS_TO_ENTITY_MAP结果转换器,直接返回Map结构,用字段名作为key取值,无需依赖下标:
public List<Model> getData() throws HibernateException { List<Model> list = new ArrayList<>(); String query = "SELECT table1.*, table2.* FROM table1, table2 WHERE table1.bridge_id = table2.bridge_id"; List<Map<String, Object>> res = this.sessionFactory.getCurrentSession() .createSQLQuery(query) // 核心配置:将查询结果转为Map,key为查询字段名 .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP) .list(); for (Map<String, Object> row : res) { Model model = new Model(); // 直接通过字段名取值,无需记下标 model.setName((String) row.get("name")); model.setDate((Date) row.get("date")); list.add(model); } return list; }
优化方案2:自动映射到实体类(极致简化,无需手动赋值)
如果你的SQL查询字段别名和Model类的属性名完全对应,可以直接用aliasToBean转换器,自动完成结果到实体的映射,省略循环赋值逻辑:
public List<Model> getData() throws HibernateException { String query = "SELECT " + // 字段别名和Model属性名保持一致即可自动映射,比如表字段create_date要写为create_date as createDate对应Model的createDate属性 "table1.name as name, table2.date as date " + "FROM table1, table2 WHERE table1.bridge_id = table2.bridge_id"; return this.sessionFactory.getCurrentSession() .createSQLQuery(query) // 核心配置:自动映射到指定实体类 .setResultTransformer(Transformers.aliasToBean(Model.class)) .list(); }
注意事项
- Hibernate 5.2及以上版本
Transformers被标记为过时,你可以自定义ResultTransformer实现类实现相同逻辑,旧版本可正常使用无问题。 - 多表查询有同名字段时,必须在SQL里给字段起别名,避免映射冲突。
内容的提问来源于stack exchange,提问作者naufal hilmi
相关产品推荐
相关产品推荐

