欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring4整合Hibernate5详细步骤

程序员文章站 2024-02-27 19:04:03
spring与hiberante整合 通过hibernate的学习,我们知道,hibernate主要在hibernate.cfg.xml配置文件中 接下来我们看一...

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.1
jdbc.driverclassname=com.mysql.jdbc.driver
jdbc.url=jdbc:mysql://${host}:3306/hibernate_test
jdbc.username=root
jdbc.password=cheng

#-----------------------------------------------------
# 适用于c3p0的配置
#-----------------------------------------------------
#-----------------------------------------------------
# c3p0反空闲设置,防止8小时失效问题28800
#-----------------------------------------------------
#idleconnectiontestperiod要小于mysql的wait_timeout
jdbc.c3p0.testconnectiononcheckout=false
jdbc.c3p0.testconnectiononcheckin=true
jdbc.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=10
jdbc.c3p0.minpoolsize=10
jdbc.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.driver
hibernate.connection.url=jdbc:mysql://${host}:3306/${dbname}
hibernate.dialect=org.hibernate.dialect.mysql5dialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.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;
@repository
public 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;
@service
public 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_
程高伟
张学友

数据库表

Spring4整合Hibernate5详细步骤

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

项目地址:

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