注意 @org.hibernate.annotations.Formula 使用 native SQL 因此可能导致依赖具体的 DB 从而影响 database portability 。
@Formula mapping usage
package org.example.demo.hibernate;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Persistence;
import org.hibernate.annotations.Formula;
public class Test {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
Account account = new Account();
account.credit = 5000d;
account.rate = 1.25 / 100;
em.persist(account);
em.getTransaction().commit();
em.clear();
Account a = em.find(Account.class, account.id);
// 62.5
System.out.println(a.interest);
em.close();
factory.close();
}
@Entity(name = "Account")
public static class Account {
@Id
@GeneratedValue
Long id;
Double credit;
Double rate;
@Formula(value = "credit * rate")
Double interest;
}
}
生成 SQL
drop table if exists Account cascade
drop sequence if exists hibernate_sequence
create sequence hibernate_sequence start 1 increment 1
create table Account (id int8 not null, credit float8, rate float8, primary key (id))
select nextval ('hibernate_sequence')
insert into Account (credit, rate, id) values (5000.0, 0.0125, 1)
select test_accou0_.id as id1_0_0_, test_accou0_.credit as credit2_0_0_, test_accou0_.rate as rate3_0_0_, test_accou0_.credit * test_accou0_.rate as formula0_0_ from Account test_accou0_ where test_accou0_.id=1
@Formula 可以包含子查询