JPA的作用
对象模型和关系模型之间的元数据映射
用来在对象上执行相关操作的GRUD API
一种对象查询语言
不同的数据获取策略和对象网络遍历功能,以便提高内存使用率以及数据获取时间性能
配置JPA和Hibernate
新建maven项目,添加依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.1.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.175</version>
</dependency>
</dependencies>
创建META-INF/persistence.xml文件
新建的META-INF文件夹应该在src/main/resources中,他是jpa入口
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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_2_0.xsd">
<persistence-unit name="test-jpa" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
jpa配置文件配置了需要访问的数据库以及jpa用到的hibernate的方言类
jpa将操作打包为一个事务。Transaction-type表示事务模式。
在main方法中检查是否成功配置jpa
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-jpa");
System.out.println(entityManagerFactory.isOpen());
}
EntityManagerFactory实例一次创建并在应用程序的整个生存期内使用。
使用JPA来持久化实体以及创建关联
创建两个实体类
@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
private String name;
public long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity
public class Student {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
@OneToMany(cascade= CascadeType.ALL)
@JoinColumn(name="student_id")
private Set<Book> books = new HashSet<Book>();
public Long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Set<Book> getBooks() {
return books;
}
}
这两个类之间是单向的1:M关联
在main方法进行持久化操作
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-jpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student student = new Student();
student.setFirstName("John");
student.setLastName("Doe");
Book book1 = new Book();
book1.setName("book 1");
Book book2 = new Book();
book2.setName("book 2");
student.getBooks().add(book1);
student.getBooks().add(book2);
entityManager.persist(student);
transaction.commit();
entityManager.close();
}
实例说明
先建立了两个实体类,用@Entity注解类
在id属性上用@Id和@GeneratedValue表示该主键自动生成,不同数据库默认生成的方法有:标识符,自动增量,序列,uuid.
使用@OneToMany注解定义了Student和Book之间1:M关联。且外键是Book表中的student_id列。
@OneToMany注解中定义了一个名为cascade属性,表示级联操作,比如删除了student表中某条记录,book表中使用了该记录的会自动被删除,调高了效率。该该过程被称为传播性持久化。
在main方法中新建了EntityManager实例和EntityTransaction实例。
Jpa的插入,更新,删除都必须在一个可用的活动事务范围内进行。
entityManager.persist(student)把student和book实体化到数据库,因为使用cascade属性,所以不用对每个bookpersist.
最后要用transaction.commit提交事务。
在数据库中发现已经被插入到数据库中了。
使用jpa来查找,更新和删除实体
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-jpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student student = entityManager.find(Student.class,1l);
Book book = entityManager.find(Book.class,2l);
student.setFirstName("Joe");
entityManager.refresh(book);
transaction.commit();
entityManager.close();
}
}
jpa提供了两种finder方法,find()和getReference()方法,区别在于
find()会将特定实体获取立即返回。
getReference返回代理实例而不是目标实体实例。
使用JPA QL查询数据库
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test-jpa");
EntityManager entityManager = entityManagerFactory.createEntityManager();
String sql = "select s from Student s where s.firstName like ?";
Query query = entityManager.createQuery(sql);
query.setParameter(1,"Jo%");
List<Student> students = query.getResultList();
Student s = students.get(0);
System.out.println(students.size());
System.out.println(s.getLastName());
entityManager.close();
}
}
使用LocalContainerEntityManagerFacotryBean配置和使用JPA
LocalContainerEntityManagerFacotryVean是Spring提供的JPA技术,它功能强大且灵活。
创建Bean配置类
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:tcp://localhost/~/test");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
private Map<String,?> jpaProperties(){
Map<String,String> jpaPropertierMap = new HashMap<String, String>();
jpaPropertierMap.put("hibernate.dialect","org.hibernate.dialect.H2Dialect");
jpaPropertierMap.put("hibernate.hbm2ddl.auto","update");
return jpaPropertierMap;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan("entity");
factoryBean.setJpaPropertyMap(jpaProperties());
return factoryBean;
}
}
dataSource类定义了需要使用的数据库的驱动名称,url,用户名,密码。
辅助的jpaPropertier方法定义了jpa需要使用的Hibernate方言,数据库架构等属性。
最后定义了localContainerEntityManagerFactoryBean将dataSource,辅助Map,需要扫描的Entity包的名称。
然后在main方法中获取EntityManagerFactory。用来执行jpa更新操作。
基于java的配置类也可以用java实现。
使用@PersistenceUnit获取EntityManagerFactory
可以在dao层使用EntityManagerFactory和EntityManager来进行持久化操作。
而也可以使用@PersistenceUnit和@PersistenceContext注解来获取它们。
创建StudentDaoImpl类
public class StudentDaoImpl {
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
public void save(Student student){
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
entityManager.persist(student);
transaction.commit();
entityManager.close();
}
}
注意该注解的使用
在Bean配置类中加入StudentDaoImplBean
@Bean
public StudentDaoImpl studentDao(){
StudentDaoImpl studentDao = new StudentDaoImpl();
return studentDao;
}
在main方法中获取StuentDaoImpl Bean使用
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Configuration.class);
StudentDaoImpl studentDao = applicationContext.getBean(StudentDaoImpl.class);
Student student = new Student();
student.setFirstName("Joe");
student.setLastName("Smith");
studentDao.save(student);
}
使用@PersistenceContext获取EntityManager
新建BookDaoImpl类
@Transactional
public class BookDaoImpl implements BookDao {
@PersistenceContext
private EntityManager entityManager;
public void save(Book book){
entityManager.persist(book);
}
}
在Bean配置类中添加bean配置
@Bean
@Autowired
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public BookDao bookDao(){
BookDaoImpl bookDao = new BookDaoImpl();
return bookDao;
}
在main方法添加book对象
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Configuration.class);
BookDao bookDao = applicationContext.getBean(BookDao.class);
Book book = new Book();
book.setName("book3");
bookDao.save(book);
}
}
在BookDaoImpl中的@Transactional注解定义了事务过程。
在配置类中添加了TransactionManager类用来执行事务。