JPA对数据库表进行简单的增删改查非常简单,大多数情况下使用JpaRepository
的函数就可以达到目的。
有时我们也会做一些复杂的条件查询,只需在函数上一行添加@Query()
也能达到目的。
@Repository()
public interface ApplicationRepository extends JpaRepository<ApplicationDTO, Integer>{
// 模糊查询
@Query("select u from ApplicationDTO u where (u.state = ?1 OR ?1 IS NULL)")
List<ApplicationDTO> findByState(Integer state);
// 模糊查询
@Query("select u from ApplicationDTO u where (u.state = ?1 OR ?1 IS NULL)")
Page<ApplicationDTO> findByState(Integer state, Pageable pageable);
}
但如果我们要做一些聚合查询,例如left join,就会遇到麻烦。
JpaRepository
要求添加实体泛型,如JpaRepository<ApplicationDTO, Integer>
。聚合查询时多张表关联查询,返回的数据类型不能定义成@Entity
,该注解是与数据库表直接映射的;数据类型不定义@Entity
又会在启动时报错。
使用javax.persistence.EntityManager
手动创建查询可以避免上面问题。下面以left join为例:
private List<TenantApp> getApp() {
EntityManager entityManager = BeanFactory.getBean(EntityManager.class);
Query query = entityManager.createNativeQuery("select a.app_name, t.project_name, a.app_identifier from t_application a left join t_project t on a.project_id = t.id");
List<Object[]> list = query.getResultList();
return list.stream().map( arr -> {
Application app = new Application();
app.setAppName(String.valueOf(arr[0]));
app.setProjectName(String.valueOf(arr[1]));
app.setAppIdentifier(String.valueOf(arr[2]));
return app;
}).collect(Collectors.toList());
}
其中BeanFactory
代码如下
@Component
public class BeanFactory implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
// TODO Auto-generated method stub
BeanFactory.applicationContext = arg0;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
}