原生jdbc
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 通过驱动管理类获取数据库链接
connection =
DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
// 定义sql语句?表示占位符
String sql = "select * from user where username = ?";
// 获取预处理statement
preparedStatement = connection.prepareStatement(sql);
// 设置参数,第⼀个参数为sql语句中参数的序号(从1开始),第⼆个参数为设置的参数值
preparedStatement.setString(1, "tom");
// 向数据库发出sql执⾏查询,查询出结果集
resultSet = preparedStatement.executeQuery();
// 遍历查询结果集
while (resultSet.next()) {
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
// 封装User
user.setId(id);
user.setUsername(username);
}
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
实现事务+连接池的jdbc
1. 添加maven依赖
数据库使用的是mysql,阿里巴巴德鲁伊连接池
<!-- 单元测试Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- mysql数据库驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
2. 添加连接池工具类
工具类一般单例饿汉式
public class DruidUtils {
private DruidUtils(){
}
private static DruidDataSource druidDataSource = new DruidDataSource();
static {
druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
druidDataSource.setUrl("jdbc:mysql://localhost:3306/bank");
druidDataSource.setUsername("root");
druidDataSource.setPassword("root");
}
public static DruidDataSource getInstance() {
return druidDataSource;
}
}
3. 获取线程绑定连接工具类
public class ConnectionUtils {
private ConnectionUtils() {
}
private static ConnectionUtils connectionUtils = new ConnectionUtils();
public static ConnectionUtils getInstance() {
return connectionUtils;
}
private ThreadLocal<Connection> threadLocal = new ThreadLocal<>(); // 存储当前线程的连接
/**
* 从当前线程获取连接
*/
public Connection getCurrentThreadConn() throws SQLException {
/**
* 判断当前线程中是否已经绑定连接,如果没有绑定,需要从连接池获取一个连接绑定到当前线程
*/
Connection connection = threadLocal.get();
if(connection == null) {
// 从连接池拿连接并绑定到线程
connection = DruidUtils.getInstance().getConnection();
// 绑定到当前线程
threadLocal.set(connection);
}
return connection;
}
}
4. 获取事务工具类
/**
* 事务管理器类:负责手动事务的开启、提交、回滚
*/
public class TransactionManager {
private TransactionManager(){
}
private static TransactionManager transactionManager = new TransactionManager();
public static TransactionManager getInstance() {
return transactionManager;
}
private ConnectionUtils connectionUtils = ConnectionUtils.getInstance();
// 开启手动事务控制
public void beginTransaction() throws SQLException {
connectionUtils.getCurrentThreadConn().setAutoCommit(false);
}
// 提交事务
public void commit() throws SQLException {
connectionUtils.getCurrentThreadConn().commit();
}
// 回滚事务
public void rollback() throws SQLException {
connectionUtils.getCurrentThreadConn().rollback();
}
}
5. 实现转账功能
/**
* @author
*/
public class TransferServiceImpl implements TransferService {
private AccountDao accountDao = new JdbcAccountDaoImpl();
@Override
public void transfer(String fromCardNo, String toCardNo, int money) throws Exception {
try{
// 开启事务(关闭事务的自动提交)
// connectionUtils.getCurrentThreadConn().setAutoCommit(false);
TransactionManager.getInstance().beginTransaction();
Account from = accountDao.queryAccountByCardNo(fromCardNo);
Account to = accountDao.queryAccountByCardNo(toCardNo);
from.setMoney(from.getMoney()-money);
to.setMoney(to.getMoney()+money);
accountDao.updateAccountByCardNo(to);
// int c = 1/0; //测试是否回滚
accountDao.updateAccountByCardNo(from);
// 提交事务
TransactionManager.getInstance().commit();
}catch (Exception e) {
e.printStackTrace();
// 回滚事务
TransactionManager.getInstance().rollback();
// 抛出异常便于上层servlet捕获
throw e;
}
}
}
6. jdbc实现dao层方法
/**
* @author 应癫
*/
public class JdbcAccountDaoImpl implements AccountDao {
private ConnectionUtils connectionUtils = ConnectionUtils.getInstance(); ;
@Override
public Account queryAccountByCardNo(String cardNo) throws Exception {
//从连接池获取连接
// Connection con = DruidUtils.getInstance().getConnection();
Connection con = connectionUtils.getCurrentThreadConn();
String sql = "select * from account where cardNo=?";
PreparedStatement preparedStatement = con.prepareStatement(sql);
preparedStatement.setString(1,cardNo);
ResultSet resultSet = preparedStatement.executeQuery();
Account account = new Account();
while(resultSet.next()) {
account.setCardNo(resultSet.getString("cardNo"));
account.setName(resultSet.getString("name"));
account.setMoney(resultSet.getInt("money"));
}
resultSet.close();
preparedStatement.close();
//con.close();
return account;
}
@Override
public int updateAccountByCardNo(Account account) throws Exception {
// 从连接池获取连接
// 改造为:从当前线程当中获取绑定的connection连接
//Connection con = DruidUtils.getInstance().getConnection();
Connection con = connectionUtils.getCurrentThreadConn();
String sql = "update account set money=? where cardNo=?";
PreparedStatement preparedStatement = con.prepareStatement(sql);
preparedStatement.setInt(1,account.getMoney());
preparedStatement.setString(2,account.getCardNo());
int i = preparedStatement.executeUpdate();
preparedStatement.close();
//con.close();
return i;
}
}
7. 建表语句
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`name` varchar(255) DEFAULT NULL,
`money` int(255) NOT NULL COMMENT '金额',
`cardNo` varchar(255) NOT NULL,
PRIMARY KEY (`cardNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of account
-- ----------------------------
BEGIN;
INSERT INTO `account` VALUES ('李大雷', 9900, '6029621011000');
INSERT INTO `account` VALUES ('韩梅梅', 10100, '6029621011001');
COMMIT;