在使用 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。