在 JPA 中,@Lob 注解将实体属性/字段映射成数据库支持的大对象类型;当映射到数据库 Lob 类型时,应用程序应该使用 @Lob 注释。当元素集合值为基本类型时,@Lob 注释可以与 @Basic 注释或 @ElementCollection 注释结合使用。
Lob 可以是二进制或字符类型,Lob 类型是从持久字段或属性的类型推断出来的,除了字符串和基于字符的类型之外,默认为 Blob。
@Lob 注解支持以下数据库类型的字段:
Clob( Character Large Ojects) 类型是长字符串类型,java.sql.Clob、Character[]、char[] 和 String 将被映射为 Clob 类型。
Blob( Binary Large Objects) 类型是字节类型,java.sql.Blob、Byte[]、byte[] 和实现了 Serializable 接口的类型将被映射为 Blob 类型。
注意:Clob、 Blob 占用内存空间较大,一般配合 @Basic(fetch=FetchType.LAZY) 注解将其设置为延迟加载。
(1)创建 users5 用户表,该表记录用户名称、头像和说明信息。SQL 脚本如下:
CREATE TABLE `users5` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `face` longblob, `summary` longtext, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
上面 SQL 脚本中,face 设置为 longblob 类型,用来存放大二进制数据;summary 设置为 longtext 类型,用来存放大文本数据;
(2)根据 users5 用户表,创建实体类。代码如下:
import lombok.Data; import javax.persistence.*; @Data @Entity @Table(name = "users5") public class User14 { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column private String name; @Lob @Basic(fetch = FetchType.LAZY) @Column private byte[] face; @Lob @Basic(fetch = FetchType.LAZY) @Column private String summary; }
上面实体中,face 属性声明为 byte[] 数组类型,summary 属性声明为 String 类型。
(3)客户端,使用 User14 实体插入数据到数据表,然后查询输出到控制台。代码如下:
import com.alibaba.fastjson.JSONObject; import com.huangx.openjpa.annotation.entity.User14; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import java.util.List; public class OpenJpaDemo14 { /** 持久化单元名称 */ 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 User14 user = new User14(); user.setName("鲁智深"); user.setSummary("鲁智深原本是渭州经略...鱼脸,不是看经念佛人。"); user.setFace("this is a picture".getBytes()); em.persist(user); // SELECT String qlString = "select t from User14 t"; Query query = em.createQuery(qlString); List<User14> userList = (List<User14>) query.getResultList(); for (User14 item : userList) { System.out.println(JSONObject.toJSONString(item)); } em.getTransaction().commit(); em.close(); emf.close(); System.out.println("finished."); } }
运行上面客户端,控制台输出如下:
{"face":"dGhpcyBpcyBhIHBpY3R1cmU=","id":351,"name":"鲁智深","summary":"鲁智深原本是渭州经略...鱼脸,不是看经念佛人。"}
上面结果中,face 是将二进制数据转换成 Base64 进行显示。你可以使用代码将上面 Base64 解码,然后转换成 String。代码如下:
import com.sun.xml.internal.messaging.saaj.util.Base64; public class Test1 { public static void main(String[] args) { String str = "dGhpcyBpcyBhIHBpY3R1cmU="; Base64 base64 = new Base64(); byte[] result = base64.decode(str.getBytes()); System.out.println(new String(result)); // 输出:this is a picture } }
上面的 face 和 summary 属性也可以指定为 Byte[] 和 char[] 类型,代码如下:
@Lob @Basic(fetch = FetchType.LAZY) @Column private Byte[] face; @Lob @Basic(fetch = FetchType.LAZY) @Column private char[] summary;
其中,face 属性可以指定为 java.sql.Blob;summary 属性开可以指定为 java.sql.Clob、Character[] 类型。