一、数据库
1.对数据库的操作
1)创建一个库
create database 库名
create database 库名 character set 编码
2)查看当前正在操作的库
select database()
3)删除一个库
drop database 库名
4)使用库
use 库名
2.对数据库表的操作
1)创建表
create table 表名(
字段名 类型(长度) [约束],
字段名 类型(长度) [约束],
字段名 类型(长度) [约束]
);
字段类型
2).查看数据库表
show tables; //查看数据库中存在的表
desc 表名 //查看表的结构
3)删除一张表
drop table 表名
4)修改表
<1> 添加一列
alter table 表名 add 字段名 类型(长度) [约束]
<2>修改列的类型(长度、约束)
alter table 表名 modify 要修改的字段名 类型(长度) [约束]
<3>修改列的列名
alter table 表名 change 旧列名 新列名 类型(长度) [约束]
<4>删除表的列
alter table 表名 drop 列名
<5>修改表名
rename table 表名 to 新表名
<6>修改表的字符集
alter table 表名 character set 编码
3.对数据库表记录进行操作(修改)
1)插入记录
insert into 表名(列名1,列名2,列名3……) values(值1,值2,值3……)
insert into 表名 values(值1,值2,值3……)
注:插入数据中文乱码问题解决办法
set names gbk; //或者utf8
2).修改表记录
<1> 不带条件的,它会将该列的所有记录都更改
update 表名 set 字段名=值, 字段名=值, 字段名=值……
<2>带条件的
update 表名 set字段名=值, 字段名=值, 字段名=值…… where 条件
3)删除表记录
<1>带条件的
delete from 表名 where 条件
<2>不带条件的
delete from 表名;
面试题:说说delete与truncate的区别?
delete删除的时候是一条一条的删除记录,它配合事务,可以将删除的数据找回。这样主键如果是自增的话,主键值不会和之前的重复
truncate删除,它是将整个表摧毁,然后再创建一张一模一样的表。它删除的数据无法找回。这样主键如果是自增的话,主键值会从头开始
4).查询操作
select [distinct] *| 列名,列名 from 表名 [where条件]
条件查询
5)排序
升序:order by [字段] ASC
降序:order by [字段] DESC
6)聚合函数
常见的聚合函数有:sum()求和,avg()求平均,max()最大值,min()最小值,count()计数
7)分组
group by
8)查询总结
查询语句保留字通常写法顺序如下:
select 要查询的字段
from 要查询的表
where 条件
group by 分组
having 分组后带有条件只能用having
order by 它必须放在最后面
二、JDBC
1.什么是JDBC
JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。
2.JDBC原理
早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!
JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。
当然还有第三方公司专门为某一数据库提供驱动,这样的驱动往往不是开源免费的!
3.JDBC核心类(接口)介绍
JDBC中的核心类有:DriverManager、Connection、Statement,和ResultSet!
<1>DriverManger(驱动管理器)的作用有两个:
注册驱动:这可以让JDBC知道要使用的是哪个驱动;
获取Connection:如果可以获取到Connection,那么说明已经与数据库连接上了。
<2>Connection对象表示连接,与数据库的通讯都是通过这个对象展开的:
Connection最为重要的一个方法就是用来获取Statement对象;
<3>Statement是用来向数据库发送SQL语句的,这样数据库就会执行发送过来的SQL语句
void executeUpdate(String sql):执行更新操作(insert、update、delete等)
<4>ResultSet executeQuery(String sql):执行查询操作,数据库在执行查询后会把查询结果,查询结果就是ResultSet
ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生。结果集是一个二维的表格,有行有列。操作结果集要学习移动ResultSet内部的“行光标”,以及获取当前行上的每一列上的数据
boolean next():使“行光标”移动到下一行,并返回移动后的行是否存在;
XXX getXXX(int col):获取当前行指定列上的值,参数就是列数,列数从1开始,而不是0
4.jdbc开发步骤
<1>注册驱动
注册驱动就只有一句话:Class.forName(“com.mysql.jdbc.Driver”)
<2>获得连接
获取连接需要两步,一是使用DriverManager来注册驱动,二是使用DriverManager来获取Connection对象。获取连接的也只有一句代码:DriverManager.getConnection(url,username,password),其中username和password是登录数据库的用户名和密码,url查对复杂一点,它是用来找到要连接数据库“网址”,就好比你要浏览器中查找百度时,也需要提供一个url。下面是mysql的url:jdbc:mysql://localhost:3306/mydb1 ,JDBC规定url的格式由三部分组成,每个部分中间使用冒号分隔。
->第一部分是jdbc,这是固定的;
->第二部分是数据库名称,那么连接mysql数据库,第二部分当然是mysql了;
->第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称(mydb1)组成。
还可以在url中提供参数:jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=UTF8
useUnicode参数指定这个连接数据库的过程中,使用的字节集是Unicode字节集;
characherEncoding参数指定穿上连接数据库的过程中,使用的字节集编码为UTF-8编码。请注意,mysql中指定UTF-8编码是给出的是UTF8,而不是UTF-8。要小心了!
获取连接的语句:
Connection con = DriverManager.getConnection(“jdbc:mysql://localhost:3306/web08”,”root”,”root”);
<3>获得语句执行者(获取Statement)
Statement stmt = con.createStatement();
Statement是用来向数据库发送要执行的SQL语句的!
<4>执行sql语句
String sql = “select * from user”;
ResultSet rs = stmt.executeQuery(sql);
请注意,执行查询使用的不是executeUpdate()方法,而是executeQuery()方法。executeQuery()方法返回的是ResultSet,ResultSet封装了查询结果,我们称之为结果集。
<5>处理结果
ResultSet就是一张二维的表格,它内部有一个“行光标”,光标默认的位置在“第一行上方”,我们可以调用rs对象的next()方法把“行光标”向下移动一行,当第一次调用next()方法时,“行光标”就到了第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法来获取指定列的数据了:
rs.next();//光标移动到第一行
rs.getInt(1);//获取第一行第一列的数据
当你使用rs.getInt(1)方法时,你必须可以肯定第1列的数据类型就是int类型,如果你不能肯定,那么最好使用rs.getObject(1)。在ResultSet类中提供了一系列的getXXX()方法,比较常用的方法有:
Object getObject(int col)
String getString(int col)
int getInt(int col)
double getDouble(int col)
<6>释放资源
与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。
rs.close();
stmt.close();
con.close();
根据以上开发步骤设计普通代码如下:
public void login(String username, String password) throws ClassNotFoundException, SQLException {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web08", "root", "root");
// 3.创建执行sql语句的对象
Statement stmt = conn.createStatement();
// 4.书写一个sql语句
String sql = "select * from tbl_user where " + "uname='" + username + "' and upassword='" + password + "'";
// 5.执行sql语句
ResultSet rs = stmt.executeQuery(sql);
// 6.对结果集进行处理
if (rs.next()) {
System.out.println("恭喜您," + username + ",登录成功!");
System.out.println(sql);
} else {
System.out.println("账号或密码错误!");
}
if (rs != null)
rs.close();
if (stmt != null)
stmt.close();
if (conn != null)
conn.close();
}
但是以上代码存在SQL攻击问题,因为username是拼接到sql语句中,因此如果被恶意添加一些sql保留字则会存在安全隐患
防止sql攻击有以下手段:
<1>过滤用户输入的数据中是否包含非法字符;
<2>分步校验!先使用用户名来查询用户,如果查找到了,再比较密码;
<3>使用PreparedStatement
->使用Connection的prepareStatement(String sql):即创建它时就让它与一条SQL模板绑定;
->调用PreparedStatement的setXXX()系列方法为问号设置值
->调用executeUpdate()或executeQuery()方法,但要注意,调用没有参数的方法;
改进后的代码如下:
public void login1(String username, String password) throws ClassNotFoundException, SQLException {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web08", "root", "root");
// 3.编写sql语句
String sql = "select * from tbl_user where uname=? and upassword=?";
// 4.创建预处理对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 5.设置参数(给占位符)
pstmt.setString(1, username);
pstmt.setString(2, password);
// 6.执行查询操作
ResultSet rs = pstmt.executeQuery();
// 7.对结果集进行处理
if (rs.next()) {
System.out.println("恭喜您," + username + ",登录成功!");
System.out.println(sql);
} else {
System.out.println("账号或密码错误!");
}
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
}
5.外键
添加外键声明约束:alter table 从表 add constraint 外键名称 foreign key 从表字段名 references 主表主键
删除外键声明约束:alter table 从表 drop foreign key 外键名称
6.表与表之间的关系(建表原则)
1)一对一:
外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique
外键是主键:主表的主键是从表的外键,形成主外键关系
2)一对多:在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
3)多对多:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键(就是将一个多对多拆分成两个一对多)
7.查询操作
1)多表查询
<1>交叉连接查询
语法:select * from A,B
<2>内连接查询(使用关键字inner join ,其中inner可以省略)
隐式内连接:select * from A,B where 条件
显示内连接:select * from A inner join B on 条件
<3>外连接查询(left/right out join)
左外连接:select * from A left outer join B on 条件
右外连接:select * from A right outer join B on 条件
2)子查询
一条select语句结果作为另一条select语法的一部分(查询条件、查询结果、表等)
8.工具类
public class JDBCUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
/**
* 静态代码块加载配置文件信息
*/
static {
try {
// 1.通过当前类获取类加载器
ClassLoader classLoader = JDBCUtils_V3.class.getClassLoader();
// 2.通过类加载器的方法获得一个输入流
InputStream is = classLoader.getResourceAsStream("db.properties");
// 3.创建一个properties对象
Properties props = new Properties();
// 4.加载输入流
props.load(is);
// 5.获取相关参数的值
driver = props.getProperty("driver");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取连接方法
*
* @return
*/
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
使用工具类测试代码,如下:
/**
* 根据id查询用户信息
*/
@Test
public void testFindUserById() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 1.获取连接
conn = JDBCUtils_V1.getConnection();
// 2.编写sql语句
String sql = "select * from tbl_user where uid=?";
// 3.获取执行sql语句对象
pstmt = conn.prepareStatement(sql);
// 4.设置参数
pstmt.setInt(1, 2);
// 5.执行查询操作
rs = pstmt.executeQuery();
// 6.处理结果集
while (rs.next()) {
System.out.println(rs.getString(2) + "----" + rs.getString("upassword"));
}
// 释放资源放在此处行么?【不行滴!】
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 7.释放资源
JDBCUtils.release(conn, pstmt, rs);
}
}
9.连接池
实际开发种,获取连接和释放资源是非常消耗系统资源的两个过程,为了解决此类问题,通常采用连接池的技术,来共享Connection
1)C3P0连接池
<1>配置文件:c3p0-config.xml
命名配置:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 命名的配置:ComboPooledDataSource调用带名称的配置的话使用该name -->
<named-config name="mysql">
<!-- 连接数据库的4项基本参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF8</property>
<property name="user">root</property>
<property name="password">123456</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 -->
<property name="acquireIncrement" value="2"/>5</property>
<!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3-->
<property name="initialPoolSize">20</property>
<!--连接池中保留的最大连接数。默认值: 15 -->
<property name="maxPoolSize">40</property>
<!-- 连接池中保留的最小连接数,默认为:3-->
<property name="minPoolSize">10</property>
<!--c3p0全局的PreparedStatements缓存的大小。如果maxStatements与maxStatementsPerConnection均为0,则缓存不生效,只要有一个不为0,则语句的缓存就能生效。如果默认值: 0-->
<property name="maxStatements">0</property>
<!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->
<property name="checkoutTimeout" value="3000"/>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->
<property name="maxIdleTime">30</property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。默认值: 30 ;小于等于0表示无限次-->
<property name="acquireRetryAttempts" value="0"/>
<!--重新尝试的时间间隔,默认为:1000毫秒-->
<property name="acquireRetryDelay" value="1000" />
<!--关闭连接时,是否提交未提交的事务,默认为false,即关闭连接,回滚未提交的事务 -->
<property name="autoCommitOnClose">false</property>
<!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。默认值: null -->
<property name="automaticTestTable">Test</property>
<!--如果为false,则获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常,但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认: false-->
<property name="breakAfterAcquireFailure">false</property>
<!--每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->
<property name="idleConnectionTestPeriod">60</property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。默认值: 0 -->
<property name="maxStatementsPerConnection"></property>
</named-config>
<c3p0-config>
默认配置:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=UTF8</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="checkoutTimeout">3000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="maxIdleTime">30</property>
<property name="acquireIncrement" value="2"/>5</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
<user-overrides user="test-user">
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="maxStatements">0</property>
</user-overrides>
</default-config>
</c3p0-config>
<2>编写工具类
C3P0提供核心工具类:ComboPooledDataSource,如果要使用连接池,必须创建该类的实例对象
new ComboPooledDataSource(“名称”):使用命名配置
new ComboPooledDataSource():使用默认配置
public class C3P0Utils {
//使用默认配置
//private static ComboPooledDataSource dataSource = new ComboPooledDataSource
//使用名为mysql的配置
private static ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");
/**
*获得数据源(连接池)
*/
public static DataSource getDataSource() {
return dataSource;
}
/**
*获得连接
*/
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
2)DBCP连接池
#驱动名
driverClassName=com.mysql.jdbc.Driver
#url
url=jdbc:mysql://localhost:3306/jdbc
#用户名
username=root
#密码
password=123456
#初试连接数
initialSize=10
#最大活跃数
maxTotal=50
#最大idle数(最大空闲连接数)
maxIdle=20
#最小idle数
minIdle=5
#最长等待时间(毫秒)
maxWaitMillis=6000
#程序中的连接不使用后是否被连接池回收(该版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow)
#removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除(秒)(为配合测试程序才配置为1秒)
removeAbandonedTimeout=1
常见配置项:
编写工具类:
public class DBCPUtils {
private static DataSource dataSource;
static{
try {
//1.加载找properties文件输入流
InputStream is = DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties");
//2.加载输入流
Properties props = new Properties();
props.load(is);
//3.创建数据源
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static DataSource getDataSource(){
return dataSource;
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
10.DBUtils
1)核心类QueryRunner
QueryRunner(DataSouce ds)
,提供数据源(连接池),DBUtils底层自动维护connection
update(String sql,Object... params)
, 执行更新数据(增删改)
query(String sql,ResultSetHandle<T> rsh, Object... params)
,执行查询
2)ResultSetHandle结果集处理类
3)DBUtils工具类
closeQuietly(Connection conn):关闭连接,如果有异常try后不抛
commitAndCloseQuietly(Connection conn):提交并关闭连接
rollbackAndClostQuietly(Connection conn):回滚并关闭连接
4)具体实现
/*
* 查询所有用户方法
*/
@Test
public void testQueryAll() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from tbl_user";
// 3.执行查询操作,把结果集转换成List<Bean>,其中每个Bean对应一行记录
List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
// 4.对结果集集合进行遍历
for (User user : users) {
System.out.println(user.getUname() + " : " + user.getUpassword());
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 根据id查询用户方法
*/
@Test
public void testQueryUserById() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from tbl_user where uid=?";
//3.为占位符设置值
Object[] params = {21};
// 4.执行查询操作,把结果集转换成一个Bean对象,在使用BeanHandler时需要指定Class,即Bean的类型
User user = qr.query(sql, new BeanHandler<User>(User.class), params);
System.out.println(user.getUname() + " : " + user.getUpassword());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 根据所有用户的总个数
*/
@Test
public void testQueryCount() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select count(*) from tbl_user";
// 4.执行查询操作,单行单列处理器,一般用于聚合查询,在使用ScalarHandler时可以指定列名,如果不指定,默认为第1列。
Long count = (Long) qr.query(sql, new ScalarHandler());
System.out.println(count);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 查询所有用户方法
*/
@Test
public void testQueryAll1() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from tbl_user";
// 3.执行查询操作,把转换集转换成List<Map>,其中每个Map对应一行记录
List<Map<String, Object>> list = qr.query(sql, new MapListHandler());
// 4.对结果集集合进行遍历
for (Map<String, Object> map : list) {
System.out.println(map);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 查询所有用户方法
*/
@Test
public void testQueryAll2() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from tbl_user";
// 3.执行查询操作,多行单例处理器,即获取name列数据
List<Object> list = qr.query(sql, new ColumnListHandler("uname"));
// 4.对结果集集合进行遍历
for (Object object : list) {
System.out.println(object);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
总结:
想要快速链接并且使用数据库需要以下几个步骤:
1.导包:
2.配置数据库文件 c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="user">root</property>
<property name="password">123456</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
</default-config>
</c3p0-config>
3.创建工具类DataSourceUtils.java
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DataSourceUtils {
private static DataSource dataSource = new ComboPooledDataSource();
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
// 直接可以获取一个连接池
public static DataSource getDataSource() {
return dataSource;
}
// 获取连接对象
public static Connection getConnection() throws SQLException {
Connection con = tl.get();
if (con == null) {
con = dataSource.getConnection();
tl.set(con);
}
return con;
}
// 开启事务
public static void startTransaction() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.setAutoCommit(false);
}
}
// 事务回滚
public static void rollback() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.rollback();
}
}
// 提交并且 关闭资源及从ThreadLocall中释放
public static void commitAndRelease() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.commit(); // 事务提交
con.close();// 关闭资源
tl.remove();// 从线程绑定中移除
}
}
// 关闭资源方法
public static void closeConnection() throws SQLException {
Connection con = getConnection();
if (con != null) {
con.close();
}
}
public static void closeStatement(Statement st) throws SQLException {
if (st != null) {
st.close();
}
}
public static void closeResultSet(ResultSet rs) throws SQLException {
if (rs != null) {
rs.close();
}
}
}
4.使用DBUtils连接使用数据库
见上DBUtils里面代码示例。