/*
* repository.cj - 仓库模块
*
* 提供类似 Spring Data JPA 的 CRUD 仓库接口和基础实现。
*/
package tybb2026::tycj_orm
import std.collection.*
/*
* CRUD 仓库接口
* 定义基本的增删改查操作
*/
public interface CrudRepository<T, ID> {
/*
* 保存实体(插入或更新)
* @param entity 实体对象
* @return 保存后的实体
*/
func save(entity: T): T
/*
* 批量保存实体
* @param entities 实体列表
* @return 保存后的实体列表
*/
func saveAll(entities: ArrayList<T>): ArrayList<T>
/*
* 根据 ID 查找实体
* @param id 主键值
* @return 实体选项
*/
func findById(id: ID): Option<T>
/*
* 判断实体是否存在
* @param id 主键值
* @return 是否存在
*/
func existsById(id: ID): Bool
/*
* 查询所有实体
* @return 实体列表
*/
func findAll(): ArrayList<T>
/*
* 根据 ID 列表查询实体
* @param ids 主键值列表
* @return 实体列表
*/
func findAllById(ids: ArrayList<ID>): ArrayList<T>
/*
* 统计实体数量
* @return 实体数量
*/
func count(): Int64
/*
* 根据 ID 删除实体
* @param id 主键值
*/
func deleteById(id: ID): Unit
/*
* 删除实体
* @param entity 实体对象
*/
func delete(entity: T): Unit
/*
* 批量删除实体
* @param entities 实体列表
*/
func deleteAll(entities: ArrayList<T>): Unit
/*
* 删除所有实体
*/
func deleteAll(): Unit
}
/*
* 分页排序仓库接口
* 扩展 CRUD 仓库,支持分页和排序
*/
public interface PagingAndSortingRepository<T, ID> <: CrudRepository<T, ID> {
/*
* 分页查询所有实体
* @param pageable 分页参数
* @return 分页结果
*/
func findAll(pageable: Pageable): Page<T>
/*
* 排序查询所有实体
* @param sort 排序参数
* @return 实体列表
*/
func findAll(sort: Sort): ArrayList<T>
}
/*
* 分页参数接口
*/
public interface Pageable {
/*
* 获取页码(从 0 开始)
*/
func getPageNumber(): Int64
/*
* 获取每页大小
*/
func getPageSize(): Int64
/*
* 获取偏移量
*/
func getOffset(): Int64
/*
* 获取排序参数
*/
func getSort(): Sort
/*
* 是否有上一页
*/
func hasPrevious(): Bool
/*
* 是否有下一页
*/
func hasNext(): Bool
/*
* 获取上一页分页参数
*/
func previous(): Pageable
/*
* 获取下一页分页参数
*/
func next(): Pageable
/*
* 获取第一页分页参数
*/
func first(): Pageable
}
/*
* 排序类
* 定义排序规则
*/
public class Sort {
/* 排序规则列表 */
private var orders: ArrayList<SortOrder>
public init(orders!: ArrayList<SortOrder> = ArrayList<SortOrder>()) {
this.orders = orders
}
/*
* 创建升序排序
* @param property 属性名
* @return 排序对象
*/
public static func ascending(property: String): Sort {
let orders = ArrayList<SortOrder>()
orders.add(SortOrder(property: property, direction: SortDirection.Asc))
return Sort(orders: orders)
}
/*
* 创建降序排序
* @param property 属性名
* @return 排序对象
*/
public static func descending(property: String): Sort {
let orders = ArrayList<SortOrder>()
orders.add(SortOrder(property: property, direction: SortDirection.Desc))
return Sort(orders: orders)
}
/*
* 添加升序排序
* @param property 属性名
* @return 当前对象
*/
public func andAscending(property: String): Sort {
orders.add(SortOrder(property: property, direction: SortDirection.Asc))
return this
}
/*
* 添加降序排序
* @param property 属性名
* @return 当前对象
*/
public func andDescending(property: String): Sort {
orders.add(SortOrder(property: property, direction: SortDirection.Desc))
return this
}
/*
* 获取排序规则列表
* @return 排序规则列表
*/
public func getOrders(): ArrayList<SortOrder> {
return orders
}
/*
* 是否为空
* @return 是否为空
*/
public func isEmpty(): Bool {
return orders.isEmpty()
}
/*
* 转换为 SQL ORDER BY 子句
* @return SQL 子句
*/
public func toSql(): String {
if (orders.isEmpty()) {
return ""
}
let parts = ArrayList<String>()
for (order in orders) {
parts.add(order.toSql())
}
return "ORDER BY " + joinStrings(parts, ", ")
}
}
/*
* 排序规则类(用于 Sort)
*/
public class SortOrder {
/* 属性名 */
public let property: String
/* 排序方向 */
public let direction: SortDirection
public init(property!: String = "", direction!: SortDirection = SortDirection.Asc) {
this.property = property
this.direction = direction
}
/*
* 是否升序
* @return 是否升序
*/
public func isAscending(): Bool {
match (direction) {
case SortDirection.Asc => return true
case SortDirection.Desc => return false
}
}
/*
* 是否降序
* @return 是否降序
*/
public func isDescending(): Bool {
match (direction) {
case SortDirection.Asc => return false
case SortDirection.Desc => return true
}
}
/*
* 转换为 SQL 排序子句
* @return SQL 子句
*/
public func toSql(): String {
return "${property} ${if (isAscending()) { "ASC" } else { "DESC" }}"
}
}
/*
* 排序方向枚举(用于 SortOrder)
*/
public enum SortDirection {
| Asc
| Desc
}
/*
* 分页请求类
* 实现 Pageable 接口
*/
public class PageRequest <: Pageable {
/* 页码 */
private let pageNumber: Int64
/* 每页大小 */
private let pageSize: Int64
/* 排序参数 */
private let sort: Sort
public init(pageNumber!: Int64 = 0, pageSize!: Int64 = 10, sort!: Sort = Sort()) {
this.pageNumber = pageNumber
this.pageSize = pageSize
this.sort = sort
}
/*
* 创建分页请求
* @param page 页码
* @param size 每页大小
* @return 分页请求
*/
public static func of(page: Int64, size: Int64): PageRequest {
return PageRequest(pageNumber: page, pageSize: size)
}
/*
* 创建带排序的分页请求
* @param page 页码
* @param size 每页大小
* @param sort 排序参数
* @return 分页请求
*/
public static func of(page: Int64, size: Int64, sort: Sort): PageRequest {
return PageRequest(pageNumber: page, pageSize: size, sort: sort)
}
public func getPageNumber(): Int64 {
return pageNumber
}
public func getPageSize(): Int64 {
return pageSize
}
public func getOffset(): Int64 {
return pageNumber * pageSize
}
public func getSort(): Sort {
return sort
}
public func hasPrevious(): Bool {
return pageNumber > 0
}
public func hasNext(): Bool {
return true // 需要总页数才能准确判断
}
public func previous(): Pageable {
if (pageNumber > 0) {
return PageRequest(pageNumber: pageNumber - 1, pageSize: pageSize, sort: sort)
}
return this
}
public func next(): Pageable {
return PageRequest(pageNumber: pageNumber + 1, pageSize: pageSize, sort: sort)
}
public func first(): Pageable {
return PageRequest(pageNumber: 0, pageSize: pageSize, sort: sort)
}
}
/*
* 分页结果类
*/
public class Page<T> {
/* 当前页内容 */
private let content: ArrayList<T>
/* 总记录数 */
private let totalElements: Int64
/* 分页参数 */
private let pageable: Pageable
public init(content!: ArrayList<T> = ArrayList<T>(), totalElements!: Int64 = 0, pageable!: Pageable = PageRequest()) {
this.content = content
this.totalElements = totalElements
this.pageable = pageable
}
/*
* 获取当前页内容
* @return 内容列表
*/
public func getContent(): ArrayList<T> {
return content
}
/*
* 获取总记录数
* @return 总记录数
*/
public func getTotalElements(): Int64 {
return totalElements
}
/*
* 获取总页数
* @return 总页数
*/
public func getTotalPages(): Int64 {
if (pageable.getPageSize() == 0) {
return 1
}
return (totalElements + pageable.getPageSize() - 1) / pageable.getPageSize()
}
/*
* 获取页码
* @return 页码
*/
public func getNumber(): Int64 {
return pageable.getPageNumber()
}
/*
* 获取每页大小
* @return 每页大小
*/
public func getSize(): Int64 {
return pageable.getPageSize()
}
/*
* 获取当前页记录数
* @return 当前页记录数
*/
public func getNumberOfElements(): Int64 {
return content.size
}
/*
* 是否为第一页
* @return 是否为第一页
*/
public func isFirst(): Bool {
return pageable.getPageNumber() == 0
}
/*
* 是否为最后一页
* @return 是否为最后一页
*/
public func isLast(): Bool {
return pageable.getPageNumber() >= getTotalPages() - 1
}
/*
* 是否有下一页
* @return 是否有下一页
*/
public func hasNext(): Bool {
return pageable.getPageNumber() < getTotalPages() - 1
}
/*
* 是否有上一页
* @return 是否有上一页
*/
public func hasPrevious(): Bool {
return pageable.getPageNumber() > 0
}
/*
* 是否为空
* @return 是否为空
*/
public func isEmpty(): Bool {
return content.isEmpty()
}
}
/*
* 基础仓库类
* 提供 CRUD 操作的工具方法(不使用继承)
*/
public class RepositoryHelper {
/*
* 构建查询 SQL
* @param metadata 实体元数据
* @return 查询构建器
*/
public static func buildSelectQuery(metadata: EntityMetadata): SelectBuilder {
let builder = SelectBuilder(metadata.tableName)
let columns = metadata.getColumnNames()
for (col in columns) {
builder.column(col)
}
return builder
}
/*
* 构建插入 SQL
* @param tableName 表名
* @return 插入构建器
*/
public static func buildInsertQuery(tableName: String): InsertBuilder {
return InsertBuilder(tableName)
}
/*
* 构建更新 SQL
* @param tableName 表名
* @return 更新构建器
*/
public static func buildUpdateQuery(tableName: String): UpdateBuilder {
return UpdateBuilder(tableName)
}
/*
* 构建删除 SQL
* @param tableName 表名
* @return 删除构建器
*/
public static func buildDeleteQuery(tableName: String): DeleteBuilder {
return DeleteBuilder(tableName)
}
}
/*
* Int64 仓库实现类
* 提供基于 HashMap 的内存存储实现,用于测试
*/
public class Int64Repository<T> <: CrudRepository<T, Int64> {
/* 内存存储 */
private var storage: HashMap<Int64, T>
/* ID 生成器 */
private var idCounter: Int64 = 0
/* ID 获取函数 */
private let getIdFunc: (T) -> Int64
/* ID 设置函数 */
private let setIdFunc: (T, Int64) -> Unit
public init(
getIdFunc: (T) -> Int64,
setIdFunc: (T, Int64) -> Unit
) {
this.storage = HashMap<Int64, T>()
this.getIdFunc = getIdFunc
this.setIdFunc = setIdFunc
}
public func save(entity: T): T {
let id = getIdFunc(entity)
// 如果 ID 为 0,则生成新 ID
if (id == 0) {
idCounter += 1
setIdFunc(entity, idCounter)
}
storage[getIdFunc(entity)] = entity
return entity
}
public func saveAll(entities: ArrayList<T>): ArrayList<T> {
let result = ArrayList<T>()
for (entity in entities) {
result.add(save(entity))
}
return result
}
public func findById(id: Int64): Option<T> {
return storage.get(id)
}
public func existsById(id: Int64): Bool {
match (findById(id)) {
case Some(_) => return true
case None => return false
}
}
public func findAll(): ArrayList<T> {
let result = ArrayList<T>()
for ((_, value) in storage) {
result.add(value)
}
return result
}
public func findAllById(ids: ArrayList<Int64>): ArrayList<T> {
let result = ArrayList<T>()
for (id in ids) {
match (findById(id)) {
case Some(entity) => result.add(entity)
case None => ()
}
}
return result
}
public func count(): Int64 {
return storage.size
}
public func deleteById(id: Int64): Unit {
storage.remove(id)
}
public func delete(entity: T): Unit {
storage.remove(getIdFunc(entity))
}
public func deleteAll(entities: ArrayList<T>): Unit {
for (entity in entities) {
delete(entity)
}
}
public func deleteAll(): Unit {
storage.clear()
}
}
/*
* String 仓库实现类
* 提供基于 HashMap 的内存存储实现,用于测试
*/
public class StringRepository<T> <: CrudRepository<T, String> {
/* 内存存储 */
private var storage: HashMap<String, T>
/* ID 获取函数 */
private let getIdFunc: (T) -> String
public init(getIdFunc: (T) -> String) {
this.storage = HashMap<String, T>()
this.getIdFunc = getIdFunc
}
public func save(entity: T): T {
storage[getIdFunc(entity)] = entity
return entity
}
public func saveAll(entities: ArrayList<T>): ArrayList<T> {
let result = ArrayList<T>()
for (entity in entities) {
result.add(save(entity))
}
return result
}
public func findById(id: String): Option<T> {
return storage.get(id)
}
public func existsById(id: String): Bool {
match (findById(id)) {
case Some(_) => return true
case None => return false
}
}
public func findAll(): ArrayList<T> {
let result = ArrayList<T>()
for ((_, value) in storage) {
result.add(value)
}
return result
}
public func findAllById(ids: ArrayList<String>): ArrayList<T> {
let result = ArrayList<T>()
for (id in ids) {
match (findById(id)) {
case Some(entity) => result.add(entity)
case None => ()
}
}
return result
}
public func count(): Int64 {
return storage.size
}
public func deleteById(id: String): Unit {
storage.remove(id)
}
public func delete(entity: T): Unit {
storage.remove(getIdFunc(entity))
}
public func deleteAll(entities: ArrayList<T>): Unit {
for (entity in entities) {
delete(entity)
}
}
public func deleteAll(): Unit {
storage.clear()
}
}