过Spring的JPA进行数据访问

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类用来执行事务。

 

发布了66 篇原创文章 · 获赞 3 · 访问量 4830

猜你喜欢

转载自blog.csdn.net/weixin_42518668/article/details/104316467