Spring整合Hibernate实现JPA持久化

Posted 云水之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring整合Hibernate实现JPA持久化相关的知识,希望对你有一定的参考价值。

Spring整合Hibernate实现JPA持久化

 

本篇文章主要介绍Spring如何集成JPA的功能,并实现基本的CURD操作。JPA,全称为JavaPersistence API,诞生与EJB2实体Bean之上,是一种新的Java持久化标准,也是基于POJO的持久化机制,它的设计灵感来源于Hibernate和Java数据对象(JDO)。

 

l  Maven管理软包依赖

l  配置实体管理器工厂

l  用JPA方式实现CURD

 

 

一、Maven管理软包依赖

这里采用Maven来集成和管理Spring、Hibernate及其它相关的软件包依赖,好处就不多说了。需要注意的是Spring和Hibernate的版本选择必须兼容,否则就会出现各种问题(笔者可是吃过亏的哦),具体各个版本的对应关系,请看下面的pom.xml配置:

 

<properties>

  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <project.tomcat.version>8.0.0-RC5</project.tomcat.version>

    <spring.version>4.3.0.RELEASE</spring.version>

    <hibernate.version>5.2.2.Final</hibernate.version>

    <mysql.connector.version>5.1.30</mysql.connector.version>

    <junit.version>4.12</junit.version>

    <javax.servlet-api.version>3.1.0</javax.servlet-api.version>

    <javax.servlet.jsp.version>2.3.1</javax.servlet.jsp.version>

    <slf4j.version>1.7.5</slf4j.version>

    <jstl.version>1.2</jstl.version>

  </properties>

 

  <dependencies>

    <dependency>

      <groupId>junit</groupId>

      <artifactId>junit</artifactId>

      <version>$junit.version</version>

      <scope>test</scope>

    </dependency>

    <!-- Logger -->

    <dependency> 

       <groupId>org.slf4j</groupId> 

       <artifactId>slf4j-api</artifactId> 

       <version>$slf4j.version</version> 

    </dependency> 

    <dependency> 

       <groupId>org.slf4j</groupId> 

       <artifactId>jcl-over-slf4j</artifactId> 

       <version>$slf4j.version</version> 

    </dependency> 

    <dependency> 

       <groupId>org.slf4j</groupId> 

       <artifactId>slf4j-log4j12</artifactId> 

       <version>$slf4j.version</version> 

    </dependency>

    <!-- Spring  -->

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-core</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-web</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-webmvc</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-context</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-beans</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-tx</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-jdbc</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

       <groupId>org.springframework</groupId>

       <artifactId>spring-aop</artifactId>

       <version>$spring.version</version>

    </dependency>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-orm</artifactId>

        <version>$spring.version</version>

    </dependency>

    <!-- Servlet+JSP+jstl-->

    <dependency>

       <groupId>javax.servlet</groupId>

       <artifactId>javax.servlet-api</artifactId>

       <version>$javax.servlet-api.version</version>

       <scope>provided</scope>

    </dependency>

    <dependency>

       <groupId>javax.servlet.jsp</groupId>

       <artifactId>javax.servlet.jsp-api</artifactId>

       <version>$javax.servlet.jsp.version</version>

    </dependency>

    <dependency>

        <groupId>javax.servlet</groupId>

        <artifactId>jstl</artifactId>

        <version>$jstl.version</version>

    </dependency>

    <!-- Hibernate -->

    <dependency>

       <groupId>org.hibernate</groupId>

       <artifactId>hibernate-core</artifactId>

       <version>$hibernate.version</version>

    </dependency>

    <dependency>

       <groupId>org.hibernate</groupId>

       <artifactId>hibernate-entitymanager</artifactId>

       <version>$hibernate.version</version>

    </dependency>

    <dependency>

       <groupId>org.hibernate</groupId>

       <artifactId>hibernate-c3p0</artifactId>

       <version>$hibernate.version</version>

    </dependency>

    <!-- Mysql -->

    <dependency>

       <groupId>mysql</groupId>

       <artifactId>mysql-connector-java</artifactId>

       <version>$mysql.connector.version</version>

    </dependency>

    <!-- apache commons --> 

    <dependency> 

       <groupId>commons-dbcp</groupId> 

       <artifactId>commons-dbcp</artifactId> 

       <version>20030825.184428</version> 

    </dependency> 

    <dependency> 

       <groupId>commons-pool</groupId> 

       <artifactId>commons-pool</artifactId> 

       <version>20030825.183949</version> 

    </dependency> 

    <dependency> 

       <groupId>commons-collections</groupId> 

       <artifactId>commons-collections</artifactId> 

       <version>2.1</version> 

    </dependency>

  </dependencies>

 

 

二、配置实体管理器工厂

我们知道,基于JPA的应用程序需要使用EntityManagerFactory的实现来获取EntityManager实例,目前JPA定义了两种类型的实体管理器,它们分别是:应用程序管理类型和容器管理类型。对于前者,程序需要负责打开和关闭实体管理器,并要在事务中对其进行控制,此种方式的实体管理器适合于非运行在Java EE容器中的独立应用程序;而后者,应用程序不需要与实体管理器工厂交互,而是交由容器与其进行交互,实体管理器可直接注入或JNDI来获取,此种类型的实体管理器适合于Java EE容器,所以这里介绍后者。

 

1、声明实体管理器工厂

    @Bean

    public LocalContainerEntityManagerFactoryBean entityManagerFactory()

       LocalContainerEntityManagerFactoryBean emf =new LocalContainerEntityManagerFactoryBean();

       emf.setDataSource(dataSource());

       emf.setJpaVendorAdapter(hibernateJpaVendorAdapter());

       emf.setPackagesToScan("com.cwteam.orm.model");      // 替代persistences.xml,对该路径下的@Entity扫描初始化

      

       Map<String,String> jpsMaps =new HashMap<String,String>();    // 实体管理器参数的配置

       jpsMaps.put("hibernate.show_sql","true");

       jpsMaps.put("hibernate.hbm2ddl.auto","update");

       jpsMaps.put("hibernate.dialect","org.hibernate.dialect.MySQLDialect");

       emf.setJpaPropertyMap(jpsMaps);

       returnemf;

   

 

这里设置了数据源dataSource和指定了选用哪种类型实现的JPA,这里选用了HibernateJpaVendorAdapter适配器,并且使用setPackagesToScan来自动初始化扫描模型Entity实体类,替代了传统的persistences.xml类似的作用。

 

dataSource配置:

   @Bean

    public BasicDataSource dataSource()

       BasicDataSource dataSource =new BasicDataSource();

       dataSource.setDriverClassName("com.mysql.jdbc.Driver");

       dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8");

       dataSource.setUsername("root");

       dataSource.setPassword(null);

       dataSource.setDefaultAutoCommit(false);

       returndataSource;

   

 

hibernateJpaVendorAdaptor配置:

   @Bean

    public JpaVendorAdapter hibernateJpaVendorAdapter()

       HibernateJpaVendorAdapter jpaVA =new HibernateJpaVendorAdapter();

       jpaVA.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");     // MySQL平台指定

       returnjpaVA;

   

 

完整的Spring上下文配置如下:

@Configuration

@ComponentScan("com.cwteam.orm.*")

@EnableTransactionManagement      // 开启事务及对注解@Transactional的支持

public class SpringConfig

    // 实体管理工厂配置

    @Bean

    public LocalContainerEntityManagerFactoryBean entityManagerFactory()

       LocalContainerEntityManagerFactoryBean emf =new LocalContainerEntityManagerFactoryBean();

       emf.setDataSource(dataSource());

       emf.setJpaVendorAdapter(hibernateJpaVendorAdapter());

       emf.setPackagesToScan("com.cwteam.orm.model");      // 替代persistences.xml,对该路径下的@Entity扫描初始化

      

       Map<String,String>jpsMaps =new HashMap<String,String>();    // 实体管理器参数的配置

       jpsMaps.put("hibernate.show_sql","true");

       jpsMaps.put("hibernate.hbm2ddl.auto","update");

       jpsMaps.put("hibernate.dialect","org.hibernate.dialect.MySQLDialect");

       emf.setJpaPropertyMap(jpsMaps);

       returnemf;

   

   

    // JPA的实体适配器

    @Bean

    public JpaVendorAdapter hibernateJpaVendorAdapter()

       HibernateJpaVendorAdapter jpaVA =new HibernateJpaVendorAdapter();

       jpaVA.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");     // MySQL平台指定

       returnjpaVA;

   

   

    // 数据源的配置

    @Bean

    public BasicDataSource dataSource()

       BasicDataSource dataSource =new BasicDataSource();

       dataSource.setDriverClassName("com.mysql.jdbc.Driver");

       dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8");

       dataSource.setUsername("root");

       dataSource.setPassword(null);

       dataSource.setDefaultAutoCommit(false);

       returndataSource;

   

   

    // Spring Data JPA事务配置

    @Bean

    public JpaTransactionManager transactionManager()

       JpaTransactionManager jpaTm =new JpaTransactionManager();

       jpaTm.setEntityManagerFactory(entityManagerFactory().getObject());

       returnjpaTm;

   

 

 

2、Model

User.java:

@Entity

@Table(name = "user")

public class User

   private Stringid;

   private Stringusername;

   private Stringpassword;

   private Stringmobile;

   private Stringemail;

  

    @Id 

    @GeneratedValue(generator="system-uuid"

    @GenericGenerator(name="system-uuid",strategy="uuid")

   public String getId()

      return id;

  

    .....

 

 

3、Dao

UserDao.java:

public interface UserDao

    // 新增记录

    void save(Useruser);

    // 修改记录

    void update(Useruser);

    // 根据用户名查询

    User findUserByID(User user);

    // 查询所有记录

    List<User> findUsersNoPage();

    // 删除一条记录

    void delete(Useruser);

 

 

UserDaoImpl.java:

@Repository("UserDaoImpl")

public class UserDaoImpl implements UserDao

    @PersistenceContext

    private EntityManagerem;

   

    @Override

    public void save(User user)

       em.persist(user);

   

   

    @Override

    public void update(User user)

       em.persist(em.merge(user));

   

 

    @Override

    public User findUserByID(Useruser)

       returnem.find(User.class,user.getId());

   

 

    @Override

    public List<User> findUsersNoPage()

       String queryString = "select * from user";

       Query query = em.createNativeQuery(queryString,User.class);

       List<?> result = query.getResultList();

       List<User> users = new ArrayList<User>();

       if (result !=null)

           Iterator<?> iterator =result.iterator();

           while (iterator.hasNext())

              User user = (User)iterator.next();

              users.add(user);

          

      

       returnusers;

   

 

    @Override

    public void delete(User user)

       em.remove(em.merge(user));

   

 

这里的@Repository注解,是Spring支持的初始化标记注解,容器初始化扫描时,会自动扫描到该标记的Dao服务实体,进而初始化。另外,这里使用的persist、find、remove及merge等均是EntityManager提供的原生API,这里不做详细介绍,有兴趣的读者可自行查阅资料学习。

 

4、Service

UserService.java:

@Service("UserService")

public class UserService

    @Autowired

    private UserDaouserDao;

   

    // 新增记录

    @Transactional

    public void saveUser(User user)

       userDao.save(user);

   

   

    // 更新记录

    @Transactional

    public void updateUser(User user)

       User result = findUserByID(user);

       result.setUsername(user.getUsername());

       result.setPassword(user.getPassword());

       result.setEmail(user.getEmail());

       result.setMobile(user.getMobile());

   

   

    // 根据用户名查询记录

    public User  findUserByID(Useruser)

       returnuserDao.findUserByID(user);

   

   

    // 查询所有记录

    public List<User>  findUsersNoPage()

       returnuserDao.findUsersNoPage();

   

   

    // 根据用户名删除记录

    @Transactional

    public void delete(User user)

       userDao.delete(user);

   

 

这里的@Service与上面的@Respository类似,暂且不做细节上差别说明。

 

 

三、用JPA方式实现CURD

上面的准备工作完成后,接下来我们就可以编写CURD的程序代码了。

 

1、控制器

UserController.java:

@Controller

@RequestMapping("/user")

public class UserController

    @Autowired

    UserServiceuserService;

   

    // 操作页面

    @RequestMapping(value="/show",method=RequestMethod.GET)

    public ModelAndView show()throws Exception

       // 业务逻辑处理

       List<User> result = userService.findUsersNoPage();

       // 页面数据渲染

       ModelAndView mav = new ModelAndView("test/user_operation");

       mav.addObject("result",result);

       returnmav;

   

   

    // 新增记录

    @RequestMapping(value="/save",method=RequestMethod.POST)

    public ModelAndView save(HttpServletRequestrequest) throws Exception

       User user = new User();

       user.setUsername(request.getParameter("username"));

       user.setPassword(request.getParameter("password"));

       user.setMobile(request.getParameter("mobile"));

       user.setEmail(request.getParameter("email"));

       // 业务逻辑处理

       userService.saveUser(user);

       // 页面数据渲染

       ModelAndView mav = new ModelAndView("test/user_operation");

       mav.addObject("result",userService.findUsersNoPage());

       returnmav;

   

   

    // 更新记录

    @RequestMapping(value="/update",method=RequestMethod.POST)

    public ModelAndView update(HttpServletRequestrequest) throws Exception

       User user = new User();

       user.setId(request.getParameter("id"));

       user.setUsername(request.getParameter("username"));

       user.setPassword(request.getParameter("password"));

       user.setMobile(request.getParameter("mobile"));

       user.setEmail(request.getParameter("email"));

       // 业务逻辑处理

       userService.updateUser(user);

       // 页面数据渲染

       ModelAndView mav = new ModelAndView("test/user_operation");

       mav.addObject("result",userService.findUsersNoPage());

       returnmav;

   

   

    // 根据ID查询

    @RequestMapping(value="/find",method=RequestMethod.GET)

    public ModelAndView find(HttpServletRequestrequest) throws Exception

       User user = new User();

       user.setId(request.getParameter("id"));

       // 业务逻辑处理

       Useruser2 = userService.findUserByID(user);

以上是关于Spring整合Hibernate实现JPA持久化的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 整合 JPA 使用多个数据源

Spring,JPA与Hibernate的最新整合范例视频

spring boot2 整合JPA(特别完整!)

Spring Boot:整合Spring Data JPA

Spring整合Hibernate实现Spring Data JPA (简单使用)

spring boot如何整合springdatajpa