Spring Data 系列(二) Spring+JPA入门(集成Hibernate)

来源:互联网 发布:骑马钉排版知乎 编辑:程序博客网 时间:2024/06/05 00:29

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://dba10g.blog.51cto.com/764602/1791946

通过【Spring Data 系列(一) 入门】的介绍通过对比的方式认识到Spring提供的JdbcTemplate的强大功能。通过使用JdbcTemplate,操作数据库,不需要手动处理Connection,Statement等底层SQL对象。可是,Spring对数据库的操作还远远没有结束。本章主要介绍Spring 对JPA的支持。

主要内容

  1. 简单介绍JPA

  2. Spring Hibernate JPA整合

1.JPA简介

 Java Persistence API (JPA),为开发人员提供了一种对象/关系映射(O-R Mapping)工具,用来管理 Java 应用中的关系数据。JPA是EJB3.0的一部分,现在公认为ORM行业标准。JPA本身只是一个规范,而不是产品; 它本身不能进行持续性或其他任何东西。JPA只是一组接口,需要一个实现。JPA允许通过标准的XML格式和注解格式声明,用于定义Java类如何映射到关系数据库表的映射规则。。JPA也定义了在对数据库中的对象处理查询和事务运行时的EntityManager的API。JPA定义一个对象级查询语言,JPQL,以允许从所述数据库中的对象的查询。JPA常用的解决方案:

    EclipseLink (Eclipse)
    Hibernate (RedHat)
    Open JPA (Apache)
    DataNucleus
    Ebean (SourceForge)
    TopLink Essentials (Glassfish)
    TopLink (Oracle)
    Kodo (Oracle)
JPA 规范也不是一成不变的。从2006年的JPA1.0,到2009年JPA2.0,最后到2013年JPA2.1。版本之间的特性具体参照

https://en.wikibooks.org/wiki/Java_Persistence/What_is_JPA%3F

https://en.wikipedia.org/wiki/Java_Persistence_API


2.Spring Hibernate JPA整合

准备

1
2
3
4
5
6
CREATE TABLE `Employee` (
  `id` int(11) unsigned NOT NULL,
  `namevarchar(20) DEFAULT NULL,
  `role` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;


2.1项目结构

wKiom1dqpY2xFPkdAAA9hhgoCj4031.png


2.2 pom.xml


<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>org.springframework</groupId>    <artifactId>gs-relational-data-access</artifactId>    <version>0.1.0</version>     <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-jpa</artifactId>        </dependency>        <dependency>            <groupId>com.h2database</groupId>            <artifactId>h2</artifactId>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-test</artifactId>        </dependency>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>        </dependency>    </dependencies>     <repositories>        <repository>            <id>spring-releases</id>            <name>Spring Releases</name>            <url>https://repo.spring.io/libs-release</url>        </repository>        <repository>            <id>org.jboss.repository.releases</id>            <name>JBoss Maven Release Repository</name>            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>        </repository>    </repositories>    <pluginRepositories>        <pluginRepository>            <id>spring-releases</id>            <name>Spring Releases</name>            <url>https://repo.spring.io/libs-release</url>        </pluginRepository>    </pluginRepositories>    <dependencyManagement>        <dependencies>            <dependency>                <groupId>io.spring.platform</groupId>                <artifactId>platform-bom</artifactId>                <version>1.1.2.RELEASE</version>                <type>pom</type>                <scope>import</scope>            </dependency>        </dependencies>    </dependencyManagement></project>

使用了platform-bom,方便了包的依赖管理。

依赖树结构

wKioL1dqpnbibnU9AAB22QiO8wc267.png

2.3 persistence.xml

<persistence version="2.1"             xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">    <persistence-unit name="JPAExamples">        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>    </persistence-unit></persistence>


2.4 spring.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:p="http://www.springframework.org/schema/p"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:aop="http://www.springframework.org/schema/aop"       xmlns:tx="http://www.springframework.org/schema/tx"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"><!--数据源-->    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">        <property name="url" value="jdbc:mysql://localhost:3306/exampledb"/>        <property name="username" value="root"/>        <property name="password" value="root"/>        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>    </bean>    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        <property name="dataSource" ref="dataSource"/>        <property name="persistenceXmlLocation" value="META-INF/persistence.xml"/>        <property name="persistenceUnitName" value="JPAExamples"/>        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>        <property name="jpaDialect" ref="jpaDialect"/>        <property name="jpaProperties">            <props>                <prop key="hibernate.show_sql">true</prop>            </props>        </property>    </bean>     <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">        <property name="generateDdl" value="false" />        <property name="database" value="MYSQL"/>    </bean>     <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>     <bean id="entityManager" factory-bean="entityManagerFactory"  factory-method="createEntityManager"></bean>    <!-- Jpa 事务管理器  -->    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"          p:entityManagerFactory-ref="entityManagerFactory" />    <!-- 开启注解事务 -->    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />     <!-- 启动对@AspectJ(面向切面)注解的支持 -->    <aop:aspectj-autoproxy />     <context:component-scan base-package="com.journaldev.spring.jpa"></context:component-scan></beans>

有的对象,不是必须的。为了保持完整性,做了保留。

可以配置entityManagerFactory的packagesToScan属性,没有配置也是可以的。

2.5 entity

package com.journaldev.spring.jpa.model;import javax.persistence.Entity;import javax.persistence.Id;@Entitypublic class Employee {    @Id    private int id;    private String name;    private String role;     public int getId() {        return id;    }     public void setId(int id) {        this.id = id;    }     public String getName() {        return name;    }     public void setName(String name) {        this.name = name;    }     public String getRole() {        return role;    }     public void setRole(String role) {        this.role = role;    }     @Override    public String toString() {        return "{ID=" + id + ",Name=" + name + ",Role=" + role + "}";    }}

2.6 接口

public interface EmployeeDAO {    //Create    public void save(Employee employee);    //Read    public Employee getById(int id);    //Update    public void update(Employee employee);    //Delete    public void deleteById(int id);    //Get All    public List<Employee> getAll();}

实现类

package com.journaldev.spring.jpa.dao; import com.journaldev.spring.jpa.model.Employee;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository; import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import javax.persistence.criteria.CriteriaBuilder;import javax.persistence.criteria.CriteriaQuery;import javax.transaction.Transactional; import java.util.List; /** * Created by zhaoguoyu on 2016/6/22. */@Transactional@Repositorypublic class EmployeeDAOImpl implements EmployeeDAO {    @PersistenceContext    EntityManager em;      @Override    public void save(Employee employee) {        em.persist(employee);    }     @Override    public Employee getById(int id) {        return em.find(Employee.class, id);    }     public void update(Employee employee) {          em.merge(employee);    }     @Override    public void deleteById(int id) {        em.remove(this.getById(id));    }     @Override    public List<Employee> getAll() {        CriteriaBuilder builder =em.getCriteriaBuilder();        final CriteriaQuery<Employee> query = builder.createQuery(Employee.class);        return this.em.createQuery(query).getResultList();    }}

2.7测试

测试类

import com.journaldev.spring.jpa.dao.EmployeeDAO;import com.journaldev.spring.jpa.model.Employee;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.annotation.Resource; import java.util.Random; /** * Created by zhaoguoyu on 2016/6/22. */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:spring.xml")public class SpringJPATest extends AbstractTransactionalJUnit4SpringContextTests {     @Resource    private EmployeeDAO employeeDAO;     @Test    public void testSave(){        Employee emp = new Employee();        int rand = new Random().nextInt(1000);        emp.setId(rand);        emp.setName("Pankaj");        emp.setRole("Java Developer");        employeeDAO.save(emp);    }    @Test    public void testUpdate(){        Employee emp = new Employee();        int rand = new Random().nextInt(1000);        emp.setId(rand);        emp.setName("Pankaj");        emp.setRole("Java Developer");        employeeDAO.save(emp);        emp.setName(emp.getName()+"_update");        employeeDAO.update(emp);    }}

OR

import com.journaldev.spring.jpa.dao.EmployeeDAO;import com.journaldev.spring.jpa.model.Employee;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.Random; /** * Created by zhaoguoyu on 2016/6/22. */public class Main {    public static void main(String[] args) {        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");        final EmployeeDAO employeeDAO = ctx.getBean(EmployeeDAO.class);        Employee emp = new Employee();        int rand = new Random().nextInt(1000);        emp.setId(rand);        emp.setName("Pankaj");        emp.setRole("Java Developer");        employeeDAO.save(emp);         Employee employee = employeeDAO.getById(rand);        employee.setName(employee.getName() +"_update");        employeeDAO.update(employee);    }}

有一点需要说明。默认使用的日志是logback.号称比log4j更优秀的一款。

默认的日志配置logback.xml

<?xml version="1.0" encoding="UTF-8"?><configuration>    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">        <layout class="ch.qos.logback.classic.PatternLayout">            <Pattern>                %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n            </Pattern>        </layout>    </appender>    <logger name="org.hibernate" level="debug" additivity="false">        <appender-ref ref="STDOUT" />    </logger>     <root level="error">        <appender-ref ref="STDOUT" />    </root> </configuration>


总结

本文主要讲解了Spring对JPA的支持,和演示了整合过程。其中JPA的内容还有很多,不可能在本文全部讲完。本系列主要是为大家提供以递进的方式,通过前后的演示对比,感觉Spring DATA API的强大。

通过JPA的整合,实现了访问数据库,完全不需要写SQL。这样的好处之一:实现了SQL的透明,可以无缝实现不同数据库厂商和数据库版本间的切换。Spring 对JPA的支持还没有结束

本文出自 “简单” 博客,请务必保留此出处http://dba10g.blog.51cto.com/764602/1791946



原创粉丝点击