pub struct OrmItemReader<'a, I>where
I: EntityTrait,{ /* private fields */ }orm only.Expand description
A reader for reading entities from a database using SeaORM.
This reader provides an implementation of the ItemReader trait for SeaORM-based
database operations. It supports reading entities from any SeaORM-compatible database
with optional pagination for efficient memory usage when dealing with large datasets.
§Generic Parameters
I: The SeaORM entity type that implementsEntityTrait
§Design Philosophy
This reader follows SeaORM’s conventions and leverages its built-in pagination
mechanisms for optimal performance. It provides a bridge between SeaORM’s async
API and the batch framework’s synchronous ItemReader trait.
§Memory Management
The reader uses an internal buffer to store entity models from the current page, which helps balance memory usage with query performance. When pagination is enabled, only one page of data is kept in memory at any time.
§Query Flexibility
Accepts any SeaORM Select query, allowing for complex filtering, joins, and
ordering. The query is executed as-is, with pagination parameters added when configured.
§State Management
offset: Tracks the absolute position across all pagescurrent_page: Tracks which page is currently loaded in the bufferbuffer: Holds the current page’s entity models
Implementations§
Source§impl<'a, I> OrmItemReader<'a, I>
impl<'a, I> OrmItemReader<'a, I>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new OrmItemReader with default configuration.
All parameters must be set using the builder methods before use. Use the builder pattern for a more convenient API.
§Returns
A new OrmItemReader instance with default settings.
§Examples
use spring_batch_rs::item::orm::OrmItemReader;
use sea_orm::{Database, EntityTrait};
let db = Database::connect("sqlite::memory:").await?;
// Using direct instantiation (less recommended)
// let reader = OrmItemReader::<MyEntity>::new()
// .connection(&db)
// .query(MyEntity::find())
// .page_size(100);
// Using builder (recommended)
// let reader = OrmItemReaderBuilder::new()
// .connection(&db)
// .query(MyEntity::find())
// .page_size(100)
// .build();Sourcepub fn connection(self, connection: &'a DatabaseConnection) -> Self
pub fn connection(self, connection: &'a DatabaseConnection) -> Self
Sets the database connection for the reader.
This is a required parameter that must be set before using the reader.
§Arguments
connection- Reference to the SeaORM database connection
§Returns
The updated OrmItemReader instance.
§Examples
use spring_batch_rs::item::orm::OrmItemReader;
use sea_orm::Database;
let db = Database::connect("sqlite::memory:").await?;
let reader = OrmItemReader::<String>::new()
.connection(&db);Sourcepub fn query(self, query: Select<I>) -> Self
pub fn query(self, query: Select<I>) -> Self
Sets the SeaORM select query for the reader.
This is a required parameter that must be set before using the reader. The query can include filtering, ordering, joins, and other SeaORM operations.
§Arguments
query- The SeaORM select query to execute
§Returns
The updated OrmItemReader instance.
§Examples
use spring_batch_rs::item::orm::OrmItemReader;
use sea_orm::EntityTrait;
// Basic query
// let reader = OrmItemReader::<MyEntity>::new()
// .query(MyEntity::find());
// Filtered query
// let reader = OrmItemReader::<MyEntity>::new()
// .query(MyEntity::find().filter(my_entity::Column::Active.eq(true)));
// Ordered query
// let reader = OrmItemReader::<MyEntity>::new()
// .query(MyEntity::find().order_by_asc(my_entity::Column::Id));Sourcepub fn page_size(self, page_size: u64) -> Self
pub fn page_size(self, page_size: u64) -> Self
Sets the page size for the reader.
When set, the reader will use pagination to limit memory usage. When not set, all data will be loaded at once.
§Arguments
page_size- The number of items to read per page
§Returns
The updated OrmItemReader instance.
§Performance Considerations
- Larger page sizes reduce the number of database round trips but use more memory
- Smaller page sizes use less memory but may result in more database queries
- Consider your dataset size and available memory when choosing a page size
- Recommended range: 50-1000 items per page for most use cases
§Examples
use spring_batch_rs::item::orm::OrmItemReader;
// Small page size for memory-constrained environments
let reader = OrmItemReader::<String>::new()
.page_size(50);
// Larger page size for better performance with ample memory
let reader = OrmItemReader::<String>::new()
.page_size(1000);Trait Implementations§
Source§impl<'a, I> Default for OrmItemReader<'a, I>
impl<'a, I> Default for OrmItemReader<'a, I>
Source§impl<I> ItemReader<<I as EntityTrait>::Model> for OrmItemReader<'_, I>
Implementation of ItemReader trait for OrmItemReader.
impl<I> ItemReader<<I as EntityTrait>::Model> for OrmItemReader<'_, I>
Implementation of ItemReader trait for OrmItemReader.
This implementation provides a way to read items from a database using SeaORM with support for pagination. It uses an internal buffer to store the results of database queries and keeps track of the current offset to determine when a new page of data needs to be fetched.
§Reading Strategy
The reader implements a lazy-loading strategy:
- First read: Loads the first page of data
- Subsequent reads: Returns items from the buffer
- Page boundary: When the buffer is exhausted, loads the next page
- End of data: Returns None when no more data is available
§State Management
offset: Tracks the absolute position across all pagescurrent_page: Tracks which page we’re currently reading frombuffer: Holds the current page’s data
The reader maintains these invariants:
offsetalways represents the next item to be readcurrent_pagerepresents the page currently loaded in the buffer- The buffer contains items for the current page only
Source§fn read(&self) -> ItemReaderResult<I::Model>
fn read(&self) -> ItemReaderResult<I::Model>
Reads the next item from the reader.
This method manages pagination internally and provides a simple interface for sequential reading. The complexity of pagination is hidden from the caller.
§Reading Algorithm
- Calculate buffer index: Determine where we are within the current page
- Check if new page needed: If at the start of a page, load new data
- Fetch from buffer: Get the item at the current index
- Update counters: Increment offset and page number as needed
- Return result: Clone the item or return None if exhausted
§Pagination Logic
- With pagination:
index = offset % page_size - Without pagination:
index = offset(all data in one “page”) - New page trigger: When
index == 0, we need to load a new page - Page advancement: When we reach the end of a page, increment
current_page
§Memory Management
Items are cloned when returned to ensure the caller owns the data. This prevents borrowing issues and allows the buffer to be modified for the next page load.
§Returns
Ok(Some(item))if an item was successfully readOk(None)if there are no more items to readErr(BatchError)if an error occurred during reading (e.g., database error)
§Examples
use spring_batch_rs::item::orm::OrmItemReaderBuilder;
use spring_batch_rs::core::item::ItemReader;
use sea_orm::FromQueryResult;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, FromQueryResult, Deserialize, Serialize)]
struct Product {
id: i32,
name: String,
price: f64,
}
// Assuming you have a database connection and query set up
// let reader = OrmItemReaderBuilder::new()
// .connection(&db)
// .query(products::Entity::find())
// .page_size(50)
// .build();
// Read all products
// let mut products = Vec::new();
// while let Some(product) = reader.read()? {
// products.push(product);
// }Auto Trait Implementations§
impl<'a, I> !Freeze for OrmItemReader<'a, I>
impl<'a, I> !RefUnwindSafe for OrmItemReader<'a, I>
impl<'a, I> Send for OrmItemReader<'a, I>
impl<'a, I> !Sync for OrmItemReader<'a, I>
impl<'a, I> Unpin for OrmItemReader<'a, I>
impl<'a, I> UnsafeUnpin for OrmItemReader<'a, I>
impl<'a, I> !UnwindSafe for OrmItemReader<'a, I>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.