java - 如何避免 if-else 树代码?
问题描述
我有一个休息控制器,其中包括一种根据“标题”和“作者”参数查找书籍的方法。
你能给我任何提示如何摆脱 if-else 结构吗?现在它并不复杂,但将来参数的数量可能会增加,这将导致混乱。
@GetMapping
public ResponseEntity<List<Book>> searchBooksByTitleAndAuthor(
@RequestParam(value = "title", required = false) String title,
@RequestParam(value = "author", required = false) String author) {
if (title == null && author == null) {
log.info("Empty request");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} else if (title != null && author == null) {
log.info("Retrieving books by title");
List<Book> books = bookService.getBooksByTitle(title);
if (books.isEmpty()) {
log.info("No books with this title");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(books, HttpStatus.OK);
} else if (author != null && title == null) {
List<Book> books = bookService.getBooksByTitle(title);
if (books.isEmpty()) {
log.info("No books with this title");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(books, HttpStatus.OK);
} else {
List<Book> books = bookService.getBooksByTitleAndAuthor(title, author);
if (books.isEmpty()) {
log.info("No books with matching this title and author");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(books, HttpStatus.OK);
}
}
解决方案
由于您的计划是最终支持更多参数,因此您最好的选择可能是研究Hibernate 的Criteria
class。这允许您动态构建查询。它不会避免if
语句,但会避免else
语句并使支持新参数变得非常容易。在您的存储库/DAO 级别:
Criteria criteria = session.createCriteria(Book.class);
if (author != null && !author.isEmpty()) {
criteria.add(Restriction.eq("author", author));
}
if (title != null && !title.isEmpty()) {
criteria.add(Restriction.eq("title", title));
}
criteria.addOrder(Order.asc("publishDate"));
return (List<Book>) criteria.list();
这有一些显着的好处:
要支持新参数,您只需将参数添加到控制器,然后将参数传递到存储库,并将参数添加到此块。
您最终可以使您的排序可配置,例如:
?sort=title:asc&author=Bobby%20Tables
但是,有一些缺点,最明显的是它依赖于字符串值来引用您的属性。如果您的属性名称发生更改(注意这是 POJO 属性,而不是 DB 列名称),则需要更改此代码。但是,我认为这是一种非常罕见的情况,除非在最新的新项目中数据库模式仍在不断变化,并且在建立数据库模式之后,这种缺点很少会引起问题。
另一个提示,一旦你达到了一定数量的传入参数(例如 4-5 个),就创建一个参数对象来将你的参数包装成一个可以传递的漂亮对象。
推荐阅读
- php - Wordpress/Woocommerce 插件代码未显示
- javascript - 在反应绑定中,“this”指的是什么?
- nginx - docker compose:浏览器无法访问与 nginx 共享的文件
- visual-studio-code - 如何在 vscode(MAC) 上启用 c++17
- shiny - 在 R Shiny 中推送重置时如何清除“隔离”变量
- email - SendGrid 总是将我的电子邮件发送到收件人的垃圾邮件文件夹
- python-3.x - 为什么 sns.lineplot 不显示我的情节中的置信区间?
- sql - 有人可以帮我在 PL/SQL Oracle 中实现以下触发器吗?
- angular - 如何在特定测试级别禁用更改检测
- android - 第一次安装 android 应用程序时如何从 Firebase 实时数据库获取数据库