sproket/Persism:Java低代码的ORM框架


Persism 是一个用于 Java 17 或更高版本的简单、自动发现、自动配置和约定优于配置的 ORM(对象关系映射)库。

Persism的API很小。大多数情况下,你只需要一个Connection和一个Persism Session对象,你就可以开始了。你的POJO可以有可选的表和列名注释,并且可以选择实现一个Persistable接口,用于你需要跟踪UPDATE语句的属性变化。

Persism为你自动推算和发现:创建一个表,编写一个JavaBean,运行一个查询,Persism使用简单的映射规则来寻找你的表和列名,只要求在它找不到匹配的地方进行注释。

Persism不需要特殊的配置。把JAR放到你的项目中就可以了。
Persism有注释,但它们只在某些东西超出常规时才需要。在大多数情况下,你可能甚至不需要它们。
Persism通常可以为你检测表和列的映射,包括主键/生成键和带默认值的列。
Persism默认会做正确的事情。Persism理解你的类被称为Customer,你的表被称为CUSTOMERS。它理解你的表列是CUSTOMER_ID,你的属性是customerId。
Persism理解你的类被称为Category,你的表被称为CATEGORIES。没问题。不需要为此做注解。Persism使用注释作为后备手段--只有当某些东西超出常规时才进行注释。

大小100k以下。是的,如果你想的话,可以把它装在软盘上。Persism没有依赖性,但是它将利用基于运行时可用的任何日志 - SLF4J、LOG4J或JUL。
支持数据库:Derby, Firebird, H2, HSQLDB, Informix, MSAccess, MSSQL, MySQL/MariaDB, Oracle (12+), PostgreSQL, SQLite.


以下是CRUD案例代码:

import static net.sf.persism.Parameters.*;
import static net.sf.persism.SQL.*;

Connection con = DriverManager.getConnection(url, username, password);

// Instantiate a Persism session object with the connection
Session session = new Session(con);

List<Customer> list = session.query(Customer.class, sql("select * from Customers where CUST_NAME = ?"), params("Fred"));
// or
List<Customer> list = session.query(Customer.class, proc("sp_FindCustomers(?)"), params("Fred"));

Customer customer;
customer = session.fetch(Customer.class, sql("select * from Customers where CUST_NAME = ?"), params("Fred"));
// or   
customer = session.fetch(Customer.class, proc("sp_FindCustomer(?)"), params("Fred"));
if (customer != null) {
    // etc...
}

// You don't need the SELECT parts for Views or Tables
List<Customer> list = session.query(Customer.class, where("CUST_NAME = ?"), params("Fred"));

// You can reference the property names instead of the column names - just use :propertyName 
List<Customer> list = session.query(Customer.class, where(":name = ?"), params("Fred"));

// Order by is also supported with where() method
List<Customer> list = session.query(Customer.class, where(":name = ? ORDER BY :lastUpdated"), params("Fred"));

// Named parameters are also supported - just use @name
SQL sql = where("(:firstname = @name OR :company = @name) and :lastname = @last");
customer = session.fetch(Customer.class, sql, params(Map.of("name", "Fred", "last", "Flintstone")));

// fetch an existing instance
Customer customer = new Customer();
customer.setCustomerId(123);
if (session.fetch(customer)) {
    // customer found and initialized


// Supports basic types
String result = session.fetch(String.class, sql("select Name from Customers where ID = ?"), params(10));

// Fetch a count as an int - Enums are supported 
int count = session.fetch(int.class, sql("select count(*) from Customers where Region = ?"), params(Region.West));

// Insert - get autoinc
Customer customer = new Customer();
customer.setCustomerName("Fred");
customer.setAddress("123 Sesame Street");

session.insert(customer); 

// Inserted and new autoinc value assigned 
assert customer.getCustomerId() > 0

// Update
customer.setCustomerName("Barney");
sesion.update(customer); // Update Customer   

// Delete
session.delete(customer);

// Handles transactions
session.withTransaction(() -> {
    Contact contact = getContactFromSomewhere();
    contact.setIdentity(randomUUID);
    session.insert(contact);
    
    contact.setContactName("Wilma Flintstone");
    
    session.update(contact);
    session.fetch(contact);
});