Spring Boot 和 Hibernate 在这里。我有以下 JPA 实体:
@Entity(name = "decision_analytics")
@Table(schema = "mydb")
@Data
public class DecisionAnalytics {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "client_name")
private String clientName;
@Column(name = "amount")
private BigDecimal amount;
// lots of other fields here, omitted for brevity
}
对应这张表:
CREATE TABLE mydb.analytics.decision_analytics (
id int IDENTITY(1,1) NOT NULL,
client_name varchar(MAX) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
amount float NULL,
-- again, lots of other columns here, omitted for brevity
);
要从该表中获取该实体的记录,我有以下控制器:
@RestController
@RequestMapping("api/v1/decision-analytics")
public class DecisionController {
@Autowired
private DecisionAnalyticsService daService;
@GetMapping("/{clientName}")
public ResponseEntity<?> getDecisionAnalytics(@PathVariable("clientName") String clientName, @RequestParam Integer pageNo, @RequestParam Integer pageSize) {
List<DecisionAnalytics> da = daService.getDecisionAnalytics(clientName, pageNo, pageSize);
return ResponseEntity.ok(da);
}
}
使用这些服务和存储库类/方法:
@Service
public class DecisionAnalyticsService {
@Autowired
private DecisionAnalyticsRepository daRepository;
public List<DecisionAnalytics> getDecisionAnalytics(String clientName, Integer pageNo, Integer pageSize) {
Pageable pageable = PageRequest.of(pageNo, pageSize);
List<DecisionAnalytics> daList = daRepository.findByClientNameOrderByAmount(clientName, pageable);
// do other stuff down here
return daList;
}
}
@Repository
public interface DecisionAnalyticsRepository extends JpaRepository<DecisionAnalytics, Long> {
List<DecisionAnalytics> findByClientNameOrderByAmount(String clientName, Pageable pageable);
}
以上所有工作都非常好。有now一个新实体,
DecisionMeta
:
@Entity
@Table(name = "decision_meta", schema = "mydb")
@Data
public class DecisionMeta {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
// see below -- cannot be a DecisionAnalytics instance w/ @OneToOne, etc.
@Column(name = "decision_analytic_id")
private Long decisionAnalyticId;
@Column(name = "status")
private String status;
}
对应一个新表:
CREATE TABLE mydb.decision_meta (
id int IDENTITY(1,1) NOT NULL,
decision_analytic_id int NULL,
status varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
);
问题来了:
[decision_meta].[decision_analytic_id]
是一个整数,但 not 是 [decision_analytics]
表的外键。哦,它应该,但它不是,也不可能是出于这个问题范围之外的(不是很好的)原因。因此,虽然 [decision_meta].[decision_analytic_id]
看起来,行为并将用作 if 它将成为 [decision_analytics]
表的外键,但没有实际的 FK 约束,我无法添加一个。非常重要的是要呼唤[decision_meta].[decision_analytic_id]
可以,有时是null
。
所以目前
DecisionAnalyticsController#fetchDecisionAnalytics(...)
端点方法:
client_name
与通过路径参数在HTTP请求中发送的内容不匹配的记录;和我现在需要进一步过滤那个端点,这样它:
client_name
与通过路径参数在HTTP请求中发送的内容不匹配的记录(同上);和DecisionAnalytics
id
存在于[decision_meta].[decision_analytic_id]
列和[decision_meta].[status]
值为"ACTIVE"
所以在 SQL 形式中,查询将是 something like:
SELECT *
FROM decision_analytics da
INNER JOIN decision_meta dm
ON da.id = dm.decision_analytic_id
WHERE
da.client_name = ?
AND
dm.decision_analytic_id IS NOT NULL
AND
dm.status = 'ACTIVE'
...当然,在 Spring 层上也应用了页码/大小。
所以如果我的表中有以下记录:
[decision_analytics]
===
id | client_name | ...other columns ... | amount
1 | ACME | ...other... | 43.12
2 | Fizzbuzz | ...other... | 144.38
3 | ACME | ...other... | 9.16
[decision_meta]
===
id | decision_analytic_id | ...other columns... | status
1 | null | ...other... | NOT_ACTIVE
2 | 3 | ...other... | null
3 | 2 | ...other... | ACTIVE
4 | null | ...other... | null
然后只返回
decision_analytics
的第二行(id=2):
2 | Fizzbuzz | ...other... | 144.38
...因为该记录与
decision_meta
记录相关联并且具有 ACTIVE
状态。
我正在努力弄清楚
DecisionAnalyticsRepository#findByClientNameOrderByAmount(...)
方法需要如何更改(可能添加特定的 @Query
注释)以适应这些更改后的标准并且仍然是 Pageable
。谁能指出我正确的方向?提前致谢!