在使用 JPA 映射数据库表时,难免会出现某个实体中部分字段在数据表中并不存在,它的存在仅仅是为了业务需要,临时存放数据。例如:存放用户生日格式化后的字符串,存放用户状态对于的可读名称。
在 JPA 中可以使用 @Transient 注解来修饰某个属性并非一个到数据库表的字段的映射,ORM 框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为 @Transient;否则,ORM 框架默认其注解为 @Basic。
实例:使用 @Transient 注解声明 ageLevel 字段为非持久化字段。代码如下:
import lombok.Data; import javax.persistence.*; @Data @Entity @Table(name = "users") public class User10 { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(table = "users") private Integer id; @Column(name = "name", table = "users") private String name; @Column(precision = 8, table = "users") private Integer age; // 保存年龄级别(不持久化到数据库) @Transient private String ageLevel; public void setAge(Integer age) { this.age = age; if(age < 18) { this.ageLevel = "未成年"; } else if(age < 30) { this.ageLevel = "青年"; } else if(age < 60) { this.ageLevel = "成年人"; } else { this.ageLevel = "朽朽老矣"; } } }
客户端代码,使用 EntityManager 的实例保存和查询 User10 实体,对于与 users 表。代码如下:
import com.alibaba.fastjson.JSONObject; import com.huangx.openjpa.annotation.entity.User10; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import java.util.List; public class OpenJpaDemo10 { /** 持久化单元名称 */ private static final String NAME = "openJPA"; public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory(NAME); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // INSERT User10 user = new User10(); user.setName("孙二娘-" + System.currentTimeMillis()); user.setAge(24); em.persist(user); // SELECT String qlString = "select t from User10 t"; Query query = em.createQuery(qlString); List<User10> userList = (List<User10>) query.getResultList(); for (User10 item : userList) { System.out.println(JSONObject.toJSONString(item, true)); } em.getTransaction().commit(); em.close(); emf.close(); System.out.println("finished."); } }
@Basic 注解指到数据库列的最简单映射类型。@Basic 注释可以应用于以下任何类型的持久属性或实例变量:
(1)Java 原始类型,如:byte、short、int、long、float、double 等
(2)Java 原始包装类型,如:Integer、Long、Float、Double 等
(3)String 字符串
(4)java.math.BigInteger
(5)java.math.BigDecimal
(6)java.util.Date
(7)java.util.Calendar
(8)java.sql.Date
(9)java.sql.Time
(10)java.sql.Timestamp
(11)byte[]
(12)Byte[]
(13)char[]
(14)Character[]
(15)enums 枚举
(16)其他实现了 java.io.Serializable 接口的类
对于上面这些类型的持久字段和属性,使用 @Basic 注释是可选的。如果没有为这样的字段或属性指定 @Basic 注释,则将应用 @Basic 注释的默认值。
实例1:
@Basic protected String name;
实例2:
@Basic(fetch=LAZY) protected String getName() { return name; }
@Basic 支持下面两个属性:
该属性默认值为 javax.persistence.FetchType.EAGER,它定义字段或属性的值是应该延迟加载还是立即加载。可取值如下:
EAGER 策略表示立即加载属性的值;
LAZY 策略表示属性值延迟加载;
该属性定义实体字段或属性的值是否可以为空,默认为 true。