如何用HQL将多表查询结果直接映射到自定义SampleForm类
看来你是想跳过手动遍历集合的步骤,直接把两张表的数据映射到自定义的SampleForm类里对吧?其实不用自己写循环,用ORM框架或者对象映射工具就能搞定,我给你梳理几个可行的方案:
首先先把你的SampleForm类补全成符合JavaBean规范的样子——框架映射大多依赖getter/setter和合理的访问修饰符:
public class SampleForm { // 建议把字段设为private,符合封装原则 private List<Tbaudittrail> audittrail; private List<Tbauditevents> auditevents; // 带参构造 public SampleForm(List<Tbaudittrail> audittrail, List<Tbauditevents> auditevents) { this.audittrail = audittrail; this.auditevents = auditevents; } // 建议添加无参构造,部分ORM框架会要求这个 public SampleForm() {} // 补全getter和setter,框架需要这些来完成属性赋值 public List<Tbaudittrail> getAudittrail() { return audittrail; } public void setAudittrail(List<Tbaudittrail> audittrail) { this.audittrail = audittrail; } public List<Tbauditevents> getAuditevents() { return auditevents; } public void setAuditevents(List<Tbauditevents> auditevents) { this.auditevents = auditevents; } }
方案1:用MyBatis直接从数据库映射到SampleForm
如果你的项目用MyBatis,可以通过定义ResultMap来直接把联表查询的结果封装成SampleForm对象,完全不用手动处理集合:
- 先在MyBatis的XML映射文件里定义ResultMap:
<resultMap id="SampleFormResultMap" type="com.yourpackage.SampleForm"> <!-- 映射audittrail列表,ofType指定集合元素的类型 --> <collection property="audittrail" ofType="com.yourpackage.Tbaudittrail"> <id column="trail_id" property="id"/> <!-- 按你的实体类字段和数据库列名对应添加映射 --> <result column="trail_operation" property="operation"/> <result column="trail_time" property="operationTime"/> </collection> <!-- 映射auditevents列表 --> <collection property="auditevents" ofType="com.yourpackage.Tbauditevents"> <id column="event_id" property="id"/> <result column="event_type" property="eventType"/> <result column="event_detail" property="detail"/> </collection> </resultMap>
- 然后在Mapper接口里定义查询方法:
@Select("SELECT t.*, e.* FROM t_baudittrail t LEFT JOIN t_bauditevents e ON t.relation_id = e.relation_id") @ResultMap("SampleFormResultMap") SampleForm getSampleForm();
调用这个方法时,MyBatis会自动把查询结果封装成SampleForm对象,你直接用就行。
方案2:用Spring ModelMapper快速组装对象
如果已经从DAO层拿到了两个表的List数据(比如List<Tbaudittrail>和List<Tbauditevents>),可以用ModelMapper直接组装成SampleForm,不用写循环:
- 先在Spring容器里配置ModelMapper:
@Bean public ModelMapper modelMapper() { return new ModelMapper(); }
- 然后在业务代码里注入并使用:
@Autowired private ModelMapper modelMapper; // 假设已经从DAO获取到两个列表 List<Tbaudittrail> trailList = auditTrailRepository.findAll(); List<Tbauditevents> eventList = auditEventRepository.findAll(); // 直接用构造方法创建(或者用setter) SampleForm sampleForm = new SampleForm(trailList, eventList); // 如果是从其他复杂对象转换,也可以用modelMapper的map方法 // sampleForm = modelMapper.map(sourceComplexObject, SampleForm.class);
方案3:用JPA构造方法投影查询
如果你的项目用JPA,可以通过构造方法投影直接从数据库查询出SampleForm:
在Repository接口里定义查询方法:
@Query("SELECT new com.yourpackage.SampleForm(t, e) FROM Tbaudittrail t JOIN Tbauditevents e ON t.relationId = e.relationId") List<SampleForm> findAllSampleForms();
注意这里的构造方法参数顺序要和SampleForm的带参构造完全对应,JPA会自动把查询到的实体对象传入构造方法,生成SampleForm实例。
另外提醒下:如果之前你的SampleForm没有无参构造,最好补上——很多框架在做对象映射时会默认调用无参构造来创建实例。
内容的提问来源于stack exchange,提问作者Dekso
相关产品推荐
相关产品推荐

