У меня есть собственный запрос Mysql
select tl_id,c_name,m_name,u_first_name,t_name,
tl_logged_at,tl_minutes,tl_description
from users inner join clients on u_id=c_frn_owner_id
inner join matters on m_frn_client_id = c_id
inner join tasks on t_frn_matter_id = m_id
inner join task_logs on tl_frn_task_id = t_id
where c_id =2 and m_id=4 and t_id= 3 and u_id = 4
для которого я могу написать JPQL
вместо собственного запроса. Но как получить тот же запрос с помощью JPA Specification
, поскольку столбцы или поля в условиях where
c_id
, m_id
, t_id
и u_id
являются необязательными. Это параметры фильтра, предоставляемые пользователю.
Создание собственного запроса может быть выполнено с использованием условий if
. Но они подвержены опечаткам и SQL Injections
.
В документации JPASpecification
нет информации, связанной с объединением нескольких таблиц.
Официальный документ спецификации Spring JPA
Я новичок в JPASpecification
, поэтому любое руководство будет мне полезно.
JPA 2 introduces a criteria API that you can use to build queries programmatically.
Если вы используете JPA 2 и хотите создать динамический запрос, я думаю, вам следует взглянуть на API критериев для создания динамических запросов. Или вы можете использовать JpaSpecificationExecutor (я еще не пробовал). Проверьте вопрос, связанный с это.
Прилагаются некоторые полезные ссылки:
Взгляните на проект querydsl, я широко использую его в ERP среднего размера и до сих пор не разочаровался.
http://www.querydsl.com/static/querydsl/latest/reference/html/
для динамического предложения where: вы можете использовать com.querydsl.core.BooleanBuilder
Итак, когда у вас есть querydsl, вы можете сначала сгенерировать предложение where, как показано ниже.
QEmployee employee = QEmployee.employee;
BooleanBuilder dynamicWhere = new BooleanBuilder();
if (true) { //Any condition
dynamicWhere.and(employee.name.equalsIgnoreCase("someName"));
}
if (true){
dynamicWhere.and(employee.age.gt(18));
}
а затем вы можете написать свой запрос следующим образом.
queryFactory.selectFrom(employee)
//joins, group by, order by goes here
.where(dynamicWhere)
.fetch();