{"id":40623600,"url":"https://github.com/elialm7/simple-crud","last_synced_at":"2026-01-21T07:14:21.372Z","repository":{"id":315989178,"uuid":"1061442262","full_name":"elialm7/simple-crud","owner":"elialm7","description":"simple crud library for creating crud classes out of an annotated entity class (NOT AN ORM)","archived":false,"fork":false,"pushed_at":"2025-10-01T04:17:10.000Z","size":110,"stargazers_count":1,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-01T06:21:40.030Z","etag":null,"topics":["crud","jdbi3","library","mysql","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elialm7.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-21T22:56:28.000Z","updated_at":"2025-10-01T04:17:13.000Z","dependencies_parsed_at":"2025-09-22T04:16:21.938Z","dependency_job_id":"38301afe-68b3-4c96-8f41-71ee34494067","html_url":"https://github.com/elialm7/simple-crud","commit_stats":null,"previous_names":["elialm7/simple-crud"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elialm7/simple-crud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elialm7%2Fsimple-crud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elialm7%2Fsimple-crud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elialm7%2Fsimple-crud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elialm7%2Fsimple-crud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elialm7","download_url":"https://codeload.github.com/elialm7/simple-crud/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elialm7%2Fsimple-crud/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28629595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crud","jdbi3","library","mysql","postgresql"],"created_at":"2026-01-21T07:14:20.741Z","updated_at":"2026-01-21T07:14:21.364Z","avatar_url":"https://github.com/elialm7.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple - CRUD Library for Java\n\nA lightweight, annotation-driven CRUD library for Java with automatic SQL generation and type transformations. Supports **MySQL and PostgreSQL fully**.\nBuilt on top of JDBI.\n\n## Features\n\n* **Zero configuration**: Define entities with annotations.\n* **Automatic SQL generation**: INSERT, UPDATE, SELECT, DELETE statements created automatically.\n* **Type transformations**: JSON, arrays, enums, UUIDs, timestamps handled automatically.\n* **Dynamic Filtering**: Powerful filtering with operators (LIKE, IN, BETWEEN, IS_NULL, etc.).\n* **Batch Operations**: Efficient bulk inserts.\n* **Automatic Timestamps**: `@CreatedDate` and `@UpdatedDate` annotations.\n* **Default Values**: `@Default` annotation for fallback values.\n* **Flexible Mapping**: `getCustomRowMapper()` for mapping to DTOs without `@Table` annotation.\n\n---\n\n## 1. Complete Example\n\n### Entity\n\n```java\n@Table(value = \"complex_entities\", schema = \"public\", dialect = Dialect.POSTGRESQL)\npublic class TestUserPostgresql {\n\n    @Id(autoGenerated = true)\n    private Long id;\n\n    @Column(\"entity_name\")\n    private String name;\n\n    @UUID(autoGenerate = true)\n    @Column(\"uuid_field\")\n    private java.util.UUID uuid;\n\n    @UUID(autoGenerate = false)\n    @Column(\"manual_uuid\")\n    private String manualUuid;\n\n    @JsonColumn\n    @Column(\"preferences_json\")\n    private UserPreferences preferences;\n\n    @JsonColumn\n    private Map\u003cString, Object\u003e metadata;\n\n    @JsonColumn\n    @Column(\"raw_json\")\n    private JsonNode rawJson;\n\n    @ArrayColumn(separator = \",\")\n    private List\u003cString\u003e tags;\n\n    @ArrayColumn(separator = \"|\")\n    private String[] categories;\n\n    @EnumColumn(EnumColumn.EnumType.STRING)\n    private Status status;\n\n    @EnumColumn(EnumColumn.EnumType.ORDINAL)\n    private Priority priority;\n\n    @EnumColumn(EnumColumn.EnumType.CODE)\n    private Department department;\n\n    @FileColumn\n    private byte[] document;\n\n    @Default(\"true\")\n    private Boolean active;\n\n    @Default(\"0\")\n    private Integer attempts;\n\n    @CreatedDate\n    @Column(\"created_at\")\n    private LocalDateTime createdAt;\n\n    @UpdatedDate\n    @Column(\"updated_at\")\n    private LocalDateTime updatedAt;\n\n    @Ignore\n    private String temporaryField;\n}\n```\n\n### Supporting Classes\n\n```java\npublic class UserPreferences {\n    private String theme;\n    private boolean notifications;\n    private Map\u003cString, String\u003e settings;\n    // getters/setters\n}\n\npublic enum Status { ACTIVE, INACTIVE }\npublic enum Priority { LOW, MEDIUM, HIGH }\npublic enum Department {\n    SALES(\"SALE\"), ENGINEERING(\"ENG\");\n    private final String code;\n    Department(String code) { this.code = code; }\n    public String getCode() { return code; }\n}\n```\n\n---\n\n### CRUD Class\n\n```java\npublic class TestUserCRUD extends CRUD\u003cTestUserPostgresql, Long\u003e {\n    public TestUserCRUD(Jdbi jdbi) { super(jdbi, TestUserPostgresql.class, Long.class); }\n}\n```\n\n---\n\n## 2. Example Usage\n\n```java\nJdbi jdbi = Jdbi.create(\"jdbc:postgresql://localhost/mydb\", \"user\", \"pass\");\nTestUserCRUD crud = new TestUserCRUD(jdbi);\n\n// Crear usuario\nTestUserPostgresql user = new TestUserPostgresql();\nuser.setName(\"John Doe\");\nuser.setPreferences(new UserPreferences(\"dark\", true, Map.of(\"lang\", \"en\")));\nuser.setMetadata(Map.of(\"version\", \"1.0\"));\nuser.setTags(List.of(\"important\", \"test\"));\nuser.setCategories(new String[]{\"cat1\", \"cat2\"});\nuser.setStatus(Status.ACTIVE);\nuser.setPriority(Priority.HIGH);\nuser.setDepartment(Department.ENGINEERING);\nuser.setActive(true); // Usará el valor por defecto si es null\n\nLong id = crud.save(user);\n\n// Leer todos\nList\u003cTestUserPostgresql\u003e allUsers = crud.findAll();\n\n// Buscar por ID\nOptional\u003cTestUserPostgresql\u003e oneUser = crud.findById(id);\n\n// Filtros dinámicos\nMap\u003cString, Object\u003e filters = new HashMap\u003c\u003e();\nfilters.put(\"name_LIKE\", \"John\"); // LIKE '%John%'\nfilters.put(\"status\", \"ACTIVE\"); // EQUALS\nfilters.put(\"priority_GREATER_THAN\", 1);\nfilters.put(\"tags_LIKE\", \"%test%\"); // Filtra sobre el string unido\nfilters.put(\"uuid_IS_NOT_NULL\", \"\"); // Verifica UUID no nulo\n\nList\u003cTestUserPostgresql\u003e filteredUsers = crud.findAll(filters);\n\n// Filtros avanzados\nfilters.clear();\nfilters.put(\"priority_BETWEEN\", \"1,3\"); // BETWEEN 1 AND 3\nfilters.put(\"department_IN\", \"SALE,ENG\"); // IN ('SALE', 'ENG')\n\nfilteredUsers = crud.findAll(filters);\n\n// Actualizar\nuser.setName(\"John Updated\");\ncrud.update(user);\n\n// Eliminar\ncrud.deleteById(id);\n\n// Inserción en lote\nList\u003cTestUserPostgresql\u003e users = createManyUsers();\ncrud.saveAll(users);\n```\n\n---\n\n## 3. Database Schema Examples\n\n### PostgreSQL\n\n```sql\nCREATE TABLE public.complex_entities (\n    id BIGSERIAL PRIMARY KEY,\n    entity_name VARCHAR(255),\n    uuid_field UUID,\n    manual_uuid UUID,\n    preferences_json JSONB,\n    metadata JSONB,\n    raw_json JSONB,\n    tags TEXT,\n    categories TEXT,\n    status VARCHAR(50),\n    priority INTEGER,\n    department VARCHAR(10),\n    document BYTEA,\n    active BOOLEAN DEFAULT TRUE,\n    attempts INTEGER DEFAULT 0,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n```\n\n### MySQL\n\n```sql\nCREATE TABLE complex_entities (\n    id BIGINT AUTO_INCREMENT PRIMARY KEY,\n    entity_name VARCHAR(255) NULL,\n    uuid_field VARCHAR(36) NULL,\n    manual_uuid VARCHAR(36) NULL,\n    preferences_json JSON NULL,\n    metadata JSON NULL,\n    raw_json JSON NULL,\n    tags TEXT NULL,\n    categories TEXT NULL,\n    status VARCHAR(50) NULL,\n    priority INT NULL,\n    department VARCHAR(10) NULL,\n    document LONGBLOB NULL,\n    active TINYINT(1) DEFAULT 1 NULL,\n    attempts INT DEFAULT 0 NULL,\n    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL,\n    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP\n);\n```\n\n---\n\n## 4. Supported Data Types\n\n| Java Type               | PostgreSQL      | MySQL           | Notes                                 |\n| ----------------------- | --------------- | --------------- | ------------------------------------- |\n| String                  | VARCHAR/TEXT    | VARCHAR/TEXT    | Regular string                        |\n| UUID (auto/manual)      | UUID            | VARCHAR(36)     | Native in PG, string in MySQL         |\n| Object / Map / JsonNode | JSONB           | JSON            | Auto-serialized via Jackson           |\n| List\u003cString\u003e            | TEXT            | TEXT            | Comma-separated or custom separator   |\n| String\\[]               | TEXT            | TEXT            | Use @ArrayColumn for custom separator |\n| Enum (STRING)           | VARCHAR(50)     | VARCHAR(50)     | Stores enum name                      |\n| Enum (ORDINAL)          | INTEGER         | INT             | Stores enum ordinal (0,1,2…)          |\n| Enum (CODE)             | VARCHAR(10)     | VARCHAR(10)     | Stores custom code via `getCode()`    |\n| byte\\[]                 | BYTEA           | LONGBLOB        | File storage                          |\n| Boolean                 | BOOLEAN         | TINYINT(1)      | With `@Default` support               |\n| Integer                 | INTEGER         | INT             | With `@Default` support               |\n| LocalDateTime           | TIMESTAMP       | TIMESTAMP       | Used for audit fields                 |\n\n---\n# CRUD Library - Data Type Mapping Diagram\n\n| Java Type                       | Annotation                      | PostgreSQL Column     | MySQL Column          | Notes                                              |\n| ------------------------------- | ------------------------------- | --------------------- | --------------------- | -------------------------------------------------- |\n| `String`                        | `@Column`                       | `VARCHAR(n)` / `TEXT` | `VARCHAR(n)` / `TEXT` | Simple string mapping                              |\n| `java.util.UUID`                | `@UUID(autoGenerate = true)`    | `UUID`                | `VARCHAR(36)`         | Auto-generated, native in PG                       |\n| `String` (Manual UUID)          | `@UUID(autoGenerate = false)`   | `UUID`                | `VARCHAR(36)`         | You provide value, PG casts `::uuid`               |\n| `Object` / `Map\u003cString,Object\u003e` | `@JsonColumn`                   | `JSONB`               | `JSON`                | Auto-serialized via Jackson, PG casts `::jsonb`    |\n| `JsonNode`                      | `@JsonColumn`                   | `JSONB`               | `JSON`                | Raw JSON, can store any structure                  |\n| `List\u003cString\u003e`                  | `@ArrayColumn(separator=\",\")`   | `TEXT`                | `TEXT`                | Stored as comma-separated string                   |\n| `String[]`                      | `@ArrayColumn(separator=\"      | \")\\`                  | `TEXT`                | `TEXT`                                             | Stored as pipe-separated string                    |\n| Enum (STRING)                   | `@EnumColumn(EnumType.STRING)`  | `VARCHAR(50)`         | `VARCHAR(50)`         | Stores enum name                                   |\n| Enum (ORDINAL)                  | `@EnumColumn(EnumType.ORDINAL)` | `INTEGER`             | `INT`                 | Stores enum ordinal (0,1,2…)                       |\n| Enum (CODE)                     | `@EnumColumn(EnumType.CODE)`    | `VARCHAR(10)`         | `VARCHAR(10)`         | Stores custom code via `getCode()`                 |\n| `byte[]`                        | `@FileColumn`                   | `BYTEA`               | `LONGBLOB`            | File storage                                       |\n| `Boolean`                       | `@Default(\"true\")`              | `BOOLEAN`             | `TINYINT(1)`          | Default value support                              |\n| `Integer`                       | `@Default(\"0\")`                 | `INTEGER`             | `INT`                 | Default value support                              |\n| `LocalDateTime`                 | `@CreatedDate` / `@UpdatedDate` | `TIMESTAMP`           | `TIMESTAMP`           | Auto timestamps for creation/update                |\n| Any Field                       | `@Ignore`                       | N/A                   | N/A                   | Field is excluded from all DB operations           |\n\n---\n\n## 5. Supported Databases\n\n| Database   | Support                                                   |\n| ---------- | --------------------------------------------------------- |\n| PostgreSQL | ✅ **Full support** (UUID, JSONB, arrays, enums, dialect-specific casts) |\n| MySQL 5.7+ | ✅ **Full support** (UUID as string, JSON, arrays, enums)      |\n| Others     | ⚠ Untested – basic types might work, but no guarantees.   |\n\n\u003e ✅ **Only MySQL and PostgreSQL are officially supported and fully tested.** Other databases may work for basic operations but lack dialect-specific optimizations.\n---\n## 7. Notes \u0026 Best Practices\n\n* **UUID**: For PostgreSQL, prefer `java.util.UUID` type for native handling. For MySQL, `String` is fine.\n* **JSON**: Annotate with `@JsonColumn`. Supports complex objects, maps, or `JsonNode`.\n* **Arrays**: Annotate with `@ArrayColumn(separator)`. Filtering is done on the *joined string*.\n* **Enums**: Use `@EnumColumn` and choose `STRING` (recommended for safety), `ORDINAL` (fragile), or `CODE` (custom).\n* **Files**: Use `@FileColumn` with `byte[]`.\n* **Timestamps**: Use `@CreatedDate` (set once) and `@UpdatedDate` (set on every update).\n* **Defaults**: Use `@Default` to provide fallback values for `null` fields.\n* **Ignore**: Use `@Ignore` for fields that should never touch the database.\n* **Batch Operations**: Use `saveAll(List\u003cE\u003e)` for high-performance bulk inserts.\n* **Transactions**: All write operations (`save`, `update`, `delete`) are automatically wrapped in transactions via JDBI.\n\n---\n\n## 8. Dependencies\n\nTo use the CRUD library, you need the following libraries in your project:\n\n### Maven\n\n```xml\n\u003cdependencies\u003e\n    \u003c!-- JDBI Core (required for database access and SQL mapping) --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.jdbi\u003c/groupId\u003e\n        \u003cartifactId\u003ejdbi3-core\u003c/artifactId\u003e\n        \u003cversion\u003e3.41.0\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- PostgreSQL Driver (for PostgreSQL support) --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.postgresql\u003c/groupId\u003e\n        \u003cartifactId\u003epostgresql\u003c/artifactId\u003e\n        \u003cversion\u003e42.7.0\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- MySQL Driver (for MySQL support) --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003emysql\u003c/groupId\u003e\n        \u003cartifactId\u003emysql-connector-java\u003c/artifactId\u003e\n        \u003cversion\u003e8.1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- Jackson Databind (for JSON serialization/deserialization) --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.fasterxml.jackson.core\u003c/groupId\u003e\n        \u003cartifactId\u003ejackson-databind\u003c/artifactId\u003e\n        \u003cversion\u003e2.17.1\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- SLF4J API (for logging) --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.slf4j\u003c/groupId\u003e\n        \u003cartifactId\u003eslf4j-api\u003c/artifactId\u003e\n        \u003cversion\u003e2.0.12\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n### Notes\n\n* PostgreSQL and MySQL are the officially tested databases.\n* Jackson is **required** for `@JsonColumn` functionality.\n* JDBI handles all SQL generation, object mapping, and transactions.\n* Other JDBC-compatible databases **might work**, but have not been fully tested and lack dialect-specific features.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felialm7%2Fsimple-crud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felialm7%2Fsimple-crud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felialm7%2Fsimple-crud/lists"}