package com.querydsl.example.dao;
import com.querydsl.core.group.GroupBy;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.QBean;
import com.querydsl.example.dto.Address;
import com.querydsl.example.dto.Customer;
import com.querydsl.example.dto.CustomerAddress;
import com.querydsl.example.dto.Person;
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.QAddress.address;
import static com.querydsl.example.sql.QCustomer.customer;
import static com.querydsl.example.sql.QCustomerAddress.customerAddress;
import static com.querydsl.example.sql.QPerson.person;
@Transactional
public class CustomerDaoImpl implements CustomerDao {
@Inject
SQLQueryFactory queryFactory;
final QBean<CustomerAddress> customerAddressBean = bean(CustomerAddress.class,
customerAddress.addressTypeCode, customerAddress.fromDate, customerAddress.toDate,
bean(Address.class, address.all()).as("address"));
final QBean<Customer> customerBean = bean(Customer.class,
customer.id, customer.name,
bean(Person.class, person.all()).as("contactPerson"),
GroupBy.set(customerAddressBean).as("addresses"));
@Override
public Customer findById(long id) {
List<Customer> customers = findAll(customer.id.eq(id));
return customers.isEmpty() ? null : customers.get(0);
}
@Override
public List<Customer> findAll(Predicate... where) {
return queryFactory.from(customer)
.leftJoin(customer.contactPersonFk, person)
.leftJoin(customer._customer3Fk, customerAddress)
.leftJoin(customerAddress.addressFk, address)
.where(where)
.transform(GroupBy.groupBy(customer.id).list(customerBean));
}
@Override
public Customer save(Customer c) {
Long id = c.getId();
if (id == null) {
id = queryFactory.insert(customer)
.set(customer.name, c.getName())
.set(customer.contactPersonId, c.getContactPerson().getId())
.executeWithKey(customer.id);
c.setId(id);
} else {
queryFactory.update(customer)
.set(customer.name, c.getName())
.set(customer.contactPersonId, c.getContactPerson().getId())
.where(customer.id.eq(c.getId()))
.execute();
// delete address rows
queryFactory.delete(customerAddress)
.where(customerAddress.customerId.eq(id))
.execute();
}
SQLInsertClause insert = queryFactory.insert(customerAddress);
for (CustomerAddress ca : c.getAddresses()) {
if (ca.getAddress().getId() == null) {
ca.getAddress().setId(queryFactory.insert(address)
.populate(ca.getAddress())
.executeWithKey(address.id));
}
insert.set(customerAddress.customerId, id)
.set(customerAddress.addressId, ca.getAddress().getId())
.set(customerAddress.addressTypeCode, ca.getAddressTypeCode())
.set(customerAddress.fromDate, ca.getFromDate())
.set(customerAddress.toDate, ca.getToDate())
.addBatch();
}
insert.execute();
c.setId(id);
return c;
}
@Override
public long count() {
return queryFactory.from(customer).fetchCount();
}
@Override
public void delete(Customer c) {
// TODO use combined delete clause
queryFactory.delete(customerAddress)
.where(customerAddress.customerId.eq(c.getId()))
.execute();
queryFactory.delete(customer)
.where(customer.id.eq(c.getId()))
.execute();
}
}