目录
1. 事务
1)操作步骤:
开启事务-->提交事务-->回滚事务
2)使用Connection对象管理事务
*开启事务 conn.setAutoCommit(false);
*提交事务 conn.Commit();
*回滚事务 conn.rollback();---放在catch模块,回滚到事务开启之前
如下是实现转账逻辑的代码:
public class JdbcAccount {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement state1 = null;
PreparedStatement state2 = null;
try {
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false);//开启事务
String sql1 = "update user set money = money - ? where id = ?";
String sql2 = "update user set money = money + ? where id = ?";
//获取sql连接对象
state1 = conn.prepareStatement(sql1);
state2 = conn.prepareStatement(sql2);
//占位符?的赋值
state1.setDouble(1,200);
state1.setInt(2,1601);
state2.setDouble(1,200);
state2.setInt(2,1602);
//更新
state1.executeUpdate();
state2.executeUpdate();
conn.commit();//提交事务
} catch (Exception e) {
if(conn != null){
try {
conn.rollback();//回滚事务
} catch (SQLException e1) {
e1.printStackTrace();
}
}
e.printStackTrace();
}finally {
JdbcUtils.release(state1,conn);
JdbcUtils.release(state2,null);
}
}
}
在如上代码中,有如下2种情况:
(1)如果只开启和提交事务,假如执行了try中的一条sql后报错,这时执行的那条语句成功将数据库中的值修改了,然后才报错,第二条sql语句不回修改成功。
(2)但如果在catch中捕获异常后进行事务回滚,这时再与1中同样情况时,数据库中两条sql语句的操作是都没有实现的,就是如果出现异常,这个事务回滚就会回滚到开启事务之前的状态。
2. 数据库连接池
概念:
其实就是一个容器集合,存放数据库连接的容器。
当系统初始化好之后,容器被创建,容器中会申请一些连接对象。
当用户访问数据库时,会先从容器中获取连接对象,在用户获取数据之后会把连接对象归还给容器。
好处:
节约资源,用户访问高效
实现:
1)标准接口 DataSource(javax.sql下的)
获取链接 getConnection();
归还连接:如果是Connection是从数据库连接池获取的,调用Connection.clase();表示归还连接到容器中。
2)一般我们不去实现它,是由数据库厂商提供实现
c3p0:数据库连接池技术
Druid:数据库连接池实现技术 阿里巴巴提供
3. 使用数据库连接池c3p0
使用c3p0步骤:
1.导入2个jar包 (参考https://blog.csdn.net/weixin_44187963/article/details/104864821)
2.定义配置文件:
*名称---c3p0.properties 或者 c3p0-config.xml
*路径---直接将文件放在src中即可
<c3p0-config>
<default-config>
<!-- 必要参数 -->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/TestDB?useSSL=false&serverTimezone=UTC</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 下面不是必要的参数 -->
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
</c3p0-config>
3.创建核心对象 数据库连接池对象 CombopooledDataSource
4.获取连接 getConnection
public class c3p0Dome01 {
public static void main(String[] args) throws SQLException {
//1.创建数据库连接池对象
DataSource ds = new ComboPooledDataSource();
//获取连接对象
Connection conn = ds.getConnection();
//3.打印连接对象
System.out.println(conn);
}
}
4. 了解数据库连接池Druid
使用Druid步骤:
1.导入jar包 druid-1.1.10.jar
2.编写配置文件、加载配置文件
---是properties形式的
---可以叫任意名称放在任意文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/TestDB? useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
jdbc.username=root
password=123456
3.获取数据库连接池对象:通过工厂类获取---DruildDataSourceFactory
4.获取连接 getConnection
public class druidDome01 {
public static void main(String[] args) throws Exception {
//1.导入jar包
//2.定义配置文件
//3.加载配置文件
Properties properties = new Properties();
InputStream input = druidDome01.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(input);
// 4.获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
//5.获取连接
Connection connection = ds.getConnection();
System.out.println(connection);
}
}
与JDBC一样,可以将重复操作封装为工具类:
1.定义一个工具类JdbcUtils
2.工具类需要提供方法:
获取连接方法:通过数据库连接池获取数据
提供静态代码块加载配置文件,初始化连接池对象
释放资源
获取连接池的方法
/**
* druid连接池的工具类
*/
public class JdbcUtils {
private static DataSource ds;
static{
try {
//加载配置文件
Properties ps = new Properties();
ps.load(JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//获取DataSource
ds = com.alibaba.druid.pool.DruidDataSourceFactory.createDataSource(ps);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* 释放资源
*/
public static void close(Statement st,Connection conn){
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(ResultSet res,Statement st, Connection conn){
if(res != null){
try {
res.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 获取连接池方法
*/
public static DataSource getDataSource(){
return ds;
}
}
然后就可以使用工具类简化代码啦
/**
* 使用工具类的操作
*/
public class DruidDome02 {
//完成添加操作,给user表添加一条记录
public static void main(String[] args){
PreparedStatement stmt = null;
Connection conn = null;
try {
//获取连接
conn = JdbcUtils.getConnection();
//定义sql
String sql = "insert into user values(1604,?,?)";
//获取Ststement对象
stmt = conn.prepareStatement(sql);
stmt.setString(1,"易烊千玺");
stmt.setDouble(2,2000);
int count = stmt.executeUpdate();
System.out.println(count);
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.close(stmt,conn);
}
}
}
5.简单了解JDBCTemplate
1)什么是JDBCTemplate?
Spring框架对JDBC的简单封装,提供一个JDBCTemplate对象简化JDBC开发的
2)步骤:
导入jar包
创建JdbcTemplate对象。依赖于数据源DataSource
*JdbcTemplate tmp = new JdbcTemplate(DataSource);
调用JdbcTemplate的方法来完成CRUD操作
- update();执行DML语句,增删改语句
- queryForMap();查询结果集集封装为map
- queryforList();查询结果集封装为list
- query();查询结果,将结果封装为Javabean对象
- queryforObject();查询结果,将结果封装为对象