【Spring Boot】SpringDataJpa/集計関数等使用時に、new xxxClass()を使用しない方法を試してみた。

この記事は、@kagamihogeさんの「<a href="https://qiita.com/kagamihoge/items/b299d17a20f86f03562c">spring-data-jpaの@Queryでカスタムオブジェクトを返す</a>」の記事を参考にして実施してみたものです。@kagamihogeさん有難うございました。

````CustomerRepository.java
package hello;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface CustomerRepository extends JpaRepository<Customer, Long> {

    @Query("SELECT cu.lastName AS lastName, Count(cu.id) AS cnt FROM Customer cu GROUP BY cu.lastName")
    List<CustomerGroupByLastName> GroupByLastName();

    public static interface CustomerGroupByLastName {
        public String getLastName();
        public long getCnt();
    }
}
````

````Customer.java
package hello;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String firstName;
    private String lastName;

    protected Customer() {}

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format(
                "Customer[id=%d, firstName='%s', lastName='%s']",
                id, firstName, lastName);
    }
}
````

````Application.java
package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {

	private static final Logger log = LoggerFactory.getLogger(Application.class);

	public static void main(String[] args) {
		SpringApplication.run(Application.class);
	}

	@Bean
	public CommandLineRunner demo(CustomerRepository repository) {
		return (args) -> {
			// save a couple of customers
			repository.save(new Customer("Jack", "Bauer"));
			repository.save(new Customer("Chloe", "O'Brian"));
			repository.save(new Customer("Kim", "Bauer"));
			repository.save(new Customer("David", "Palmer"));
			repository.save(new Customer("Michelle", "Dessler"));

			// fetch all customers
			log.info("Customers found with findAll():");
			log.info("-------------------------------");
			for (Customer customer : repository.findAll()) {
				log.info(customer.toString());
			}
			log.info("");

			// Customers'Count GroupByLastName
			log.info("Customers'Count GroupByLastName with GroupByLastName():");
			log.info("--------------------------------------------");
			repository.GroupByLastName().forEach(result -> {
				log.info("LastName = " + result.getLastName() + " Count = " + result.getCnt());
			});
			log.info("");
		};
	}
}
````

````実行結果.log
hello.Application : Started Application in 3.026 seconds (JVM running for 4.501)
hello.Application : Customers found with findAll():
hello.Application : -------------------------------
hello.Application : Customer[id=1, firstName='Jack', lastName='Bauer']
hello.Application : Customer[id=2, firstName='Chloe', lastName='O'Brian']
hello.Application : Customer[id=3, firstName='Kim', lastName='Bauer']
hello.Application : Customer[id=4, firstName='David', lastName='Palmer']
hello.Application : Customer[id=5, firstName='Michelle', lastName='Dessler']
hello.Application : 
hello.Application : Customers'Count GroupByLastName with GroupByLastName():
hello.Application : --------------------------------------------
hello.Application : LastName = Bauer Count = 2
hello.Application : LastName = O'Brian Count = 1
hello.Application : LastName = Palmer Count = 1
hello.Application : LastName = Dessler Count = 1
hello.Application : 
````

併せて、こちらの記事も参考ください。
「<a href="https://qiita.com/Hisashi-Yamauchi/items/d4cdb5c321255d141a13">SpringDataJpa/集計関数等使用時に、新しいJavaBeansを作成するのではなく既存Entityを流用して実装してみた</a>」