例:我的账户 -500,小红的账户 +500:要么都成功,要么都失败
演示数据库连接
1.数据库连接池
1.1使用驱动获取连接的弊端
1.2如何配置连接池
1.3使用连接池实现数据库操作
2.JdbcTemplate
2.1传统方式进行数据库操作
2.2使用JdbcTemplate进行数据库操作:增删改查
3.集成声明式事务
3.1实现步骤
3.1.1引入jar包
3.1.2配置数据库连接池
3.1.3配置配置事务管理器
3.1.4开始事务注解扫描
3.2测试事务
创建表student
,添加表中信息及数据信息,效果如图所示:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Map.Entry;
import javax.naming.spi.DirStateFactory.Result;
import javax.swing.Spring;
import javax.swing.plaf.synth.SynthGraphicsUtils;
import javax.xml.crypto.Data;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
/**
* 演示数据库链接
* @author Katrina
*
*/
public class Demo {
@Test
public void test1() throws Exception {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取链接
String url = "jdbc:mysql://localhost:3306/demo?charactorEncoding=UTF-8";
String user = "root";
String password = "1234"; //"" 和 " "不同!
Connection connection = DriverManager.getConnection(url, user, password);
//3.创建statement并执行sql
Statement statement = connection.createStatement();
String sql = "INSERT INTO student (name) VALUES ('tom')";
int row = statement.executeUpdate(sql);
//4.处理结果集
System.out.println("执行sql影响行数是:" + row);
//5.关闭资源
statement.close();
connection.close();
}
@Test
public void test2() throws Exception {
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取链接 //高版本驱动,必须添加的参数serverTimezone=Asia/Shanghai&useSSL=false
String url = "jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&useSSL=false";
String user = "root";
String password = "1234"; //"" 和 " "不同!
Connection connection = DriverManager.getConnection(url, user, password);
//3.创建statement并执行sql
Statement statement = connection.createStatement();
String sql = "INSERT INTO student (name) VALUES ('tom')";
int row = statement.executeUpdate(sql);
//4.处理结果集
System.out.println("执行sql影响行数是:" + row);
//5.关闭资源
statement.close();
connection.close();
}
@Test
public void test3() throws Exception {
//数据库连接池
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&useSSL=false");
druidDataSource.setUsername("root");
druidDataSource.setPassword("1234");
//获取链接
DruidPooledConnection connection = druidDataSource.getConnection();
//创建statement、执行sql
Statement statement = connection.createStatement();
String sql = "INSERT INTO student (name) VALUES ('tom1')";
int row = statement.executeUpdate(sql);
//处理结果集
System.out.println("执行sql影响行数是:" + row);
//关闭资源
statement.close();
connection.close();
druidDataSource.close(); //真正关闭资源
}
@Test
public void test4() throws Exception {
//1.创建容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
//2.获取类并执行操作
DruidDataSource dataSource = (DruidDataSource) context.getBean("dataSource");
DruidPooledConnection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
String sql = "INSERT INTO student (name) VALUES ('tom22')";
int row = statement.executeUpdate(sql);
System.out.println("sql执行影响的行数:" + row);
//3.关闭容器
statement.close();
connection.close();
dataSource.close();
context.close();
}
@Test
public void test5() {
//1.创建容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
//2.获取类并操作
JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
/*
* jdbcTemplate的增删改查
* 查询:query*
* 修改:
* update*:返回值是int,对于数据的操作语句建议使用update
* execute:返回值是void,对于表结构等操作语句建议使用execute
*/
// jdbcTemplate.queryForList(sql); //查询列表
// jdbcTemplate.queryForMap(sql); //查询单条数据
// jdbcTemplate.queryForObject(); //查询单挑数据,必须查询出数据,没有回报错
// jdbcTemplate.queryForRowSet(sql); //对应ResultSet存在
String sql = "SELECT * FROM student WHERE id = 1";
// 泛型
Student student = jdbcTemplate.queryForObject(sql, new RowMapper<Student>() { //映射:匿名内部类,即实现接口
@Override
public Student mapRow(ResultSet resultSet, int arg1) throws SQLException {
Student student = new Student();
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("name"));
return student;
}
});
System.out.println("学生的id是:" + student.getId() + ",学生的名字是:" + student.getName());
// String sql="SELECT * FROM student WHERE id=?";
// Map data = jdbcTemplate.queryForMap(sql, 1);
//不建议使用select *,效率比较差
// String sql = "SELECT * FROM student WHERE id=1";
// Map data = jdbcTemplate.queryForMap(sql);
// for (Entry entry : data.entrySet()) {
// System.out.println("key为:" + entry.getKey() + ",value值为:" + entry.getValue());
// }
// String sql = "INSERT INTO student (name) VALUES ('jack')";
// int row = jdbcTemplate.update(sql);
// System.out.println("执行sql影响的行数是:" + row);
//3.关闭容器
context.close();
}
@Test
public void test6() {
//1.加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//2.获取链接
String url = "jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&useSSL=false";
String user = "root";
String password = "1234"; //"" 和 " "不同!
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//3.创建statement并执行sql
Statement statement = null;
try {
statement = connection.createStatement();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String sql = "INSERT INTO student (name) VALUES ('tom')";
int row = 0;
try {
row = statement.executeUpdate(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//4.处理结果集
System.out.println("执行sql影响行数是:" + row);
//5.关闭资源
try {
statement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试test2,效果如图所示:
测试test3,效果如图所示:
测试test4,效果如图所示:
测试test5,效果如图所示:
测试test6,效果如图所示:
/**
* student实体类,用于映射数据库student表
* @author Katrina
*
*/
public class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* 使用dao,来模拟service
* @author Katrina
*
*/
//注解到类上,对类中所有的方法都进行事务管理
@Transactional(readOnly = true) //只读
@Repository
public class StudentDao {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 保存学生
*/
@Transactional(readOnly = false) //其他功能仍有..
public void saveStudent() {
String sql1 = "INSERT INTO student (NAME) VALUES ('james')";
jdbcTemplate.update(sql1);
// Integer.parseInt("xxxxxx");
String sql2 = "INSERT INTO student (NAME) VALUES ('tom')";
jdbcTemplate.update(sql2);
}
}
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 事务测试类
* @author Katrina
*
*/
public class StudentDaoTest {
@Test
public void test() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
StudentDao studentDao = context.getBean(StudentDao.class);
studentDao.saveStudent();
context.close();
}
}
<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"
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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver">property>
<property name="url" value="jdbc:mysql://localhost:3306/demo?charactorEncoding=UTF-8">property>
<property name="username" value="root">property>
<property name="password" value="1234">property>
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource">property>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<context:component-scan base-package="demo">context:component-scan>
<tx:annotation-driven transaction-manager="transactionManager"/>
beans>