首页 > 开发 > Java > 正文

Spring4整合Hibernate5详细步骤

2019-10-22 00:00:39
字体:
来源:转载
供稿:网友

Spring与Hiberante整合

通过hibernate的学习,我们知道,hibernate主要在hibernate.cfg.xml配置文件中

接下来我们看一下hibernate的一个配置文件

hibernate配置文件

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration>  <session-factory>    <!-- 指定连接数据库所用的驱动 -->    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>    <!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 -->    <property name="connection.url">jdbc:mysql://localhost/hibernate_test</property>    <!-- 指定连接数据库的用户名 -->    <property name="connection.username">root</property>    <!-- 指定连接数据库的密码 -->    <property name="connection.password">cheng</property>    <!-- 指定连接池里最大连接数 -->    <property name="hibernate.c3p0.max_size">20</property>    <!-- 指定连接池里最小连接数 -->    <property name="hibernate.c3p0.min_size">1</property>    <!-- 指定连接池里连接的超时时长 -->    <property name="hibernate.c3p0.timeout">5000</property>    <!-- 指定连接池里最大缓存多少个Statement对象 -->    <property name="hibernate.c3p0.max_statements">100</property>    <property name="hibernate.c3p0.idle_test_period">3000</property>    <property name="hibernate.c3p0.acquire_increment">2</property>    <property name="hibernate.c3p0.validate">true</property>    <!-- 指定数据库方言 -->    <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>    <!-- 根据需要自动创建数据表 -->    <property name="hbm2ddl.auto">update</property><!--①-->    <!-- 显示Hibernate持久化操作所生成的SQL -->    <property name="show_sql">true</property>    <!-- 将SQL脚本进行格式化后再输出 -->    <property name="hibernate.format_sql">true</property>    <!-- 避免这个错误信息Disabling contextual LOB creation as createClob() method threw error :java.lang.reflect.InvocationTargetException -->    <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>    <!-- 罗列所有持久化类的类名 -->    <mapping class="com.wechat.entity.po.User"/>    <mapping class="com.wechat.entity.po.Person"/>  </session-factory></hibernate-configuration>

配置文件的作用

hibernate.cfg.xml文件的主要作用就是配置了一个session-factory

  1. 在session-factory中主要通过property配置一些数据库的连接信息,我们知道,spring通常会将这种数据库连接用dataSource来表示,这样一来,hibernate.cfg.xml文件中的所有跟数据库连接的都可以干掉了,直接用spring的dataSource,而dataSource也可以用c3p0、dbcp等。
  2. 在session-factory中通过property除了配置一些数据库的连接信息之外,还有一些hibernate的配置,比如方言、自动创建表机制、格式化sql等,这些信息也需要配置起来。
  3. 还有最关键的一个持久化类所在路径的配置

当不采用spring整合的时候,我们使用hibernate时主要是用hibernate从sessionFactory中去的session,然后用session来操作持久化对象,而sessionFactory来自于配置文件。像下面这样:

  StandardServiceRegistry registry = null;  SessionFactory sessionFactory = null;  Session session = null;  Transaction transaction = null;  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  @Before  public void init() {    registry = new StandardServiceRegistryBuilder()        .configure() // configures settings from hibernate.cfg.xml        .build();    sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();    session = sessionFactory.openSession();    //开始事务    transaction = session.getTransaction();    transaction.begin();  }  @Test  public void testSaveUser() {    User user = new User();    user.setUsername("张学友");    user.setPassword("jacky");    user.setRegistDate(sdf.format(new Date()));    File file = new File("D:"+File.separator+"ubuntu.png");    String fileName = file.getName();    String prefix=fileName.substring(fileName.lastIndexOf(".")+1);    System.out.println(prefix);    InputStream input = null;    try {      input = new FileInputStream(file);    } catch (FileNotFoundException e) {      e.printStackTrace();    }    Blob image = null;    try {      image = Hibernate.getLobCreator(session).createBlob(input,input.available());    } catch (IOException e) {      // TODO Auto-generated catch block      e.printStackTrace();    }    user.setUserPic(image);    session.save(user);  }  @After   public void destroy(){    transaction.commit();    session.close();    sessionFactory.close();    StandardServiceRegistryBuilder.destroy( registry );  }

Spring对hibernate的整合就是将上述三点通过spring配置起来,而hibernate最关键的sessionFactroy就是spring的一个bean

这些理解了整合就简单了,

SessionFactoryBean

spring的sessionFactroy像下面这样配置:

<!-- 加载配置文件 -->  <context:property-placeholder location="classpath:jdbc.properties"    file-encoding="utf-8" ignore-unresolvable="true" />  <bean id="sessionFactory"    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">    <property name="dataSource" ref="dataSource" />    <property name="packagesToScan">      <list>        <!-- 可以加多个包 -->        <value>com.wechat.entity.po</value>      </list>    </property>    <property name="hibernateProperties">      <props>        <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>        <prop key="hibernate.dialect">${hibernate.dialect}</prop>        <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>        <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>        <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>      </props>    </property>  </bean>

通过bean的配置可以看出该bean就是hibernate的sessionFactroy

因为它指向了org.springframework.orm.hibernate5.LocalSessionFactoryBean

在这个bean中主要配置了上面说的三点:

  1. 数据源dataSource
  2. hibernate的配置,包括方言,输出sql等
  3. 持久化类的位置,通过包进行扫描

下面给出数据源dataSource的配置

dataSource

<!-- 配置数据源 -->  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"    destroy-method="close" p:driverClass="${jdbc.driverClassName}"    p:jdbcUrl="${jdbc.url}" p:user="${jdbc.username}" p:password="${jdbc.password}"    p:testConnectionOnCheckout="${jdbc.c3p0.testConnectionOnCheckout}"    p:testConnectionOnCheckin="${jdbc.c3p0.testConnectionOnCheckin}"    p:idleConnectionTestPeriod="${jdbc.c3p0.idleConnectionTestPeriod}"    p:initialPoolSize="${jdbc.c3p0.initialPoolSize}" p:minPoolSize="${jdbc.c3p0.minPoolSize}"    p:maxPoolSize="${jdbc.c3p0.maxPoolSize}" p:maxIdleTime="${jdbc.c3p0.maxIdleTime}" />

还有数据库的连接信息

jdbc.properties

#-----------------------------------------------------# 数据库配置#-----------------------------------------------------#服务器地址host=127.0.0.1jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://${host}:3306/hibernate_testjdbc.username=rootjdbc.password=cheng#-----------------------------------------------------# 适用于c3p0的配置#-----------------------------------------------------#-----------------------------------------------------# c3p0反空闲设置,防止8小时失效问题28800#-----------------------------------------------------#idleConnectionTestPeriod要小于MySQL的wait_timeoutjdbc.c3p0.testConnectionOnCheckout=falsejdbc.c3p0.testConnectionOnCheckin=truejdbc.c3p0.idleConnectionTestPeriod=3600#-----------------------------------------------------# c3p0连接池配置#-----------------------------------------------------#initialPoolSize, minPoolSize, maxPoolSize define the number of Connections that will be pooled.#Please ensure that minPoolSize <= maxPoolSize.#Unreasonable values of initialPoolSize will be ignored, and minPoolSize will be used instead.jdbc.c3p0.initialPoolSize=10jdbc.c3p0.minPoolSize=10jdbc.c3p0.maxPoolSize=100#maxIdleTime defines how many seconds a Connection should be permitted to go unused before being culled from the pool.jdbc.c3p0.maxIdleTime=3600#-----------------------------------------------------# hibernate连接池配置#-----------------------------------------------------hibernate.connection.driverClass=com.mysql.jdbc.Driverhibernate.connection.url=jdbc:mysql://${host}:3306/${dbName}hibernate.dialect=org.hibernate.dialect.MySQL5Dialecthibernate.show_sql=truehibernate.format_sql=truehibernate.hbm2ddl.auto=update

配置完这些还有spring强大的事务管理

<!-- 配置Hibernate事务管理器 -->  <bean id="transactionManager"    class="org.springframework.orm.hibernate5.HibernateTransactionManager">    <property name="sessionFactory" ref="sessionFactory" />  </bean>  <!-- 配置事务异常封装 -->  <bean id="persistenceExceptionTranslationPostProcessor"    class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />  <!-- 基于数据源的事务管理器 -->  <!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"     p:dataSource-ref="dataSource" /> -->  <!-- 配合<tx:advice>和<aop:advisor>完成了事务切面的定义 -->  <!-- 使用强大的切点表达式是语言轻松定义目标方法 -->  <aop:config proxy-target-class="true">    <!-- 通过aop定义事务增强切面 -->    <aop:pointcut expression=" execution(* com.wechat.service..*(..))"      id="serviceMethod" />    <!-- 引用事务增强 -->    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />  </aop:config>  <!-- 事务增强 -->  <tx:advice id="txAdvice" transaction-manager="transactionManager">    <!-- 事务属性定义 -->    <tx:attributes>      <tx:method name="*" />    </tx:attributes>  </tx:advice>

好了,这些配置好之后就可以使用在spring中配置的sessionFactroy了

UserDao

package com.wechat.dao;import java.util.List;import com.wechat.entity.po.User;public interface UserDao {  // 得到所有用户  public List<User> getAllUser();  // 检测用户名是否存在  public boolean isExists(String username);}

实现类

package com.wechat.dao.impl;import java.util.ArrayList;import java.util.List;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;import com.wechat.dao.UserDao;import com.wechat.entity.po.User;@Repositorypublic class UserDaoImpl implements UserDao {  //注入sessionFactory  @Autowired  private SessionFactory sessionFactory;  @SuppressWarnings("unchecked")  @Override  public List<User> getAllUser() {    List<User> userList = new ArrayList<User>();    String hsql="from User";    Session session = sessionFactory.getCurrentSession();    Query query = session.createQuery(hsql);    userList = query.list();    return userList;  }  @Override  public boolean isExists(String username) {    Query query = sessionFactory.openSession()        .createQuery("from User u where u.username = :username").setParameter("username", username);    System.out.println(query.list().size());    return query.list().size()>0?true:false;  }}

UserService

package com.wechat.service.user;import java.util.List;import com.wechat.entity.po.User;public interface UserService {  public List<User> getAllUser();  public boolean isExists(String username);}

实现类

package com.wechat.service.user.impl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import com.wechat.dao.UserDao;import com.wechat.entity.po.User;import com.wechat.service.user.UserService;@Servicepublic class UserServiceImpl implements UserService {  @Autowired  private UserDao userDao;  @Override  public List<User> getAllUser() {    return userDao.getAllUser();  }  @Override  @Cacheable(cacheNames="isExists", key="#username")  public boolean isExists(String username) {    return userDao.isExists(username);  }}

因为事务管理是配置在service层,所以用service来测试

测试

package com.wechat.dao;import java.util.List;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.wechat.entity.po.User;import com.wechat.service.user.UserService;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = { "classpath:spring/spring-core.xml" })public class UserServiceTest {  @Autowired  private UserService userService;  @Test  public void test() {    List<User> userList = userService.getAllUser();    for(User user:userList){      System.out.println(user.getUsername());    }  }}

输入结果

Hibernate:   select    user0_.userid as userid1_2_,    user0_.password as password2_2_,    user0_.registDate as registDa3_2_,    user0_.userPic as userPic4_2_,    user0_.username as username5_2_   from    user_info user0_程高伟张学友

数据库表

spring整合hibernate5,spring,hibernate整合,spring4,hibernate5

好了Spring整合hibernate就写到这里。

项目地址:https://github.com/peer44/testwechat

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CuoXin错新网。


注:相关教程知识阅读请移步到JAVA教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表