Spring与JDBC模板 需要注意的是:
//getJdbcTemplate模板对象是多例的,只在一个方法内有效,当前线程有效,系统会为每一个使用模板对象的方法创建爱一个getJdbcTemplate模板,当
//该方法结束之后便自动销毁,只局限于当前方法 这个类的使用方法是错误的,会报空指针异常
private JdbcTemplate jt;
public StudentDaoImpl() {
jt = this.getJdbcTemplate();
}
@Override
public void insertStudent(Student student) {
String sql = “insert into student(name,age) value(?,?)”;
this.jt.update(sql,student.getName(),student.getAge()) ;
}
Spring的事务管理:
原子性: server层调用DAO层 要成功都成功,不成功都不成功
主要是把DAO层提升到server层
Spring中通常可以通过三种方式通过以下三种方法实现对事务的管理:
事务属于系统级服务,将来作为切面出现,把需要做的操作织入到主业务中,切入点实际上就是server层的方法,只要指定了切入点,又指定了切面(事务),就可以把事务织入到方法层的server上(系统级方法调用AOP(切面),我们需要给织入主业务,织入点就是主业务的server层)把事务织入到server层的方法上 这就是我们实现的思路
Spring事务管理API:接口
必须保证记住,理解记忆
Spring的回滚方式:默认方式:发生运行时异常时发生回滚(严重),发生受查时异常时提交(编译时异常)
运行时异常虚拟机直接挂掉,受查时异常可以挽救通过捕捉异常 受查异常可以由程序员可以设置其回滚方式
Spring事务定义接口:
oracal的隔离级别 isolation 默认为2 级
MySQL默认的隔离级别是 4级
事务定义了七个事务传播行为常量
此配置文件没有采用事务管理,所以购买股票的时候,出现了数据库中账户金额减少了,但是股票数目没有增加的不一致情况。
下面说一下其中一个demo
首先是整个框架结构
实体类:银行账户 Accoount.java
package com.vrv.yinkailong.bean;
//银行账户
public class Accoount {
private Integer aid;
private String aname; //账户名称
private double balance; // 账户余额
public Accoount() {
super();
}
public Accoount(String aname, double balance) {
super();
this.aname = aname;
this.balance = balance;
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override
public String toString() {
return "Accoount [aid=" + aid + ", aname=" + aname + ", balance=" + balance + "]";
}
}
实体类: 股票账户 Stock.java
package com.vrv.yinkailong.bean;
//股票账户
public class Stock {
private Integer sid;
private String sname; //股票名称
private int amount; //股票数量
public Stock() {
super();
}
public Stock(String sname, int amount) {
super();
this.sname = sname;
this.amount = amount;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
@Override
public String toString() {
return "Stock [sid=" + sid + ", sname=" + sname + ", amount=" + amount + "]";
}
}
接着是service层: 定义接口 IBuyStockService.java
package com.vrv.yinkailong.service;
import com.vrv.yinkailong.exception.BuyStockException;
public interface IBuyStockService {
//开账户的方法
void openAccouont(String aname,double money);
void openStock(String sname,int count);
//买股票
void buyStock(String aname,double money,String sname,int count) throws BuyStockException;
}
接口的实现
package com.vrv.yinkailong.service;
import com.vrv.yinkailong.dao.IAccountDao;
import com.vrv.yinkailong.dao.IStockDao;
import com.vrv.yinkailong.exception.BuyStockException;
public class BuyStockServiceImpl implements IBuyStockService {
private IAccountDao ado;
private IStockDao idao;
//必須要實現set方法
public void setAdo(IAccountDao ado) {
this.ado = ado;
}
public void setIdao(IStockDao idao) {
this.idao = idao;
}
@Override
public void openAccouont(String aname, double money) {
ado.insertAccount(aname,money);
}
@Override
public void openStock(String sname, int count) {
idao.insertStock(sname,count);
}
@Override
public void buyStock(String aname, double money, String sname, int count) throws BuyStockException {
Boolean isBuy = true;
ado.updateAccount(aname,money,isBuy);
//人为的制造异常,然后引出事务
/* if (true)
{
throw new BuyStockException("购买股票不成功!!!但是钱被扣了");
}*/
idao.updateStock(sname,count,isBuy);
}
}
增加相应的dao层,因为实现中用到了相应的dao 接口 IAccountDao.java
package com.vrv.yinkailong.dao;
public interface IAccountDao {
void insertAccount(String aname, double money);
void updateAccount(String aname, double money, Boolean isBuy);
}
接口 : IStockDao.java
package com.vrv.yinkailong.dao;
public interface IStockDao {
void insertStock(String sname, int count);
void updateStock(String sname, int count, Boolean isBuy);
}
DAO接口的实现 AccountDaoImpl.java 需要继承 JdbcDaoSupport
package com.vrv.yinkailong.daoImpl;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.vrv.yinkailong.dao.IAccountDao;
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao{
@Override
public void insertAccount(String aname, double money) {
String sql = "insert into account(aname,balance) value(?,?)";
this.getJdbcTemplate().update(sql,aname,money);
}
@Override
public void updateAccount(String aname, double money, Boolean isBuy) {
//默认卖股票
//尤其需要主要sql里面语句增加和修改是在原字段基础上进行的修改,切勿写错了 balance
String sql = "update account set balance=balance+? where aname=?";
if (isBuy) {
//此处为买入股票增加股票数量
sql = "update account set balance=balance-? where aname=?";
}
this.getJdbcTemplate().update(sql,money,aname);
}
}
DAO层的实现 StockDaoImpl.java 同理需要继承JdbcDaoSupport
package com.vrv.yinkailong.daoImpl;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.vrv.yinkailong.dao.IStockDao;
public class StockDaoImpl extends JdbcDaoSupport implements IStockDao {
@Override
public void insertStock(String sname, int count) {
String sql = "insert into stock(sname,amount) value(?,?)";
this.getJdbcTemplate().update(sql,sname,count);
}
@Override
public void updateStock(String sname, int count, Boolean isBuy) {
//默认卖股票
String sql = "update stock set amount=amount-? where sname=?";
if (isBuy) {
//此处为买入股票增加股票数量
sql = "update stock set amount=amount+? where sname=?";
}
this.getJdbcTemplate().update(sql,count,sname);
}
}
下面是主配置文件 applicationContext.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约束必须引入相应的头文件 常用方式context约束-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- -注册数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/curd"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
</bean>
<!-- 指定读取配置文件路径 加上context约束必须引入相应的头文件 常用方式context约束 任意选其中一种方法即可-->
<!-- <context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean> -->
<bean id="IAccountdao" class="com.vrv.yinkailong.daoImpl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="IStockdao" class="com.vrv.yinkailong.daoImpl.StockDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 注册Service -->
<bean id="BuyStockService" class="com.vrv.yinkailong.service.BuyStockServiceImpl">
<property name="ado" ref="IAccountdao"/>
<property name="idao" ref="IStockdao"/>
</bean>
</beans>
使用的jdbc.properties 配置文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/curd
jdbc.user=root
jdbc.password=123456
然后是测试类 MyTest.java
package com.vrv.yinkailong.test;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.vrv.yinkailong.exception.BuyStockException;
import com.vrv.yinkailong.service.IBuyStockService;
public class MyTest {
private IBuyStockService service;
@Before
public void testBefore()
{
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
service = (IBuyStockService) ac.getBean("BuyStockService");
System.out.println("我执行了before()方法");
}
@Test
public void testOpen()
{
service.openAccouont("张三", 10000);
service.openStock("动力节点", 1);
}
//需要处理受查 异常 该方法是虚拟机调用
@Test
public void testBuyAccount() throws BuyStockException
{
service.buyStock("张三", 500, "动力节点", 5);
}
}
此时的执行结果是没问题的
但是我们这里主要学习得是事务处理,很明显在购买股票过程很可能发生异常,需要我们进行处理,这里我们自定义一个异常类 BuyStockException.java
package com.vrv.yinkailong.exception;
//买股票过程可能会发生异常 只要继承exception就会发生授权异常,必须进行处理
public class BuyStockException extends Exception {
public BuyStockException() {
super();
}
public BuyStockException(String message) {
super(message);
}
}
暂时代码只写到这里,如果还需要继续使用事务来处理异常,需要重新定义主配置文件
此配置文件没有采用事务管理,所以购买股票的时候,出现了数据库中账户金额减少了,但是股票数目没有增加的不一致情况。
使用 Spring 的事务代理工厂管理事务:
该方式是,需要为目标类,即 Service 的实现类创建事务代理。事务代理使用的类是TransactionProxyFactoryBean,该类需要初始化如下一些属性:
(1)transactionManager:事务管理器
(2)target:目标对象,即 Service 实现类对象
(3)transactionAttributes:事务属性设置
对于 XML 配置代理方式实现事务管理时,受查异常的回滚方式,程序员可以通过以下方式进行设置:通过“-异常”方式,可使发生指定的异常时事务回滚;通过“+异常”方式,可使发生指定的异常时事务提交。
明天继续补上!与君共勉,今天由于粗心大意,在数据库方面遇到一些问题,所以进度有点慢,明天继续补上!谢谢观看