在 Spring 内做 JOIN 联查
数据库 ORM 框架大部分情况下都是为了方便进行数据库操作——只需要操作一个结构体,就可以将修改同步至数据库中,增删改查都可以被屏蔽为对一个对象的操作。
但是由于结构和数据库深度绑定,因此对于类似于多表联查的需求反而变得更麻烦:
- 一方面是关联的条件难以描述
- 另一方面是返回的数据结构没有适当的结构存储
简单来说,大部分类似的需求,都需要使用外键来实现,也就是 OneToOne、OneToMany、ManyToOne、ManyToMany 之类的
但是有时候数据之间并不希望有外键这个关系,因此只能回归原生 SQL 查询
(这么看,框架本身反而增加了工作量)
这里的 SQL 与标准的 SQL 并不完全等价,因为结果必然会返回为一个对象,因此SELECT
部分,应该是一个对象的构造函数(按照 Java 的写法)。
只需要提前声明一个类,并且拥有相应入参个数和类型的构造函数,那么就可以将查询结果存入一个该类型的对象中。
@Service @Component public class XXXService { @PersistenceContext private EntityManager em; public List<XXX> search(long start, long end) { StringBuilder sb = new StringBuilder(); sb.append( "SELECT new XXX(a.id, a.name, a.id2, b.name2) FROM A a, B b WHERE a.id2=b.id" ); if (start != 0 && end != 0) { sb.append(" AND a.timestamp BETWEEN"); sb.append(start); sb.append(" AND "); sb.append(end); } else if (start != 0) { sb.append(" AND a.timestamp > "); sb.append(start); } else if (end != 0) { sb.append(" AND a.timestamp < "); sb.append(end); } List<XXX> res = em.createQuery(sb.toString()).getResultList(); return res; } }