一、事务
2.一致性:事务执行后,数据库状态与其它业务规则保持一致。
3.隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
4.持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中。即使提交事务后数据库马上崩溃,在数据库重启后,也必须能保证通过某种机制恢复数据。
1.2JDBC中操作事务
在JDBC中处理事务都是通过Connection对象完成的,同一事务中的所有操作,都在使用同一个Connection对象。
setAutoCommit(boolean);设置是否自动提交事务,如果为true表示自动提交(默认值就是true),也就是每条执行的sql语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了。con.setAutoCommit(false);语句表示开启事务。
con.commit();提交并结束事务。
con.rollback();回滚事务。
二、MVC模型简单介绍
MVC是模型(model)、视图(view)、控制器(controller)的缩写。即MVC分为模型层、视图层、控制层。
1.模型层:分为两个部分:1.数据库中具体表的映射类。2.对数据库映射类操作(增、删、改、查)方法的封装类。
2.业务层:一般还会有一个业务层,业务层调用模型层中基本操作方法(增、删、改、查)实现更复杂的操作(即业务)。
3.控制层:对业务层方法的调用,在视图层与控制层之间起到了一个桥梁的作用。
4.视图层:直接与用户交互,用于接受用户的数据和用户进行数据交换。
三、通过一个简单的MVC模型项目了解JDBC和事务(没用到连接池)
项目说明
功能:通过事务实现用户之间的转账功能。
具体操作流程:分别输入转账人、收款人的用户名和具体转账金额,完成用户之间的转账。
2.Account_info类 //数据库中用户信息的映射类。
3.Trans_info类 //数据库中用户交易记录的映射类。
4.AccountDao类 //对Account_info基本操作方法(增删改查)的封装类。
5.TransDao类 //对Trans_info基本操作方法(增删改查)的封装类。
6.TransService类 //实现转账功能。
7.Trans_action类 //对TransService类的调用,和控制。
8.View类 //用于接受用户数据。
1.1事务的四大特性(ACID)
1.原子性:事务中的所有操作要么全部执行成功,要么执行全部失败。2.一致性:事务执行后,数据库状态与其它业务规则保持一致。
3.隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
4.持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中。即使提交事务后数据库马上崩溃,在数据库重启后,也必须能保证通过某种机制恢复数据。
1.2JDBC中操作事务
在JDBC中处理事务都是通过Connection对象完成的,同一事务中的所有操作,都在使用同一个Connection对象。
setAutoCommit(boolean);设置是否自动提交事务,如果为true表示自动提交(默认值就是true),也就是每条执行的sql语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了。con.setAutoCommit(false);语句表示开启事务。
con.commit();提交并结束事务。
con.rollback();回滚事务。
二、MVC模型简单介绍
MVC是模型(model)、视图(view)、控制器(controller)的缩写。即MVC分为模型层、视图层、控制层。
1.模型层:分为两个部分:1.数据库中具体表的映射类。2.对数据库映射类操作(增、删、改、查)方法的封装类。
2.业务层:一般还会有一个业务层,业务层调用模型层中基本操作方法(增、删、改、查)实现更复杂的操作(即业务)。
3.控制层:对业务层方法的调用,在视图层与控制层之间起到了一个桥梁的作用。
4.视图层:直接与用户交互,用于接受用户的数据和用户进行数据交换。
三、通过一个简单的MVC模型项目了解JDBC和事务(没用到连接池)
项目说明
功能:通过事务实现用户之间的转账功能。
具体操作流程:分别输入转账人、收款人的用户名和具体转账金额,完成用户之间的转账。
3.1 数据库中表单和账号信息准备
account_info 表单:
trans_info 表单:
account_info 中插入的两条账号记录用于转账
3.2 准备的类
1.DBUtil类 //取得数据库的连接。2.Account_info类 //数据库中用户信息的映射类。
3.Trans_info类 //数据库中用户交易记录的映射类。
4.AccountDao类 //对Account_info基本操作方法(增删改查)的封装类。
5.TransDao类 //对Trans_info基本操作方法(增删改查)的封装类。
6.TransService类 //实现转账功能。
7.Trans_action类 //对TransService类的调用,和控制。
8.View类 //用于接受用户数据。
说明:2345属于模型层,6属于业务层、7属于控制层、8属于视图层。
DBUtil类:
package transaction;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
static Connection con=null;
static {
String url="jdbc:mysql://localhost:3306/demo1?useSSL=false&useUnicode=ture&characterEncoding=utf8";//连接数据库的url
String user="root";//用户名
String password="123";//密码
try {
con=DriverManager.getConnection(url,user,password);//获取与数据库连接的对象
}catch(SQLException e) {
e.printStackTrace();
}
}
//获取连接对象的方法
public static Connection getConnection() {
return con;
}
}
Account_info类:
package transaction;
import java.util.Date;
public class Account_info {
//数据库account_info表中字段的定义
private Integer id;
private String name;
private double balance;
private Date date;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
Trans_info类:
package transaction;
public class Trans_info {
//对数据库中trans_info表字段的定义
private Integer t_id;
private Integer source_id;
private String source_name;
private Integer destination_id;
private String destination_name;
private double money;
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public Integer getT_id() {
return t_id;
}
public void setT_id(Integer t_id) {
this.t_id = t_id;
}
public Integer getSource_id() {
return source_id;
}
public void setSource_id(Integer source_id) {
this.source_id = source_id;
}
public String getSource_name() {
return source_name;
}
public void setSource_name(String source_name) {
this.source_name = source_name;
}
public Integer getDestination_id() {
return destination_id;
}
public void setDestination_id(Integer destination_id) {
this.destination_id = destination_id;
}
public String getDestination_name() {
return destination_name;
}
public void setDestination_name(String destination_name) {
this.destination_name = destination_name;
}
public String toString() {
String st;
st=t_id.toString()+" "+source_id.toString()+" "+source_name.toString()+" "+destination_id.toString()
+" "+destination_name.toString();
return st;
}
}
AccountDao类:
package transaction;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class AccountDao {
//在数据库account_info表中添加账号的方法
public void Account_add(Account_info account) throws SQLException {
Connection con=DBUtil.getConnection();//获取连接对象
String sql="insert into account_info value(?,?,?,?;)";//编写预处理sql语句
PreparedStatement pstmt=con.prepareStatement(sql);//创造PreparedStatement对象
//定义sql语句中不完整的部分
pstmt.setInt(1, account.getId());
pstmt.setNString(2, account.getName());
pstmt.setDate(3, new Date(account.getDate().getTime()));
pstmt.setDouble(4, account.getBalance());
int isexe=pstmt.executeUpdate();//执行更改操作
}
//在数据库account_info表中删除账号的方法
public void Account_delete(Account_info account) throws SQLException {
Connection con=DBUtil.getConnection();
String sql="delete from account_info where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, account.getId());
int isexe=pstmt.executeUpdate();
}
//更新指定id用户账号的账户金额的方法
public void Account_update(Account_info account) throws SQLException {
Connection con=DBUtil.getConnection();
String sql="update account_info set balance=? where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, (int) account.getBalance());
pstmt.setInt(2, account.getId());
int isexe=pstmt.executeUpdate();
}
//查询所有账号信息
public List<Account_info> Account_query() throws SQLException {
List<Account_info> list=new ArrayList<Account_info>();//创建用于接收Account_info对象的列表对象
Connection con=DBUtil.getConnection();
String sql="select * from account_info";
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(sql);//执行查询操作获得结果集对象
//遍历结果集,将结果集赋值给对应Account_info实例
while(rs.next()) {
Account_info ac=new Account_info();//创建用于接收指定结果集的Account_info对象
//获取结果集中的数据给Account_info对象赋值
ac.setId(rs.getInt("id"));
ac.setName(rs.getString("a_name"));
ac.setDate(rs.getDate("a_date"));
ac.setBalance(rs.getInt("balance"));
list.add(ac);
}
return list;
}
//根据id查询指定用户账号方法
public Account_info Account_query(int id) throws SQLException{
Account_info ac=new Account_info();//创建用于接收查询结果的Account_info对象
Connection con=DBUtil.getConnection();
String sql="select * from account_info where id=?";
PreparedStatement stmt=con.prepareStatement(sql);
stmt.setInt(1, id);
ResultSet rs=stmt.executeQuery();
rs.next();//这里要注意,如果要对结果集进行操作就一定要实行这一步
ac.setId(rs.getInt("id"));
ac.setName(rs.getString("a_name"));
ac.setDate(rs.getDate("a_date"));
ac.setBalance(rs.getInt("balance"));
return ac;}}
TransDao类:
package transaction;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class TransDao {
public void Trans_add(Trans_info trans) throws SQLException {
Connection con=DBUtil.getConnection();
String sql="insert into trans_info(source_id,source_name,destination_id,destination_name,money) value(?,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, trans.getSource_id());
pstmt.setString(2, trans.getSource_name());
pstmt.setInt(3, trans.getDestination_id());
pstmt.setString(4, trans.getDestination_name());
pstmt.setDouble(5, trans.getMoney());
int isexe=pstmt.executeUpdate();
}
public void Trans_delete(Trans_info trans) throws SQLException {
Connection con=DBUtil.getConnection();
String sql="delete from trans_info where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, trans.getT_id());
int isexe=pstmt.executeUpdate();
}
public void Trans_update(Trans_info trans) throws SQLException {
Connection con=DBUtil.getConnection();
String sql="update trans_info set source_id=?,source_name=?,destination_id=?,destination_name=?,money=? where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, trans.getSource_id());
pstmt.setString(2, trans.getSource_name());
pstmt.setInt(3, trans.getDestination_id());
pstmt.setString(4, trans.getDestination_name());
pstmt.setDouble(5, trans.getMoney());
pstmt.setInt(6, trans.getT_id());
int isexe=pstmt.executeUpdate();
}
public List<Trans_info> Trans_query() throws SQLException {
List<Trans_info> list=new ArrayList<Trans_info>();
Connection con=DBUtil.getConnection();
String sql="select * from trans_info";
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()) {
Trans_info trans=new Trans_info();
trans.setT_id(rs.getInt("t_id"));
trans.setSource_id(rs.getInt("source_id"));
trans.setSource_name(rs.getString("source_na,e"));
trans.setDestination_id(rs.getInt("destination_id"));
trans.setDestination_name(rs.getString("destination_name"));
list.add(trans);
}
return list;
}
public Trans_info Trans_query(int id) throws SQLException {
Trans_info trans=new Trans_info();
Connection con=DBUtil.getConnection();
String sql="select * from trans_info where id=?";
PreparedStatement stmt=con.prepareStatement(sql);
stmt.setInt(1, id);
ResultSet rs=stmt.executeQuery();
rs.next();
trans.setT_id(rs.getInt("t_id"));
trans.setSource_id(rs.getInt("source_id"));
trans.setSource_name(rs.getString("source_na,e"));
trans.setDestination_id(rs.getInt("destination_id"));
trans.setDestination_name(rs.getString("destination_name"));
trans.setMoney(rs.getDouble("money"));
return trans;
}
}
TransService类 :
package service;
import java.sql.Connection;
import java.sql.SQLException;
import transaction.AccountDao;
import transaction.Account_info;
import transaction.DBUtil;
import transaction.TransDao;
import transaction.Trans_info;
public class TransService {
//业务层方法输入参数为:转账人(from)、收款方(to)、转账金额(money)
public String transaction(Account_info from ,Account_info to, double money) throws SQLException {
Connection con=DBUtil.getConnection();
con.setAutoCommit(false);//关闭每次操作自动提交,即开始事务操作
try {
AccountDao a_dao=new AccountDao();//创建AccountDao对象用于对指定账户对象进行基本操作
TransDao t_dao=new TransDao();//创建TransDao对象用于对指定转账信息对象进行基本操作
//对转账人账户金额进行修改
from.setBalance(from.getBalance()-money);
a_dao.Account_update(from);
//对收款方账户金额进行修改
to.setBalance(to.getBalance()+money);
a_dao.Account_update(to);
Trans_info trans=new Trans_info();//创建用于接收转账信息的Trans_info对象
//对trans对象进行赋值
trans.setSource_id(from.getId());
trans.setSource_name(from.getName());
trans.setDestination_id(to.getId());
trans.setDestination_name(to.getName());
trans.setMoney(money);
t_dao.Trans_add(trans);//在数据库中添加转账信息
con.commit();//提交事务
return "成功";//如果事务进行成功返回一个"成功"字符串
}catch(Exception e) {
con.rollback();//如果事务中存在异常,回滚这次事务执行的操作,即取消这次事务中的任何操作,并返回一个"失败"字符串
e.printStackTrace();
return "失败";
}
finally{
con.close();
}
}
}
Trans_action类 :
package action;
import java.sql.SQLException;
import service.TransService;
import transaction.AccountDao;
import transaction.Account_info;
public class Trans_action {
//控制层方法输入参数为:转账人的id(f_id)、收款人的id(t_id)、转账金额(money)
public String trans_action(int f_id,int t_id ,double money) throws SQLException {
AccountDao a_dao=new AccountDao();//创建一个Account对象用于对查找Account对象
Account_info from=a_dao.Account_query(1);
Account_info to=a_dao.Account_query(2);
//调用业务层的transcation(from,to,money)方法实现业务
TransService ts=new TransService();
String re=ts.transaction(from, to, money);
return re;
}
}
View类:
package test;
import java.sql.SQLException;
import java.util.Scanner;
import action.Trans_action;
public class view {
public static void main(String[] args) throws SQLException {
Scanner scan=new Scanner(System.in);
System.out.println("请输入转账人的id:");
int f_id=scan.nextInt();
System.out.println("请输入收款方的id:");
int t_id=scan.nextInt();
System.out.println("亲输入转账金额:");
double money= scan.nextDouble();
Trans_action action=new Trans_action();
String rs=action.trans_action(f_id, t_id, money);
System.out.println("您的转账结果:"+rs);
}
}
3.4 效果展示
eclipse 控制台中输入数据:
MySQL中用户账号金额的变化:
MySQL中的转账信息(看最新一条):