Java SpringBoot-JPA或SQL查询以查找联接表中最常见的项?
我使用Spring Boot、JPA和MySQL创建了一个Spring Boot微服务,它由以下实体关系组成:Java SpringBoot-JPA或SQL查询以查找联接表中最常见的项?,java,mysql,spring-boot,maven,jpa,Java,Mysql,Spring Boot,Maven,Jpa,我使用Spring Boot、JPA和MySQL创建了一个Spring Boot微服务,它由以下实体关系组成: Owner can have multiple Cars. Cars can only have one Owner. pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.
Owner can have multiple Cars.
Cars can only have one Owner.
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.myapi</groupId>
<artifactId>car-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>car-api</name>
<description>Car REST API</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
业主地址:
@Repository
public interface OwnerRepository extends JpaRepository<Owner, Long> {
@Query(value = "SELECT * FROM owner WHERE name = ?", nativeQuery = true)
Owner findOwnerByName(String name);
}
@Repository
public interface CarRepository extends JpaRepository<Car, Long> {
}
正如你所看到的,汤姆·布雷迪、科比·布莱恩特、魔术师约翰逊都拥有保时捷911。。。那是这个列表中最常见的汽车
在幕后,JPA创建了如下表格:
轿厢台:
CREATE TABLE `car` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`battery_capacity` int(11) NOT NULL,
`make` varchar(255) DEFAULT NULL,
`model` varchar(255) DEFAULT NULL,
`year` varchar(255) DEFAULT NULL,
`owner_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK6wxv6hdekqn26n47pb7f1dt02` (`user_id`),
CONSTRAINT `FK6wxv6hdekqn26n47pb7f1dt02` FOREIGN KEY (`owner_id`) REFERENCES `owner` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
所有者表:
CREATE TABLE `owner` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`address` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`state` varchar(255) DEFAULT NULL,
`zip_code` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
从所有者中选择*:
选择id、用户id、c.make、c.model、c.year FROM cars c
JPA或SQL查询甚至可以是一个命名查询,我可以将其放在我的存储库中,该查询将返回最常见汽车的数据,例如Select count*和可能的Group By语句,该语句将表明最常见的汽车是保时捷911s,因为有3个人拥有它们?声明一个用于持有汽车的类别及其计数
public class CarStatistics {
private final Car car;
private final Long count;
public CarStatistics(Car car, Long count) {
this.car = car;
this.count = count;
}
public Car getCar() {
return car;
}
public Long getCount() {
return count;
}
}
从存储库方法按计数分组和排序返回bean实例:
public interface CarRepository extends JpaRepository<Car, Long> {
@Query("SELECT new com.example.CarStatistics(c, COUNT(c)) "
+ " FROM Car c "
+ " GROUP BY c.make, c.model "
+ " ORDER BY COUNT(c) DESC")
List<CarStatistics> findCarCount();
}
调用repository方法并获取结果集中的第一个对象:
@Service
public class CarService {
private final CarRepository carRepository;
public CarService(CarRepository carRepository) {
this.carRepository = carRepository;
}
public Car findMostCommonCar() {
List<CarStatistics> carStatistics = carRepository.findCarCount();
return carStatistics.get(0).getCar();
}
}
谢谢@Evgeniy Khyst。。。我很快就会试试的。在阅读你的解决方案之前,我发现了一个不同的解决方案。
[
{
"id": 1,
"name": "Tom Brady",
"cars": [
{
"id": 1,
"make": "Honda",
"model": "Accord",
"year": "2020"
},
{
"id": 11,
"make": "Nissan",
"model": "Maxima",
"year": "2019"
},
{
"id": 12,
"make": "Porsche",
"model": "911",
"year": "2017"
}
]
},
{
"id": 2,
"name": "Kobe Bryant",
"cars": [
{
"id": 2,
"make": "Porsche",
"model": "911",
"year": "2017"
}
]
},
{
"id": 3,
"name": "Mike Tyson",
"cars": [
{
"id": 3,
"make": "Volkswagen",
"model": "Beatle",
"year": "1973"
}
]
},
{
"id": 4,
"name": "Scottie Pippen",
"cars": [
{
"id": 4,
"make": "Ford",
"model": "F-150",
"year": "2010"
}
]
},
{
"id": 5,
"name": "John Madden",
"cars": [
{
"id": 5,
"make": "Chevrolet",
"model": "Silverado",
"year": "2020"
}
]
},
{
"id": 6,
"name": "Arnold Palmer",
"cars": [
{
"id": 6,
"make": "Toyota",
"model": "Camary",
"year": "2018"
}
]
},
{
"id": 7,
"name": "Tiger Woods",
"cars": [
{
"id": 7,
"make": "Alfa",
"model": "Romeo",
"year": "2017"
}
]
},
{
"id": 8,
"name": "Magic Johnson",
"cars": [
{
"id": 8,
"make": "Porsche",
"model": "911",
"year": "2017"
}
]
},
{
"id": 9,
"name": "George Foreman",
"cars": [
{
"id": 9,
"make": "Toyota",
"model": "Camary",
"year": "2018"
}
]
},
{
"id": 10,
"name": "Charles Barkley",
"cars": [
{
"id": 10,
"make": "Alfa",
"model": "Romeo",
"year": "2017"
}
]
}
]
CREATE TABLE `car` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`battery_capacity` int(11) NOT NULL,
`make` varchar(255) DEFAULT NULL,
`model` varchar(255) DEFAULT NULL,
`year` varchar(255) DEFAULT NULL,
`owner_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK6wxv6hdekqn26n47pb7f1dt02` (`user_id`),
CONSTRAINT `FK6wxv6hdekqn26n47pb7f1dt02` FOREIGN KEY (`owner_id`) REFERENCES `owner` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
CREATE TABLE `owner` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`address` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`state` varchar(255) DEFAULT NULL,
`zip_code` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+----+----------------+
| id | name |
+----+----------------+
| 1 | Tom Brady |
| 2 | Kobe Bryant |
| 3 | Mike Tyson |
| 4 | Scottie Pippen |
| 5 | John Madden |
| 6 | Arnold Palmer |
| 7 | Tiger Woods |
| 8 | Magic Johnson |
| 9 | George Foreman |
| 10 | Charles Barkley|
+----+----------------+
+----------------+--------------+------+
| id | make | model | year |
+----+-----------+-----------+---------+
| 1 | Honda | Accord | 2020 |
| 2 | Nissan | Leaf | 2029 |
| 3 | Volkswagen| Beatle | 1973 |
| 4 | Porsche | Taycan | 2020 |
| 5 | Ford | F-150 | 2010 |
| 6 | Chevrolet | Silverado | 2020 |
| 7 | Toyota | Camry | 2018 |
| 8 | Chevrolet | Bolt | 2020 |
| 9 | Honda | Clarity | 2018 |
| 10 | Hyundai | Ioniq | 2017 |
| 11 | Nissan | Maxima | 2019 |
| 12 | Porsche | 911 | 2020 |
+----+-----------+--------------+------+
public class CarStatistics {
private final Car car;
private final Long count;
public CarStatistics(Car car, Long count) {
this.car = car;
this.count = count;
}
public Car getCar() {
return car;
}
public Long getCount() {
return count;
}
}
public interface CarRepository extends JpaRepository<Car, Long> {
@Query("SELECT new com.example.CarStatistics(c, COUNT(c)) "
+ " FROM Car c "
+ " GROUP BY c.make, c.model "
+ " ORDER BY COUNT(c) DESC")
List<CarStatistics> findCarCount();
}
@Service
public class CarService {
private final CarRepository carRepository;
public CarService(CarRepository carRepository) {
this.carRepository = carRepository;
}
public Car findMostCommonCar() {
List<CarStatistics> carStatistics = carRepository.findCarCount();
return carStatistics.get(0).getCar();
}
}