何为JPA:
JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate、TopLink等ORM框架的基础上发展而来的,具有易于使用、伸缩性强等优点。
JPA包括以下3方面的技术:
ORM映射元数据
JPA支持XML和JDK 5.0注释(也可译作注解)两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
Java持久化API
用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者可以从繁琐的JDBC和SQL代码中解脱出来。
查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
总体来说JPA提供了一个基于注解的比较统一的ORM解决方案。
而现有的ORM框架,诸如Hibernate3.2(及以上)、TopLink10.1.3以及OpenJpa都提供了JPA的实现。
首先,创建一个Maven工程,由于Hibernate3.2以上的版本都对JPA进行了实现,所以可以借由Hibernate来了解JPA。
所需要配置的Jar包依赖只有一个,Maven会帮我们导入其所依赖的所有jar包:
<properties> <hibernate.version>3.5.6-Final</hibernate.version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> </dependencies>
导入的Jar包包括:
接下来是JPA的配置文件,JPA规范要求在类路径的META-INF目录下放置persistence.xml,文件的名称是固定的,所以在src/main/resource目录下新建名为META-INF的文件夹,并在其中新建persistence.xml,文件具体内容如下:
<?xml version="1.0"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="jpaDemo" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
在保存好以上文件的同时不要忘了将对应数据库的jdbc的jar包加到工程依赖中:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.22</version> </dependency>
然后可以在数据库中准备一张名为User的表:
CREATE TABLE `user` ( `ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `Name` VARCHAR(50) NULL DEFAULT NULL, `Age` INT(3) UNSIGNED NULL DEFAULT NULL, `Sex` CHAR(1) NULL DEFAULT 'M' COMMENT 'M for male and F for female', `Address` TEXT NULL, `Birth` DATE NULL DEFAULT NULL, `Income` DECIMAL(10,2) UNSIGNED NULL DEFAULT '0.00', PRIMARY KEY (`ID`) )
其实体类信息如下:
@Entity public class User implements Serializable { private static final long serialVersionUID = -4969930054771554775L; @Id @GeneratedValue(strategy = GenerationType.TABLE) @Column(name = "ID") private int id; @Column(name = "Name", length = 50) private String name; @Column(name = "Age") private int age; @Column(name = "Sex", length = 1) private char sex; @Column(name = "Address") private String address; @Column(name = "Birth") @Temporal(TemporalType.DATE) private Date birth; @Column(name = "Income") private BigDecimal income; // getter and setter methods }
我们可以看到除了注解之外,这就是一个简单的pojo,那么实体类与表的关联就是依靠每个字段上的注解,下面对一些比较重要的注解进行下说明:
@Entity(name = "User"):指明这个类是一个Domian Object(实体类),name属性不指定,则类名即为表名,指定则无此限制。
@Id:此字段为表的主键。
@GeneratedValue(strategy = xxx):主键生成策略,有以下4种:
GenerationType.IDENTITY:自增主键,oracle不支持。
GenerationType. AUTO:默认选项,由JPA选择合适策略。
GenerationType. TABLE:通过表产生主键,主要方便数据库移植。
GenerationType. SEQUENCE:通过序列产生主键。
@Column(name = "ID"):将字段与指定列绑定。不必制定字段类型,JPA可以通过反射获取。可以为字符类型指定长度,以便可以自动生成DDL语句。
@Temporal(TemporalType.DATE):时间类型必须指明具体类型,包括DATE,TIME,TIMESTAMP。
是不是很简单,下面我们可以对已经配置好的实体类进行下简单的测试:
public class TestDAO { @PersistenceContext private EntityManager em; public User getUserById(int id) { EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpaDemo"); em = factory.createEntityManager(); return em.find(User.class, id); } public static void main(String[] args) { TestDAO dao = new TestDAO(); User user = dao.getUserById(1); System.out.println(user.getName()); } }
其中Persistence.createEntityManagerFactory("jpaDemo")方法参数为persistence.xml中persistence-unit标签的name值。
Run以下,可能会报出一些关于slf4j包的错误,主要原因是我们没有引入slf4j-log4j12的jar包,并且hernate本身关联的slf4j包版本过低,对pom.xml进行修改加入如下依赖:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.2</version> </dependency>
再Run一次,成功: