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);

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

       result.add(user2);

       // 页面数据渲染

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

       mav.addObject("result",result);

       returnmav;

    }

   

    // 根据ID删除记录

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

    public ModelAndView delete(HttpServletRequestrequest) throws Exception {

       User user = new User();

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

       // 业务逻辑处理

       userService.delete(user);

       // 页面数据渲染

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

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

       returnmav;

    }

}

 

2、测试页面

user_operation.jsp:

<%@ page language="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%>

<%@ taglib prefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

 

<!DOCTYPEhtmlPUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

<head>

    <scripttype="text/javascript"src="${pageContext.request.contextPath}/resources/js/jquery.min.js"></script>

    <scripttype="text/javascript"src="${pageContext.request.contextPath}/resources/js/jquery.form.js"></script>

   

    <style>

       .input {width:98%;height:20px;}

    </style>

</head>

<body>

    <scripttype="text/javascript">

       // 显示新增记录视图

       function create_show(){

           $("#id_mod_record").hide();

           $("#id_add_record").show();

       }

      

       // 显示更新记录视图

       function update_show(id,username,password,email,mobile){

           $("#id_form_val").val(id);

           $("#username_form_val").val(username);

           $("#password_form_val").val(password);

           $("#email_form_val").val(email);

           $("#mobile_form_val").val(mobile);

          

           $("#id_add_record").hide();

           $("#id_mod_record").show();

       }

      

       // 根据ID查询单条记录

       function find() {

           var id = $("#id_search_val").val();

           window.location.href= "/spring-orm-jpa/user/find?id="+id;

       }

      

    </script>

    <div>

       <!-- 根据ID查询记录 -->

       <div>

               <table>

                  <tr>

                      <tdalign="left"><pstyle="line-height:10px;font-size:14px;">ID:</p></td>

                      <tdalign="left"><inputstyle="width:240px;"type="text"name="id"id="id_search_val"value="402881e85fce9aac015fce9aded30000"placeholder="id"/></td>

                      <td>  <input type="button"onclick="javascript:find();"value="点击根据ID查询"/></td>

                      <td><inputstyle="margin-left:386px;"type="button"onclick="javascript:create_show();"value="点击新增"/></td>

                  </tr>

               </table>  

            </div>

           

       <!-- 所有记录列表 -->

       <div>

           <tableborder="1px;"cellspacing="0"cellpadding="0">

              <tr><td>ID</td><td>UserName</td><td>Password</td><td>Email</td><td>Mobile</td><td>操作</td></tr>

                  <c:forEachitems="${result}"var="item"> 

                     <inputtype="hidden"class="c_user_val"value="${item}"></input>

                        <tr>

                            <td><c:outvalue="${item.id}"></c:out></td>

                            <td><c:outvalue="${item.username}"></c:out></td>

                            <td><c:outvalue="${item.password}"></c:out></td>

                            <td><c:outvalue="${item.email}"></c:out></td>

                            <td><c:outvalue="${item.mobile}"></c:out></td>

                            <td>

                                 <ahref="javascript:update_show('${item.id}','${item.username}','${item.password}','${item.email}','${item.mobile}');"

                                    onclick="">&nbsp;&nbsp;编辑&nbsp;&nbsp;</a>|

                                 <ahref="/spring-orm-jpa/user/delete?id=${item.id}">&nbsp;&nbsp;删除&nbsp;&nbsp;</a>

                            </td>

                        </tr>

                    </c:forEach>

           </table>

       </div>

      

       <!-- 新增记录 -->

       <divid="id_add_record"style="display:block;margin-top:20px;">

           <formmethod="post"action="/spring-orm-jpa/user/save">

                  <tableborder="1px;"cellspacing="0"cellpadding="0"width="400">

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">UserName:</p></td>

                          <tdalign="left"><inputclass="input"type="text"name="username"value="cwteam"placeholder="username"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">Password:</p></td>

                          <tdalign="left"><inputclass="input"type="password"name="password"value="123456"placeholder="password"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">Mobile:</p></td>

                          <tdalign="left"><inputclass="input"type="text"name="mobile"value="18721663282"placeholder="mobile"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">Email:</p></td>

                          <tdalign="left"><inputclass="input"type="text"name="email"value="123456@qq.com"placeholder="email"/></td>

                      </tr>

                   </table>

                   <inputstyle="margin-left:160px;margin-top:10px;"type="submit"value="新增记录"/>

               </form>

            </div>

       

        <!-- 更新记录 -->

        <divid="id_mod_record"style="display:none;margin-top:20px;">

           <formmethod="post"action="/spring-orm-jpa/user/update">

                  <tableborder="1px;"cellspacing="0"cellpadding="0"width="400">

                      <tr>

                          <tdalign="left"><pstyle="line-height:10px;font-size:14px;">ID:</p></td>

                          <tdalign="left"><inputclass="input"id="id_form_val"type="text"name="id"value="402881e85fce9aac015fce9aded30000"placeholder="id"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:10px;font-size:14px;">UserName:</p></td>

                          <tdalign="left"><inputclass="input"id="username_form_val"type="text"name="username"value="cwteam2"placeholder="username"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">Password:</p></td>

                          <tdalign="left"><inputclass="input"id="password_form_val"type="password"name="password"value="1234567"placeholder="password"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">Mobile:</p></td>

                          <tdalign="left"><inputclass="input"id="mobile_form_val"type="text"name="mobile"value="18721663283"placeholder="mobile"/></td>

                      </tr>

                      <tr>

                          <tdalign="left"><pstyle="line-height:0px;font-size:14px;">Email:</p></td>

                          <tdalign="left"><inputclass="input"id="email_form_val"type="text"name="email"value="123456789@qq.com"placeholder="email"/></td>

                      </tr>

                   </table>

                   <inputstyle="margin-left:160px;margin-top:10px;"type="submit"value="更新记录"/>

               </form>

            </div>

    </div>

</body>

</html>

 

 

3、验证结果

整体的结果:

 

A、新增一条记录

新增了cwteam7记录

 

 

B、修改一条记录

更新了cwteam6记录,修改了email值。

 

 

C、删除一条记录

删除了cwteam5记录

 

D、根据ID查询记录:

根据ID查询了cwteam4的单条记录信息

 

 

 

 

 

 

 

 

 

好了,由于作者水平有限,如有不正确或是误导的地方,请不吝指出讨论(技术交流群:497552060(新))

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云水之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值