package com.querydsl.example.dao;
import com.querydsl.core.dml.StoreClause;
import com.querydsl.core.group.GroupBy;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.QBean;
import com.querydsl.example.dto.Product;
import com.querydsl.example.dto.ProductL10n;
import com.querydsl.example.dto.Supplier;
import com.querydsl.sql.SQLQueryFactory;
import com.querydsl.sql.dml.SQLInsertClause;
import org.springframework.transaction.annotation.Transactional;
import javax.inject.Inject;
import java.util.List;
import static com.querydsl.core.types.Projections.bean;
import static com.querydsl.example.sql.QProduct.product;
import static com.querydsl.example.sql.QProductL10n.productL10n;
import static com.querydsl.example.sql.QSupplier.supplier;
@Transactional
public class ProductDaoImpl implements ProductDao {
@Inject
SQLQueryFactory queryFactory;
final QBean<ProductL10n> productL10nBean = bean(ProductL10n.class,
productL10n.description, productL10n.lang, productL10n.name);
final QBean<Product> productBean = bean(Product.class,
product.id, product.name, product.otherProductDetails, product.price,
bean(Supplier.class, supplier.all()).as("supplier"),
GroupBy.set(productL10nBean).as("localizations"));
@Override
public Product findById(long id) {
List<Product> persons = findAll(product.id.eq(id));
return persons.isEmpty() ? null : persons.get(0);
}
@Override
public List<Product> findAll(Predicate... where) {
return queryFactory.from(product)
.innerJoin(product.supplierFk, supplier)
.innerJoin(product._productFk, productL10n)
.where(where)
.transform(GroupBy.groupBy(product.id).list(productBean));
}
private <T extends StoreClause<T>> T populate(T dml, Product p) {
return dml.set(product.name, p.getName())
.set(product.otherProductDetails, p.getOtherProductDetails())
.set(product.price, p.getPrice())
.set(product.supplierId, p.getSupplier().getId());
}
@Override
public Product save(Product p) {
Long id = p.getId();
if (id == null) {
id = populate(queryFactory.insert(product), p)
.executeWithKey(product.id);
p.setId(id);
} else {
populate(queryFactory.update(product), p)
.where(product.id.eq(id))
.execute();
// delete l10n rows
queryFactory.delete(productL10n)
.where(productL10n.productId.eq(id))
.execute();
}
SQLInsertClause insert = queryFactory.insert(productL10n);
for (ProductL10n l10n : p.getLocalizations()) {
insert.set(productL10n.productId, id)
.set(productL10n.description, l10n.getDescription())
.set(productL10n.lang, l10n.getLang())
.set(productL10n.name, l10n.getName())
.addBatch();
}
insert.execute();
return p;
}
@Override
public long count() {
return queryFactory.from(product).fetchCount();
}
@Override
public void delete(Product p) {
// TODO use combined delete clause
queryFactory.delete(productL10n)
.where(productL10n.productId.eq(p.getId()))
.execute();
queryFactory.delete(product)
.where(product.id.eq(p.getId()))
.execute();
}
}