第一步、HIbernate部分
1、导入Hibernate的lib包
2、新建一个Hibernate的cfg文件
hibernate.cfg.xml
org.hibernate.dialect.Dialect
true
true
update
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
配置映射文件BookInfo.hbm.xml
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的核心文件和配置持久类的映射文件
测试类如下
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();
}
}
}
运行程序
结果:不报错,打开数据库,自动生成了两张表
注意:是运行程序自动生成的,不是我事先新建的表;
是
在配置文件里面Spring对事务的声明
1、配置事务管理器
2、配置事务的属性
3、把切点和事务关联起来
疑问?为什么需要用到事务?为什么需要用到切面??
解答:事务的目的就是保证可以让整个过程只有两个结果,全部失败或者全部成功,不存在有的完成了,有的没有完成
为什么用到切面,事务用到哪些包哪些方法,针对哪个类而言的,
配置文件的代码如下
现在就是接口和实现类了
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 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 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
测试类
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、
和@Transactional(isolation=Isolation.READ_COMMITTED)
一个是基于xml的配置,另一个是注解的方式配置事务的属性
2、在类BookShopListImpl里面的方法名不可以是getpurchare,不然会报错,因为在配置文件里面有一个