事务[Transaction,简称tx]
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。即不存在一半成功,一半失败的情况。
事务的四大特性
原子性(Atomicity):事务中所有操作是不可再分割的原子单位,
事务中所有操作要么全部执行成功,要么全部执行失败。
一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致,
如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,
使每个并发中的事务不会相互干扰。
持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据
事务常用的API
01——setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了。
02——commit():提交结束事务。
03——rollback():回滚结束事务。
数据库连接池,简称“池”
用池来管理Connection,这可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。池就可以再利用这个Connection对象了。这个池要等到Web服务器停止,或应用程序彻底结束时,才会直正销毁。池销毁之前,池会让池中每个Connection对象调用close()方法来关闭自己。
原SUN公司为数据库连接池提供了公共的接口:叫javax.sql.DataSource,各个厂商可以让自己的连接池实现这个接口
市场上流行的JDBC数据库连接池实现
01——DBCP(早期)
DBCP是Apache提供的一款开源免费的数据库连接池!
Hibernate3.0之后不再对DBCP提供支持!
实现类:BasicDataSource
准备工作:
导入commons-collections.jar
commons-dbcp-1.3.jar
commons-pool.jar
mysql-connector-java-5.1.7-bin.jar到/WEB-INF/lib/目录下
/**
* DBCP数据库连接池的使用
*/
public class Demo01 {
private static BasicDataSource basicDataSource = new BasicDataSource();
static{
//设置数据库连接池基本属性
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver"); basicDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
basicDataSource.setUsername("root");
basicDataSource.setPassword("root");
//设置数据库连接池扩展属性
basicDataSource.setInitialSize(10);
basicDataSource.setMaxActive(10);
basicDataSource.setMaxIdle(5);
}
/**
* 获取数据库连接
*/
public Connection getConnection() throws SQLException{
try {
return basicDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
Demo01 test = new Demo01();
Connection conn = test.getConnection();
System.out.println(basicDataSource.getNumIdle());
if(conn!=null){
System.out.println("已获取连接");
conn.close();
System.out.println(basicDataSource.getNumIdle());
}else{
System.out.println("未获取连接");
}
}
}
02——C3P0(如今)
C3P0也是开源免费的连接池!C3P0被很多人看好!
实现类:ComboPooledDataSource
准备工作:
导入 c3p0-0.9.1.2.jar
mysql-connector-java-5.1.7-bin.jar到/WEB-INF/lib/目录下
* C3P0数据库连接池的使用方式一
*/
public class Demo01 {
private static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
static{
try {
//设置数据库连接池基本属性 comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver"); comboPooledDataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
comboPooledDataSource.setUser("root");
comboPooledDataSource.setPassword("root");
//设置数据库连接池扩展属性
comboPooledDataSource.setInitialPoolSize(10);
comboPooledDataSource.setMaxPoolSize(10);
comboPooledDataSource.setAcquireIncrement(5);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接
*/
public Connection getConnection() throws SQLException{
try {
return comboPooledDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
Demo01 test = new Demo01();
Connection conn = test.getConnection();
if(conn!=null){
System.out.println("已获取连接");
conn.close();
}else{
System.out.println("未获取连接");
}
}
}
c3p0也可以指定配置文件,而且配置文件可以是properties,也可以是xml的。当然xml的高级一些了。但是c3p0的配置文件名必须为c3p0-config.xml,并且必须放在src路径下。
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 连接MySQL数据库服务器 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/jdbc</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">50</property>
<property name="maxPoolSize">100</property>
<property name="acquireIncrement">10</property>
</default-config>
<!-- 连接Oracle数据库服务器-->
<named-config name="oracle-config">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/newsdb</property>
<property name="user">root</property>
<property name="password">roott</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">100</property>
<property name="acquireIncrement">5</property>
</named-config>
</c3p0-config>
/**
* C3P0数据库连接池的使用方式二
* 准备工作:
* 1_编写c3p0-config.xml
* 2_将c3p0-config.xml放在src目录下
*/
public class Demo03 {
/**
* 自动加载/src/c3p0-config.xml文件
*/
private static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("oracle-config");
/**
* 获取数据库连接
*/
public Connection getConnection() throws SQLException{
try {
return comboPooledDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
Demo03 test = new Demo03();
Connection conn = test.getConnection();
if(conn!=null){
System.out.println("已获取连接");
conn.close();
}else{
System.out.println("未获取连接");
}
}
}
/**
* C3P0数据库连接池的使用方式二B
* 准备工作:
* 1_编写c3p0-config.xml
* 2_将c3p0-config.xml放在src目录下
*/
public class Demo03 {
/**
* 自动加载/src/c3p0-config.xml文件
*/
private static ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("oracle-config");
/**
* 获取数据库连接
*/
public Connection getConnection() throws SQLException{
try {
return comboPooledDataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
Demo03 test = new Demo03();
Connection conn = test.getConnection();
if(conn!=null){
System.out.println("已获取连接");
conn.close();
}else{
System.out.println("未获取连接");
}
}
}
DBUtils工具类
DBUtils是Apache Commons组件中的一员,开源免费。
DBUtils是对JDBC的简单封装,但是它还是被很多个人和公司使用。
DBUtils工具类,需要导入dbutils.jar到项目的classpath中。即/WEB-INF/lib/目录下
01— 辅助类DBUtils类
02— 主要类QueryRunner(DataSource)类
update():执行insert、update、delete;
batch():相同结构的SQL,批处理
/**
* 演示DBUtils工具类的CUD操作
*/
public class Demo01 {
public void add() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "insert into users(username,password,gender,city) values(?,?,?,?)";
Object[] params = {"赵君","123456","男","深圳"};
runner.update(sql,params);
}
public void addAll() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "insert into users(username,password,gender,city) values(?,?,?,?)";
Object[][] params =
{
{"哈哈","123456","男","北京"},
{"呵呵","123457","男","深圳"},
{"嘻嘻","123458","男","上海"},
{"嘿嘿","123459","男","广州"},
};
runner.batch(sql,params);
}
public void update() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "update users set city=? where username=?";
Object[] params = {"广州","赵君"};
runner.update(sql,params);
}
public void delete() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "delete from users where username=?";
Object[] params = {"赵君"};
runner.update(sql,params);
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
Demo01 test = new Demo01();
//test.add();
//test.update();
//test.delete();
test.addAll();
}
}
DBUtils提供了很多个ResultSetHandler接口的实现,这些实现已经基本够用了。
01——MapHandler:单行处理器
把结果集转换成Map<String,Object>,其中key为列名,value为列值
02——MapListHandler:多行处理器
把结果集转换成List<Map<String,Object>>
03——BeanHandler:单行处理器
把结果集转换成Bean,该处理器需要Class参数,即Bean的类型
04——BeanListHandler:多行处理器
把结果集转换成List<Bean>
05——ScalarHandler:单行单列处理器
把结果集转换成Object。一般用于聚集查询
例如select count(id) from users
/**
* 演示DBUtils工具类的R操作
*/
public class Demo {
public void findByIdWithMapHandler() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "select * from users";
Map<String,Object> map = runner.query(sql,new MapHandler());
System.out.println(map.get("username")+"#"+map.get("gender"));
}
public void findAllWithMapListHandler() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "select * from users";
List<Map<String,Object>> list = runner.query(sql,new MapListHandler());
for(Map<String,Object> map : list){
System.out.println(map.get("username")+"#"+map.get("gender"));
}
}
public void findByIdWithBeanHandler() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "select id,username,password,gender,city from users";
User user = runner.query(sql,new BeanHandler<User>(User.class)); System.out.println(user.getUsername()+"#"+user.getGender());
}
public void findByIdWithBeanListHandler() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "select * from users";
List<User> userList = runner.query(sql,new BeanListHandler<User>(User.class));
for(User user:userList){
System.out.println(user.getUsername()+"#"+user.getGender());
}
}
public void getTotalWithScalarHandler() throws Exception{
QueryRunner runner = new QueryRunner(JdbcUtil2.getDs());
String sql = "select count(id) from users";
Long temp = (Long) runner.query(sql,new ScalarHandler());
System.out.println(temp.intValue());
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
Demo02 test = new Demo02();
//test.findByIdWithMapHandler();
//test.findAllWithMapListHandler();
//test.findByIdWithBeanHandler();
//test.findByIdWithBeanListHandler();
test.getTotalWithScalarHandler();
}
}