【Spring实战】----Spring4.3.2集成Hibernate5.2.5

本篇讲Spring4.3.2集成Hibernate5.2.5(目前最新版本),先说下环境配置

一、环境配置

1)jdk1.8.0_101,Hibernate5.2.5要求jdk8

2)tomcat8.0.0,由于8以下版本和jdk8不兼容,所以采取tomcat8

3)mysql5.1.38

4)需要的库

//hibernate
	compile group: 'org.springframework', name: 'spring-orm', version: "$springVersion"
    compile group: 'org.hibernate', name: 'hibernate-core', version: '5.2.5.Final'
	
	//mysql
	compile "mysql:mysql-connector-java:5.1.38" 
	
	//c3p0 
	//compile "c3p0:c3p0:0.9.1.2"
	compile group: 'org.hibernate', name: 'hibernate-c3p0', version: '5.2.5.Final'
	//aspectj
	compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.9'

二、数据源和Hibernate5配置

1)数据源配置applicationContext-dao.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:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">

	<context:property-placeholder location="classpath:jdbc.properties"/>
	
	<!-- 配置数据源  -->	
	<!-- 配置C3P0连接池: -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="${jdbc.driver}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		<!--每5小时检查所有连接池中的空闲连接。防止mysql wait_timeout(默认的为8小时) -->
		<property name="idleConnectionTestPeriod" value="${jdbc.c3p0.idleConnectionTestPeriod}"/>	
	</bean>
	
	<!-- 配置hibernate -->
	<bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <!-- 可以加多个包 -->
                <value>com.mango.jtt.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>
    
    <!--<start id="bean_exception_translation_post_processor" />--> 
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
 	<!--<end id="bean_exception_translation_post_processor" />-->
    <context:component-scan base-package="com.mango.jtt"></context:component-scan>

</beans>

其中数据源的配置是采用的c3p0资源池,c3p0的基本配置可参考:C3P0连接池+MySQL的配置以及wait_timeout问题的解决(Hibernate官方文档中说,当使用c3p0资源池时,应用程序必须将 hibernate-c3p0 的 jar 包(还有它的辅助包)放到 classpath 中。),jdbc.properties文件如下:<context:property-placeholder/>标签可参考Spring类PropertyPlaceholderConfigurer的作用

#-----------------------------------------------------
# 数据库配置
#-----------------------------------------------------
#服务器地址
host=127.0.0.1
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://${host}:3306/hhl
jdbc.username=root
jdbc.password=123456

#-----------------------------------------------------
# 适用于c3p0的配置
#-----------------------------------------------------
#-----------------------------------------------------
# c3p0反空闲设置,防止8小时连接失效问题28800
#-----------------------------------------------------
#idleConnectionTestPeriod要小于MySQL的wait_timeout 默认为8小时
jdbc.c3p0.testConnectionOnCheckout=false
jdbc.c3p0.testConnectionOnCheckin=true
jdbc.c3p0.idleConnectionTestPeriod=18000
#-----------------------------------------------------
# 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.dialect=org.hibernate.dialect.MySQL5Dialect        #方言类型
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=update                                #自动建表功能


2)hibernate5配置

sessionFactory用的是LocalSessionFactoryBean,4以后就只有这一种结合了两者,3以前包括AnnotationSessionFactoryBean

org.springframework.orm.hibernate5.LocalSessionFactoryBean

并且使用的是使用packagesToScan属性告诉Spring扫描一个或多个包以查找域类,这些类通过注解的方式表明要使用Hibernate进行持久化,这些类可以使用的注解包括JPA@Entity@MappedSuperclass以及Hibernate@Entity


三、pojo的定义

其中用的注解的方式进行的映射,@Id是必须有的,@Column非必须,如果字段名和列名相同的话就不需要加

Product.java

package com.mango.jtt.po;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;


/**
 * @author HHL
 * 
 * @date 2016年9月12日
 * 
 *       商品类
 */
@Entity
@Table(name = "product")
public class Product extends BaseBean {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3844317879498218112L;

	/**
	 * 商品id
	 */
	@Id
	private String productId;
	/**
	 * 商品名称
	 */
	private String productName;
	/**
	 * 商品单价
	 */
	private double unitPrice;
	/**
	 * 库存
	 */
	private double quantity;
	/**
	 * 单位
	 */
	private String unit;
	/**
	 * 商品图片地址
	 */
	private String picture;

	public String getProductId() {
		return productId;
	}

	public void setProductId(String productId) {
		this.productId = productId;
	}
	public double getQuantity() {
		return quantity;
	}
	public void setQuantity(double quantity) {
		this.quantity = quantity;
	}
	public String getProductName() {
		return productName;
	}
	public void setProductName(String productName) {
		this.productName = productName;
	}
	public double getUnitPrice() {
		return unitPrice;
	}
	public void setUnitPrice(double unitPrice) {
		this.unitPrice = unitPrice;
	}
	public String getUnit() {
		return unit;
	}
	public void setUnit(String unit) {
		this.unit = unit;
	}
	public String getPicture() {
		return picture;
	}
	public void setPicture(String picture) {
		this.picture = picture;
	}
	
}


四、dao类

/**
 * 
 */
package com.mango.jtt.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * @author HHL
 *
 * @date 2016年11月30日
 */
@Repository
public class MangoDaoImpl implements IMangoDao {
	@Autowired
	private SessionFactory sessionFactory;

	private Session currentSession() {
		return sessionFactory.getCurrentSession();
	}

	/* (non-Javadoc)
	 * @see com.mango.jtt.dao.MangoDao#list(java.lang.String)
	 */
	@Override
	public List list(String querySql) {
		Query<?> query = currentSession().createQuery(querySql);
		return query.getResultList();
	}

	@Override
	public Object get(Class clazz, String productId) {
		return currentSession().get(clazz, productId);
	}

	@Override
	public void saveBean(Object object) {
		currentSession().save(object);

	}

	@Override
	public void updateBean(Object object) {
		currentSession().update(object);

	}

}

使用@Repository注解,这会为我们做两件事情。首先,@RepositorySpring的另一种构造性注解,它能够像其他注解一样被Spring的组件扫描所扫描到。这样就不必明确声明HibernateSpitterRepositorybean了,只要这个Repository类在组件扫描所涵盖的包中即可。除了帮助减少显式配置以外,@Repository还有另外一个用处。让我们回想一下模板类,它有一项任务就是捕获平台相关的异常,然后使用Spring统一非检查型异常的形式重新抛出。如果我们使用Hibernate上下文Session而不是Hibernate模板的话,那异常转换会怎么处理呢?为了给不使用模板的Hibernate Repository添加异常转换功能,我们只需在Spring应用上下文中添加一个PersistenceExceptionTranslationPostProcessorbean,PersistenceExceptionTranslationPostProcessor是一个bean后置处理器(bean post-processor),它会在所有拥有@Repository注解的类上添加一个通知器(advisor),这样就会捕获任何平台相关的异常并以Spring非检查型数据访问异常的形式重新抛出。

使用@Autowired注解(基于类型进行装配)将SessionFactory装配进来,使用sessionFactory.getCurrentSession()来获取当前事务的session,sessionFactory.getCurrentSession()的使用需要配置spring事务,否则会抛Could not obtain transaction-synchronized Session for current thread异常,applicationContext-transaction.xml,异常和事务的配置会在后面的文章中详解

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	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.xsd 
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx.xsd ">
		
	<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<!-- 通知 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 传播行为 -->
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
			<tx:method name="insert*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="list*" propagation="SUPPORTS" read-only="true"/>
			<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- aop -->
	<aop:config>
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mango.jtt.service.*.*(..))"/>
	</aop:config>

	<!-- 注解管理事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>


五、Service类

/**
 * 
 */
package com.mango.jtt.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mango.jtt.dao.IMangoDao;
import com.mango.jtt.po.Product;

/**
 * @author HHL
 *
 * @date 2016年11月30日
 */
@Service
public class ProductServiceImpl implements IProductService {

	@Autowired
	private IMangoDao dao;

	/* (non-Javadoc)
	 * @see com.mango.jtt.service.ProductService#getProductList()
	 */
	@Override
	public List<Product> getProductList() {
		String sql = "from Product";
		return dao.list(sql);
	}

	@Override
	public Product getProductById(String productId) {

		return (Product) dao.get(Product.class, productId);
	}

}


/**
 * 
 */
package com.mango.jtt.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mango.jtt.dao.IMangoDao;
import com.mango.jtt.po.Order;

/**
 * @author HHL
 *
 * @date 2016年12月1日
 */
@Service
public class OrderService implements IOrderService {
	@Autowired
	private IMangoDao dao;

	/* (non-Javadoc)
	 * @see com.mango.jtt.service.IOrderService#addOrder(com.mango.jtt.po.Order)
	 */
	@Override
	public void saveOrder(Order order) {
		dao.saveBean(order);

	}

	/* (non-Javadoc)
	 * @see com.mango.jtt.service.IOrderService#getOrderById(java.lang.String)
	 */
	@Override
	public Order getOrderById(String orderId) {
		return (Order) dao.get(Order.class, orderId);
	}

	/* (non-Javadoc)
	 * @see com.mango.jtt.service.IOrderService#updateOrderPay(com.mango.jtt.po.Order)
	 */
	@Override
	public void updateOrder(Order order) {
		dao.updateBean(order);
	}

}


利用@Autowired注解就可以使用dao类了


六、springMVC的使用

/**
 * 
 */
package com.mango.jtt.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.mango.jtt.po.Product;
import com.mango.jtt.service.IProductService;

/**
 * @author HHL
 *
 * @date 2016年11月30日
 */
@Controller
public class ProductController {
	@Autowired
	private IProductService productService;
	
	@RequestMapping("/product/{productId}")
	public String getProductById(Model model, @PathVariable String productId) {
		Product product = productService.getProductById(productId);
		model.addAttribute("product", product);
		return "product_detail";
	}

}


/**
 * 
 */
package com.mango.jtt.controller;

import java.util.Date;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.mango.jtt.po.Order;
import com.mango.jtt.service.IOrderService;
import com.mango.jtt.util.DateUtil;

/**
 * 订单控制类
 * 
 * @author HHL
 * 
 * @date 2016年12月1日
 */
@Controller
public class OrderController {
	@Autowired
	private IOrderService orderService;

	/**
	 * @param order
	 * @param session
	 * @param model
	 * @return 保存订单
	 */
	@RequestMapping("order/submit")
	public String orderSubmit(Order order, HttpSession session, Model model) {

		order.setTotalPrice(order.getUnitPrice() * order.getNumber());
		order.setOrderId(DateUtil.getDateFormat1(new Date()));
		order.setCreateTime(DateUtil.getDateFormat2(new Date()));
		// Customer user = (Customer) session.getAttribute("user");
		orderService.saveOrder(order);
		// 改用spring aspect
		// LogUtil.testLogError("addOrder 返回值:" + res, null);
		model.addAttribute("orderId", order.getOrderId());
		// 防止重复提交
		return "redirect:/order/{orderId}";
	}

	/**
	 * @param orderId
	 * @param model
	 * @return 订单信息
	 */
	@RequestMapping("order/{orderId}")
	public String orderSave(@PathVariable String orderId, Model model) {
		Order order = orderService.getOrderById(orderId);
		model.addAttribute("order", order);
		return "order_submit";
	}

	/**
	 * @param orderId
	 * @param model
	 * @return 订单支付信息
	 */
	@RequestMapping("pay/{orderId}")
	public String orderPayInfo(@PathVariable String orderId, Model model) {
		Order order = orderService.getOrderById(orderId);
		model.addAttribute("order", order);
		return "order_pay";
	}

	/**
	 * @param orderId
	 * @param model
	 * @return 订单支付
	 */
	@RequestMapping("order/{orderId}/pay")
	public String orderPay(@PathVariable String orderId, Model model) {
		Order order = orderService.getOrderById(orderId);
		order.setStatus("1");
		order.setPayTime(DateUtil.getDateFormat2(new Date()));
		orderService.updateOrder(order);
		return "redirect:/pay/{orderId}";
	}
}


七、springMVC4+Spring4+Hibernate5+MySQL5的完整代码

SpringMVC4+Spring4+Hibernate5+MySQL5     或 https://github.com/honghailiang/SpringMango





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值