Spring整合Hibernate的步骤

版权声明:博客知识产权来源命运的信徒,切勿侵权 https://blog.csdn.net/qq_37591637/article/details/85258686

第一步、HIbernate部分

1、导入Hibernate的lib包

2、新建一个Hibernate的cfg文件

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
<hibernate-configuration>
  <session-factory>
 <!--1.配置数据库属性  -->
 <!-- 2.配置映射文件 -->
 <!-- 3.配置方言 、显示mysql数据、生成数据库表的策略等等 -->
 <!--前面两个可以在Spring的配置文件中设置就可以了  -->
 <!-- 配置方言:生成sql语言  换一句话就是说我们的查询语句会自动转化成底层sql语句去查询sql表-->
<property name="hibernate.dialect">org.hibernate.dialect.Dialect</property>
<!-- 在日志中显示sql语句 -->
 <property name="hibernate.show_sql">true</property>
 <property name="hibernate.format_sql">true</property> 
 <!--有了这句话的话,只需要根据持久类的映射文件就可以生成sql表  -->
 <property name="hibernate.hbm2ddl.auto">update</property>
  </session-factory>
</hibernate-configuration>

3、新建两个实体类

Account.java

package cn.spring.hibernate;

public class Account {
private int id; 
private String username;
private int account;
private int stock;
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public String getUsername() {
	return username;
}
public void setUsername(String username) {
	this.username = username;
}
public int getAccount() {
	return account;
}
public void setAccount(int account) {
	this.account = account;
}
public void setStock(int stock) {
	this.stock = stock;
}
public int getStock() {
	return stock;
}
}

BookInfo.java

package cn.spring.hibernate;

public class BookInfo {
private int id;
private String bookname;
private String isbn;
private int price;
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public String getBookname() {
	return bookname;
}
public void setBookname(String bookname) {
	this.bookname = bookname;
}
public String getIsbn() {
	return isbn;
}
public void setIsbn(String isbn) {
	this.isbn = isbn;
}
public void setPrice(int price) {
	this.price = price;
}
public int getPrice() {
	return price;
}

}

配置映射文件Account.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="cn.spring.hibernate.Account" table="Account" catalog="lf">
<id column="id" name="id" type="int">
<generator class="native"></generator>
</id>
<property name="username" column="username" type="string"></property>
<property name="account" column="account" type="int"></property>
<property name="stock" column="stock" type="int"></property>
</class>
</hibernate-mapping>

配置映射文件BookInfo.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="cn.spring.hibernate.Account" table="Account" catalog="lf">
<id column="id" name="id" type="int">
<generator class="native"></generator>
</id>
<property name="username" column="username" type="string"></property>
<property name="account" column="account" type="int"></property>
<property name="stock" column="stock" type="int"></property>
</class>
</hibernate-mapping>

4、在Spring的配置文件里面做如下的任务

4.1 、配置jdbc

4.2、配置hibernate的核心文件

4.3、配置持久类的映射文件

4.4、事务的声明


如下是具体的实现过程,

新建一个applicationContexts.xml

配置jdbc

新建一个db.properties

jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///lf

配置hibernate的核心文件和配置持久类的映射文件

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	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-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!--配置数据库 -->
	<context:property-placeholder location="classpath:db.properties" />
	<bean id="da" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="driverClassName" value="${jdbc.driverClassName}"></property>
		<property name="url" value="${jdbc.url}"></property>
	</bean>
	<!-- 配置hibernate的sessionFactory实例 -->
	<bean id="localSessionFactoryBean"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="da"></property>
		<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
		<property name="mappingLocations" value="classpath:cn/spring/hibernate/*.hbm.xml">
		</property>
	</bean>
</beans>

测试类如下

package cn.com.text;
import java.sql.SQLException;

import javax.sql.DataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
	ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContexts.xml");
	DataSource  da=ioc.getBean(DataSource.class);
	try {
		System.out.println(da.getConnection());
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

}
}

运行程序

结果:不报错,打开数据库,自动生成了两张表

注意:是运行程序自动生成的,不是我事先新建的表;

是    <property name="hibernate.hbm2ddl.auto">update</property>起到作用的


在配置文件里面Spring对事务的声明

1、配置事务管理器

2、配置事务的属性

3、把切点和事务关联起来

疑问?为什么需要用到事务?为什么需要用到切面??

解答:事务的目的就是保证可以让整个过程只有两个结果,全部失败或者全部成功,不存在有的完成了,有的没有完成

为什么用到切面,事务用到哪些包哪些方法,针对哪个类而言的,

配置文件的代码如下

	<!-- 配置Spring的申明式事务 -->
	<!-- 1、事务管理器 -->
	<bean id="hibernateTransactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="localSessionFactoryBean"></property>
	</bean>
	<!-- 配置事务的属性 -->
	<tx:advice transaction-manager="hibernateTransactionManager"
		id="txAdvice">
		<tx:attributes>
			<tx:method name="get*" read-only="true" />
			<tx:method name="*" />
		</tx:attributes>
	</tx:advice>
	<!--把事务的属性和切点关联起来 -->
	<aop:config>
		<aop:pointcut expression="execution(* cn.com.service.*.*(..))"
			id="pointvut" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointvut" />
	</aop:config>

现在就是接口和实现类了

BookShopDao.java

package cn.com.dao;
public interface BookShopDao {
     //根据书号获取书的单价
	public int findBookPriceByIsbn(String isbn);
	//更新书的库存,使得书号对应的库存-1
	public void updateBookStock(String isbn);
	//更新用户的账户余额,使得username的balance-price
	public void updateUserAccount(String username,int price);
}

 BookShopDaoImpl.java

package cn.com.dao;
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 cn.com.dao.exception.BookCountException;
import cn.com.dao.exception.BookStockException;
@Repository(value="bookShopDao")
public class BookShopDaoImpl implements BookShopDao {
	/*
	 * 在这里只能用hibernate,不能跟之前一样用的是底层的sql代码
	 * date:2018/12/27
	 */
	@Autowired
	private SessionFactory sessionFactory;
	// 获取和当前线程绑定的session
	private Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	public int findBookPriceByIsbn(String isbn) {
		String sql = "SELECT b.price FROM BookInfo b WHERE b.isbn = ?";
		System.out.println("sql:"+sql);
		Query query = getSession().createQuery(sql);
		query.setString(0, isbn);
		int bi = (int) query.uniqueResult();
		System.out.println("hahah"+bi);
		return bi;
	}

	public void updateBookStock(String isbn) {
		// 首先看一下库存够不够
		String sql0 = "select stock from BookInfo where isbn = ?";
		int stock = (int) getSession().createQuery(sql0).setString(0, isbn)
				.uniqueResult();
		if (stock == 0) {
			throw new BookStockException("库存不足...");
		}
		// 查询库存
		String sql = "update BookInfo set stock = stock-1 where isbn = ?";
		getSession().createQuery(sql).setString(0, isbn).executeUpdate();
		
	}

	public void updateUserAccount(String username, int price) {
		// 首先看一下余额足不足
		String sql = "select account from Account where username = ?";
		int account = (int) getSession().createQuery(sql)
				.setString(0, username).uniqueResult();
		if (account < price) {
			throw new BookCountException("余额不足...");
		}
		// 扣除金额
		String sqls = "update Account set account = ? where username = ?";
		Query query=getSession().createQuery(sqls);
		query.setInteger(0, account-price);
		query.setString(1,username);
		query.executeUpdate();
	}

}

BookCountException.java

package cn.com.dao.exception;
public class BookCountException extends RuntimeException {

	public BookCountException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public BookCountException(String message, Throwable cause,
			boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public BookCountException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public BookCountException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public BookCountException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}

}

BookStockException.java

package cn.com.dao.exception;
public class BookStockException extends RuntimeException{

	public BookStockException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause,
			boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}

}

BookShopList.java

package cn.com.dao.service;
import java.util.List;
public interface BookShopList {
public void getpurchare(String name,List<String> isbns);
}

BookShopListImpl.java

package cn.com.dao.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository(value="list")
public class BookShopListImpl implements BookShopList {
	@Autowired
	private BookShopService bookShopService;
	public void getpurchare(String name, List<String> isbns) {
		// TODO Auto-generated method stub
		for (String isbn : isbns) {
			bookShopService.purchase(name, isbn);
		}
	}

}

 BookShopService.java

package cn.com.dao.service;

public interface BookShopService {
public void purchase(String username,String isbn);
}

BookShopServiceImpl.java

package cn.com.dao.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import cn.com.dao.BookShopDao;
@Repository(value="book")
public class BookShopServiceImpl implements BookShopService {
	@Autowired
	private BookShopDao bookShopDaoImpl;
/*	@Transactional(isolation=Isolation.READ_COMMITTED)*/
	public void purchase(String username, String isbn) {
		// 1.根据isbn来查询价格和库存
		int price = bookShopDaoImpl.findBookPriceByIsbn(isbn);
		// 2.更新库存
		bookShopDaoImpl.updateBookStock(isbn);
		// 3.扣除账户余额
		bookShopDaoImpl.updateUserAccount(username, price);

	}

}

最终版本的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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	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-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 扫描组件 -->
<context:component-scan base-package="cn.com.dao"></context:component-scan>
	<!--配置数据库 -->
	<context:property-placeholder location="classpath:db.properties" />
	<bean id="da" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="driverClassName" value="${jdbc.driverClassName}"></property>
		<property name="url" value="${jdbc.url}"></property>
	</bean>
	<!-- 配置hibernate的sessionFactory实例 -->
	<bean id="localSessionFactoryBean"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="da"></property>
		<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
		<property name="mappingLocations" value="classpath*:cn/com/spring/hibernate/*.hbm.xml">
		</property>
	</bean>

	<!-- 配置Spring的申明式事务 -->
	<!-- 1、事务管理器 -->
	<bean id="hibernateTransactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="localSessionFactoryBean"></property>
	</bean>
	<!-- 配置事务的属性 -->
	<tx:advice transaction-manager="hibernateTransactionManager"
		id="txAdvice">
		<tx:attributes>
			<tx:method name="get*" read-only="true" />
			<tx:method name="purchase" propagation="REQUIRES_NEW"/>
			<tx:method name="*" />
		</tx:attributes>
	</tx:advice>
	<!-- 把事务的属性和切点关联起来 -->
	<aop:config>
		<aop:pointcut expression="execution(* cn.com.dao.service.*.*(..))"
			id="pointcut" />
			
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
	</aop:config>
	<!--使得注解生效 -->
	<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
	</beans> 

测试类

package cn.com.dao.com;
import java.util.Arrays;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.com.dao.service.BookShopList;
public class Test {
public static void main(String[] args) {
	      ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml");
	    /* 一个人买一本书
	     *  BookShopService bs=(BookShopService) ioc.getBean("book");
          bs.purchase("aa", "0102");
	     * */
	     
	      //一个人买多本书
	      BookShopList bp=(BookShopList) ioc.getBean("list");
	      bp.getpurchare("bb", Arrays.asList(new String[]{"0101","0102"}));
}
}

测试无误


注意两个点

1、<!-- 配置事务的属性 -->
    <tx:advice transaction-manager="hibernateTransactionManager"
        id="txAdvice">
        <tx:attributes>
            <tx:method name="get*" read-only="true" />
            <tx:method name="purchase" propagation="REQUIRES_NEW"/>
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

和@Transactional(isolation=Isolation.READ_COMMITTED)

一个是基于xml的配置,另一个是注解的方式配置事务的属性

2、在类BookShopListImpl里面的方法名不可以是getpurchare,不然会报错,因为在配置文件里面有一个

 <tx:method name="purchase" propagation="REQUIRES_NEW"/>

猜你喜欢

转载自blog.csdn.net/qq_37591637/article/details/85258686
今日推荐