分页
如果你的数据库中有数百万的记录,你肯定不希望将其一骨碌地给到同一个页面中。那样的话,客户端和服务端都无法承受。所以,你需要分页。
添加分页逻辑
调整方法参数,domain/gateway/book_manager.rs:
@@ -7,5 +7,5 @@ pub trait BookManager: Send + Sync {
fn update_book(&self, id: u32, b: &model::Book) -> Result<(), Box<dyn Error>>;
fn delete_book(&self, id: u32) -> Result<(), Box<dyn Error>>;
fn get_book(&self, id: u32) -> Result<Option<model::Book>, Box<dyn Error>>;
- fn get_books(&self) -> Result<Vec<model::Book>, Box<dyn Error>>;
+ fn get_books(&self, offset: u32) -> Result<Vec<model::Book>, Box<dyn Error>>;
}
为 get_books
方法添加名为 offset
的参数。
添加 page_size
配置项,infrastructure/config/mod.rs:
@@ -25,6 +25,7 @@ pub struct CacheConfig {
#[derive(Debug, Deserialize, Serialize)]
pub struct ApplicationConfig {
pub port: i32,
+ pub page_size: u32,
}
pub fn parse_config(file_name: &str) -> Config {
设置 page_size
配置值,config.toml:
@@ -1,5 +1,6 @@
[app]
port = 8080
+page_size = 5
[db]
file_name = "test.db"
合入 page_size
,application/wire_helper.rs:
@@ -13,7 +13,8 @@ pub struct WireHelper {
impl WireHelper {
pub fn new(c: &Config) -> Result<Self, Box<dyn std::error::Error>> {
- let sql_persistence = Arc::new(database::MySQLPersistence::new(&c.db.dsn)?);
+ let sql_persistence =
+ Arc::new(database::MySQLPersistence::new(&c.db.dsn, c.app.page_size)?);
let no_sql_persistence = Arc::new(database::MongoPersistence::new(
&c.db.mongo_uri,
&c.db.mongo_db_name,
更新查询逻辑,将 offset
和 page_size
考虑进去,infrastructure/database/mysql.rs:
@@ -9,12 +9,13 @@ use crate::domain::model;
pub struct MySQLPersistence {
pool: Pool,
+ page_size: u32,
}
impl MySQLPersistence {
- pub fn new(dsn: &str) -> Result<Self, MySQLError> {
+ pub fn new(dsn: &str, page_size: u32) -> Result<Self, MySQLError> {
let pool = Pool::new(dsn)?;
- Ok(MySQLPersistence { pool })
+ Ok(MySQLPersistence { pool, page_size })
}
}
@@ -93,10 +94,10 @@ impl BookManager for MySQLPersistence {
Ok(books.first().cloned())
}
- fn get_books(&self) -> Result<Vec<model::Book>, Box<dyn Error>> {
+ fn get_books(&self, offset: u32) -> Result<Vec<model::Book>, Box<dyn Error>> {
let mut conn = self.pool.get_conn()?;
let books = conn.query_map(
- "SELECT * FROM books",
+ format!("SELECT * FROM books LIMIT {}, {}", offset, self.page_size),
|(
id,
title,
调整缓存键,application/executor/book_operator.rs:
@@ -30,15 +30,16 @@ impl BookOperator {
self.book_manager.get_book(id)
}
- pub fn get_books(&self) -> Result<Vec<model::Book>, Box<dyn std::error::Error>> {
- let raw_value = self.cache_helper.load(BOOKS_KEY)?;
+ pub fn get_books(&self, offset: u32) -> Result<Vec<model::Book>, Box<dyn std::error::Error>> {
+ let k = format!("{}-{}", BOOKS_KEY, offset);
+ let raw_value = self.cache_helper.load(&k)?;
if let Some(v) = raw_value {
let cached_books = serde_json::from_str(&v)?;
Ok(cached_books)
} else {
- let fetched_books = self.book_manager.get_books()?;
+ let fetched_books = self.book_manager.get_books(offset)?;
let v = serde_json::to_string(&fetched_books)?;
- self.cache_helper.save(BOOKS_KEY, &v)?;
+ self.cache_helper.save(&k, &v)?;
Ok(fetched_books)
}
}
最后一步,在 adapter/router.rs 中传递 query 参数:
@@ -24,11 +24,12 @@ pub fn health_check() -> content::RawJson<&'static str> {
content::RawJson("{\"status\":\"ok\"}")
}
-#[get("/books")]
+#[get("/books?<o>")]
pub fn get_books(
rest_handler: &rocket::State<RestHandler>,
+ o: Option<u32>,
) -> Result<Json<Vec<model::Book>>, status::Custom<Json<ErrorResponse>>> {
- match rest_handler.book_operator.get_books() {
+ match rest_handler.book_operator.get_books(o.unwrap_or(0)) {
Ok(books) => Ok(Json(books)),
Err(err) => Err(status::Custom(
Status::InternalServerError,
好啦!改完啦!让我们试下。
使用 curl 测试
放入待测试数据
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "published_at": "1925-04-10", "description": "A novel depicting the opulent lives of wealthy Long Island residents during the Jazz Age.", "isbn": "9780743273565", "total_pages": 218}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "To Kill a Mockingbird", "author": "Harper Lee", "published_at": "1960-07-11", "description": "A novel set in the American South during the 1930s, dealing with themes of racial injustice and moral growth.", "isbn": "9780061120084", "total_pages": 281}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "1984", "author": "George Orwell", "published_at": "1949-06-08", "description": "A dystopian novel depicting a totalitarian regime, surveillance, and propaganda.", "isbn": "9780451524935", "total_pages": 328}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "Pride and Prejudice", "author": "Jane Austen", "published_at": "1813-01-28", "description": "A classic novel exploring the themes of love, reputation, and social class in Georgian England.", "isbn": "9780486284736", "total_pages": 279}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Catcher in the Rye", "author": "J.D. Salinger", "published_at": "1951-07-16", "description": "A novel narrated by a disaffected teenager, exploring themes of alienation and identity.", "isbn": "9780316769488", "total_pages": 277}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Lord of the Rings", "author": "J.R.R. Tolkien", "published_at": "1954-07-29", "description": "A high fantasy epic following the quest to destroy the One Ring and defeat the Dark Lord Sauron.", "isbn": "9780544003415", "total_pages": 1178}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "Moby-Dick", "author": "Herman Melville", "published_at": "1851-10-18", "description": "A novel exploring themes of obsession, revenge, and the nature of good and evil.", "isbn": "9780142000083", "total_pages": 624}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Hobbit", "author": "J.R.R. Tolkien", "published_at": "1937-09-21", "description": "A fantasy novel set in Middle-earth, following the adventure of Bilbo Baggins and the quest for treasure.", "isbn": "9780345339683", "total_pages": 310}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Adventures of Huckleberry Finn", "author": "Mark Twain", "published_at": "1884-12-10", "description": "A novel depicting the journey of a young boy and an escaped slave along the Mississippi River.", "isbn": "9780486280615", "total_pages": 366}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "War and Peace", "author": "Leo Tolstoy", "published_at": "1869-01-01", "description": "A novel depicting the Napoleonic era in Russia, exploring themes of love, war, and historical determinism.", "isbn": "9781400079988", "total_pages": 1392}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "Alice’s Adventures in Wonderland", "author": "Lewis Carroll", "published_at": "1865-11-26", "description": "A children’s novel featuring a young girl named Alice who falls into a fantastical world populated by peculiar creatures.", "isbn": "9780141439761", "total_pages": 192}' http://localhost:8000/books
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Odyssey", "author": "Homer", "published_at": "8th Century BC", "description": "An ancient Greek epic poem attributed to Homer, detailing the journey of Odysseus after the Trojan War.", "isbn": "9780140268867", "total_pages": 541}' http://localhost:8000/books
列出第一页的图书
curl -X GET http://localhost:8000/books
结果:
[
{
"id": 3,
"title": "Sample Book",
"author": "John Doe",
"published_at": "2023-01-01",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200,
"created_at": "2024-03-01 12:40:16",
"updated_at": "2024-03-01 12:40:16"
},
{
"id": 4,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"published_at": "1925-04-10",
"description": "A novel depicting the opulent lives of wealthy Long Island residents during the Jazz Age.",
"isbn": "9780743273565",
"total_pages": 218,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 5,
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"published_at": "1960-07-11",
"description": "A novel set in the American South during the 1930s, dealing with themes of racial injustice and moral growth.",
"isbn": "9780061120084",
"total_pages": 281,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 6,
"title": "1984",
"author": "George Orwell",
"published_at": "1949-06-08",
"description": "A dystopian novel depicting a totalitarian regime, surveillance, and propaganda.",
"isbn": "9780451524935",
"total_pages": 328,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 7,
"title": "Pride and Prejudice",
"author": "Jane Austen",
"published_at": "1813-01-28",
"description": "A classic novel exploring the themes of love, reputation, and social class in Georgian England.",
"isbn": "9780486284736",
"total_pages": 279,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
}
]
列出偏移之后的图书:
curl -X GET "http://localhost:8000/books?o=5"
结果:
[
{
"id": 8,
"title": "The Catcher in the Rye",
"author": "J.D. Salinger",
"published_at": "1951-07-16",
"description": "A novel narrated by a disaffected teenager, exploring themes of alienation and identity.",
"isbn": "9780316769488",
"total_pages": 277,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 9,
"title": "The Lord of the Rings",
"author": "J.R.R. Tolkien",
"published_at": "1954-07-29",
"description": "A high fantasy epic following the quest to destroy the One Ring and defeat the Dark Lord Sauron.",
"isbn": "9780544003415",
"total_pages": 1178,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 10,
"title": "Moby-Dick",
"author": "Herman Melville",
"published_at": "1851-10-18",
"description": "A novel exploring themes of obsession, revenge, and the nature of good and evil.",
"isbn": "9780142000083",
"total_pages": 624,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 11,
"title": "The Hobbit",
"author": "J.R.R. Tolkien",
"published_at": "1937-09-21",
"description": "A fantasy novel set in Middle-earth, following the adventure of Bilbo Baggins and the quest for treasure.",
"isbn": "9780345339683",
"total_pages": 310,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 12,
"title": "The Adventures of Huckleberry Finn",
"author": "Mark Twain",
"published_at": "1884-12-10",
"description": "A novel depicting the journey of a young boy and an escaped slave along the Mississippi River.",
"isbn": "9780486280615",
"total_pages": 366,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
}
]
列出另一个偏移后的图书:
curl -X GET "http://localhost:8000/books?o=10"
结果:
[
{
"id": 13,
"title": "War and Peace",
"author": "Leo Tolstoy",
"published_at": "1869-01-01",
"description": "A novel depicting the Napoleonic era in Russia, exploring themes of love, war, and historical determinism.",
"isbn": "9781400079988",
"total_pages": 1392,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 14,
"title": "Alice’s Adventures in Wonderland",
"author": "Lewis Carroll",
"published_at": "1865-11-26",
"description": "A children’s novel featuring a young girl named Alice who falls into a fantastical world populated by peculiar creatures.",
"isbn": "9780141439761",
"total_pages": 192,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 15,
"title": "The Odyssey",
"author": "Homer",
"published_at": "8th Century BC",
"description": "An ancient Greek epic poem attributed to Homer, detailing the journey of Odysseus after the Trojan War.",
"isbn": "9780140268867",
"total_pages": 541,
"created_at": "2024-03-02 05:48:25",
"updated_at": "2024-03-02 05:48:25"
},
{
"id": 16,
"title": "Sample Book",
"author": "John Doe",
"published_at": "2023-01-01",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200,
"created_at": "2024-03-07 10:17:59",
"updated_at": "2024-03-07 10:17:59"
},
{
"id": 17,
"title": "Sample Book",
"author": "John Doe",
"published_at": "2023-01-01",
"description": "A sample book description",
"isbn": "1234567890",
"total_pages": 200,
"created_at": "2024-03-07 10:18:20",
"updated_at": "2024-03-07 10:18:20"
}
]
看来分页功能一切正常!进展不错!