JDBC及配置文件的使用。测试类(@Test和@Before依旧没解决)。DBCP。事务
2017-09-23 10:37
465 查看
2018.2.27 19:33 第二次修改。
JDBC:是java程序与数据库系统通信的标准API,定义在JDK的API中,通过JDBC,Java可以很方便的与各种数据库进行交互。
前面是具体代码例子,总结在例子后面。
组成包:java.sql.* 和javax.sql.*这两个包都包含在JDK当中
注意:引入的都是java.sql.connection而不是com.mysql.jdbc.connection
JDBC工程建立过程public class JdbcDemo {
public static void main(String[] args) throws Exception {
/*
* 1.创建一个java项目
* 2.倒入jar包
* 3.注册驱动
* 4.获取连接 对象
* 5.获取执行sql语句的对象
* 6.如果是查询 应该有结果集 封装结果集
* 7.关系资源 有顺序 对象自下而上关闭
*/
// 注册数据库驱动
DriverManager.registerDriver(new Driver());
// Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "root", "123456");
// 获取执行sql语句的对象 执行sql语句
Statement st = conn.createStatement();
String sql = "select *from products";
// 执行 返回 结果集对象 set集合去重
ResultSet resultSet = st.executeQuery(sql);
while (resultSet.next()) {
// int id =resultSet.getInt(1);
String id = resultSet.getString(1);
String name = resultSet.getString("name");
// 可输入列数,也可以说输入列的名称
// 当我去封装结果集的时候再去转换products
System.out.println(id + ":" + name);
}
}
}注意点:new Driver 包是com.mysql.jdbc.Driver
导入的jar包为:mysql-connector-java-5.0.8-bin.jar包,一定要buildpath一下。作用为连接mysql数据库
除executeQuery外还有String sql ="insert into products values(null,'高数之四角函数',100,'计算机',1000,'简单')";
int i = statement.executeUpdate(sql); 注册驱动的三种方法 //第一种方式
Driver driver = new Driver() ;
DriverManager.registerDriver(driver) ;
//第二种方式
Driver d = (Driver)Class.forName("com.mysql.jdbc.Driver").newInstance() ;
DriverManager.registerDriver(d) ;
//第三种方式
Class.forName("com.mysql.jdbc.Driver") ; //自动进行注册获取配置文件的三种方法
JDBC和配置文件结合
工作经验:关闭之后赋值为null是因为这样可以运用垃圾回收机制。
封装的工具类public class MyDbutils {
//读取配置文件 注册驱动
static String driverClass=null;
static String url=null;
static String username=null;
static String password=null;
static {
// 读取配置文件
InputStream in = Demo2.class.getClassLoader().getResourceAsStream("config/db.properties");
// 创建properties工具类
Properties p = new Properties();
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driverClass =p.getProperty("driverClass");
url =p.getProperty("url");
username =p.getProperty("username");
password =p.getProperty("password");
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取链接
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url, username, password);
}
/**
* 关闭资源
*/
public static void release(Connection conn,Statement st,ResultSet set){
try {
if(null!=set){
set.close();
set=null;//经验操作
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(null!=st){
st.close();
st=null;//经验操作
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(null!=conn){
conn.close();
conn=null;//经验操作
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试类
@Before和@Test的导入方法,前面博文有,如果报错No tests found matching,首先记住加@Test。mac系统下如果多次报错:not match类的,删除Junit4多删除多导入几遍
测试对象
public class TestObject {
Connection conn=null;
@Before
public void init() throws SQLException{
// 获取数据库连接
conn= MyDbUtils.getConnection();
}
@Test
public void test1(String username,String password) throws SQLException{
String sql="select * from user1 where username= ? and password = ?";
PreparedStatement ps = conn.
f56a
prepareStatement(sql);
// 执行sql语句之前,对sql语句进行检查
ps.setString(1, "zhangsan");
ps.setString(2, "123");
ResultSet set = ps.executeQuery(sql);
while(set.next()){
String name = set.getString("username");
System.out.println(name);
}
}
JDBC常用类的总结
DriverManager类主要作用于用户及驱动程序之间,它是JDBC中的管理层,通过DriverManager类可以管理数据库的驱动程序。
Connection接口位于java.sql包中,相当于与特定数据库的连接会话。
Statement接口接口封装了对数据库的操作,提供了执行语句和获取查询结果的基本方法。
DriverMangerDriverManager.registerDriver()缺点:会导致驱动被创建两次替代方案:Class.forName("com.mysql.jdbc.Driver")
statement作用:向数据库发送并执行具体的sql语句常用方法:ResultSet executeQuery(String sql):只适合查询,返回查询的结果集。Set集合可以去除重复int executeUpdate(String sql):只适合适合增删改,返回影响的记录行数boolean execute(String sql):执行任何sql语句。有结果集的返回1,没有结果集的返回0
ResultSet用于存放结果集注意:Connection要尽量晚的创建,尽量早的释放。确保一定释放,所以要放在finally中
数据库连接池优点:节省创建连接和释放连接 性能消耗连接池中连接起到复用的作用,提高程序性能运行机制:(1)程序初始化时创建连接池(2)使用时向连接池申请可用连接(3)使用完毕,将连接返还给连接池(4)
public class MyDataPool {
// 创建一个池子,里面是Connection对象
List<Connection> list = new LinkedList<Connection>();
public MyDataPool() throws Exception {
for (int i = 0; i < 5; i++) {
Connection conn = MyDbUtils.getConnection();
list.add(conn);
}
}
/**
* 从池子中获取链接
*
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
if (list.size() == 0) {// 池子中没有东西
for (int i = 0; i < 5; i++) {
Connection conn = MyDbUtils.getConnection();
list.add(conn);
}
}
Connection connection = list.remove(0);
return connection;
}
/**
* 将连接归还到池子当中
*
* @throws Exception
*/
public void addBack(Connection conn) throws Exception {
if (list.size() > 8) {
conn.close();
}
list.add(conn);
}
}
测试
手动DBCP(DataBase ConnectionPool)数据库连接池public class Demo1 {
public static void main(String[] args) throws SQLException {
// 创建数据库连接池
BasicDataSource dataSource = new BasicDataSource();
// 设置四大参数 读取配置文件
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///mydb1?characterEncoding=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 获取连接
Connection conn = dataSource.getConnection();
String sql = "update user set username = ? where id=? ";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "吕布");
ps.setString(2, "3");
int i = ps.executeUpdate();
System.out.println(i);
ps.close();
conn.close();
}
}需要事先导入jar包commons-dbcp-1.4jar和commons-pool-1.5.6jar。不然无法创建数据库连接池,也无法调用相关方法配置文件的JDBCdriverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb1?characterEncoding=UTF-8
username =root
password=123456
c3p0数据库连接池:配置文件如下c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///mydb1?characterEncoding=UTF-8
c3p0.user=root
c3p0.password=123456
测试代码如下public class Demo {
public static void main(String[] args) throws Exception {
// 获取c3p0的数据库原数据
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 获取执行sql语句的对象
String sql = "select * from products ";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
List<Product> list = new ArrayList<>();
while (resultSet.next()) {
Product product = new Product();
// 封装结果集
String id = resultSet.getString(1);
String name = resultSet.getString(2);
String price = resultSet.getString(3);
String category = resultSet.getString(4);
String pnum = resultSet.getString(5);
String description = resultSet.getString(6);
product.setId(Integer.parseInt(id));
product.setName(name);
product.setPrice(Double.parseDouble(price));
product.setCategory(category);
product.setPnum(Integer.parseInt(pnum));
product.setDescription(description);
list.add(product);
}
System.out.println(list.size());
MyDbUtils.release(conn, ps, resultSet);
}
}是的。。及其麻烦,所以引入apache的工具类jar包commons-dbutils-1.4jar
现在,用c3p0和刚才的工具类完成功能public class Demo2 {
public static void main(String[] args) throws SQLException {
// 创建数据库连接池的原数据
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 使用apache的工具类
QueryRunner runner = new QueryRunner(dataSource);
// 操作sql语句
// 查询操作,返回一条结果
String sql = "select * from products where id=?";
Product product = runner.query(sql, new BeanHandler<Product>(Product.class), 1);
System.out.println(product);
// 不需要关闭资源
}
}
注意,不用关闭资源。。。c3p0具有自动回收空闲连接的功能,还可以断线自动连接。query(sql,new BeanHandler<封装的实体类>(类名.class),参数可以多个)多条数据的话用 new BeanListHandler<>()
事务:单个逻辑工作单元执行的一系列操作,要么完全的执行,要么完全的不执行
事务的特性原子性:强调事务不可分割的特性,是执行的最小单位一致性:强调事务执行前后的数据保持一致隔离性:强调多个事务同时操作同一条数据的时候,保证事务事件互不干扰持久性:事务一旦结束,数据应该全部保存在数据库中设置事务的隔离级别Read uncommitted 相当于没有隔离级别Read committed 解决脏读问题Repeatable read(mysql默认隔离级别) 解决脏读和不可重复读Serializable 解决任何问题,但是效率最低不考虑隔离级别可能产生的问题脏读:一个事务读取到另一个事务未提交的数据不可重复读:事务中,两次读取到的数据不一致,其他事务有更新操作幻读:食物中两次事务读取到的数据不一致,另一事务存在插入操作mysql操作事务:mysql中的事务默认是开启的,一条sql语句一个事务1.开启事务 start transaction2.提交事务 commit(事务已经结束了,数据也永久的保存在数据库中了)3.回滚事务 rollback(代表事务已经结束了,回滚到了初始化状态)jdbc操作事务Connection接口管理事务void setAutoCommit(boolean auto commit)方法void commit()事务提交void rollback()事务回滚
事务的演示public class TestShiWu {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
//获取链接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1?characterEncoding=UTF-8","root","123456");
//获取执行sql语句的对象
// 西门庆花钱操作
Statement statement = conn.createStatement();
conn.setAutoCommit(false);
String sql ="update user1 set money = money - 100 where name='西门庆'";
int i = statement.executeUpdate(sql);
int h=i/0;
// 武大郎挣钱操作
String sql2 ="update user1 set money = money + 100 where name='武大郎'";
int j = statement.executeUpdate(sql2);
conn.commit();
//释放资源
statement.close();
conn.close();
}
}
这段代码精髓在于。。conn.setAutoCommit(false)和conn.commit();如果不设置为false,默认的是AutoCommit,对,自动提交,这个时候可能会发生西门庆花了钱,h处报错,然后武大郎没有收到钱的情况。但是加了事务的提交后,虽然依旧报错,但是只要扣了钱,另一个操作该数据的操作依旧会执行。
JDBC:是java程序与数据库系统通信的标准API,定义在JDK的API中,通过JDBC,Java可以很方便的与各种数据库进行交互。
前面是具体代码例子,总结在例子后面。
组成包:java.sql.* 和javax.sql.*这两个包都包含在JDK当中
注意:引入的都是java.sql.connection而不是com.mysql.jdbc.connection
JDBC工程建立过程public class JdbcDemo {
public static void main(String[] args) throws Exception {
/*
* 1.创建一个java项目
* 2.倒入jar包
* 3.注册驱动
* 4.获取连接 对象
* 5.获取执行sql语句的对象
* 6.如果是查询 应该有结果集 封装结果集
* 7.关系资源 有顺序 对象自下而上关闭
*/
// 注册数据库驱动
DriverManager.registerDriver(new Driver());
// Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "root", "123456");
// 获取执行sql语句的对象 执行sql语句
Statement st = conn.createStatement();
String sql = "select *from products";
// 执行 返回 结果集对象 set集合去重
ResultSet resultSet = st.executeQuery(sql);
while (resultSet.next()) {
// int id =resultSet.getInt(1);
String id = resultSet.getString(1);
String name = resultSet.getString("name");
// 可输入列数,也可以说输入列的名称
// 当我去封装结果集的时候再去转换products
System.out.println(id + ":" + name);
}
}
}注意点:new Driver 包是com.mysql.jdbc.Driver
导入的jar包为:mysql-connector-java-5.0.8-bin.jar包,一定要buildpath一下。作用为连接mysql数据库
除executeQuery外还有String sql ="insert into products values(null,'高数之四角函数',100,'计算机',1000,'简单')";
int i = statement.executeUpdate(sql); 注册驱动的三种方法 //第一种方式
Driver driver = new Driver() ;
DriverManager.registerDriver(driver) ;
//第二种方式
Driver d = (Driver)Class.forName("com.mysql.jdbc.Driver").newInstance() ;
DriverManager.registerDriver(d) ;
//第三种方式
Class.forName("com.mysql.jdbc.Driver") ; //自动进行注册获取配置文件的三种方法
public class ReadProperties { public static void main(String[] args) throws Exception { // 第一种方法获取文件配置 // FileInputStream in = new FileInputStream("src/db.properties"); //第二种方法获取类加载器 来获取文件的输入流 // InputStream in = ReadProperties.class.getClassLoader().getResourceAsStream("config/db.properties"); // 第三种方法 ResourceBundle bundle = ResourceBundle.getBundle("config/db"); String name = bundle.getString("username"); /*Properties p = new Properties(); p.load(in); String url = p.getProperty("url");一二种方法需要,使用一二种方法相应的修改输出语句参数为url。*/ System.out.println(name); } }
JDBC和配置文件结合
public class Demo3 { static String driverClass=null; static String url=null; static String username=null; static String password=null; static { // 读取配置文件 InputStream in = Demo2.class.getClassLoader().getResourceAsStream("config/db.properties"); // 创建properties工具类 Properties p = new Properties(); try { p.load(in); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } driverClass =p.getProperty("driverClass"); url =p.getProperty("url"); username =p.getProperty("username"); password =p.getProperty("password"); try { Class.forName(driverClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void main(String[] args) { Connection conn =null; Statement st =null; ResultSet set=null; try { conn =DriverManager.getConnection(url,username,password); // 获取执行sql语句的对象 st = conn.createStatement(); String sql ="select * from products where id<8"; // 执行 set = st.executeQuery(sql); while(set.next()){ String name = set.getString("name"); System.out.println(name); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { if(null!=set){ set.close(); set=null;//经验操作,为空之后马上垃圾回收 } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(null!=st){ st.close(); st=null;//经验操作 } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(null!=conn){ conn.close(); conn=null;//经验操作 } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
preparedStatement接口替代Statement的原因及preparedStatement用法:
https://www.cnblogs.com/ysw-go/p/5459330.html
preparedStatement将数据使用setString(int,String),Setint()等方法放进去,要及时executeUpdate()更新一下,并关闭ps,conn,result。工作经验:关闭之后赋值为null是因为这样可以运用垃圾回收机制。
封装的工具类public class MyDbutils {
//读取配置文件 注册驱动
static String driverClass=null;
static String url=null;
static String username=null;
static String password=null;
static {
// 读取配置文件
InputStream in = Demo2.class.getClassLoader().getResourceAsStream("config/db.properties");
// 创建properties工具类
Properties p = new Properties();
try {
p.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driverClass =p.getProperty("driverClass");
url =p.getProperty("url");
username =p.getProperty("username");
password =p.getProperty("password");
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取链接
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url, username, password);
}
/**
* 关闭资源
*/
public static void release(Connection conn,Statement st,ResultSet set){
try {
if(null!=set){
set.close();
set=null;//经验操作
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(null!=st){
st.close();
st=null;//经验操作
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(null!=conn){
conn.close();
conn=null;//经验操作
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试类
public class TestUtil { Connection conn = null; Statement st = null; @Before /** * 在单元测试的每个方法执行前执行此方法 * @throws SQLException */ public void init() throws SQLException { conn = MyDbUtils.getConnection(); st = conn.createStatement(); } @Test /** * 测试完成添加商品 * @throws SQLException */ public void add() throws SQLException { // sql语句 String sql = "insert into products values(null,'六角函数',12.00,'数学',100,'不难')"; // 执行插入操作 int i = st.executeUpdate(sql); System.out.println(i); } @Test /** * 测试完成添加商品 * @throws SQLException */ public void delete() throws SQLException { // sql语句 String sql = "delete from products where id=11"; // 执行插入操作 int i = st.executeUpdate(sql); System.out.println(i); } @Test /** * 测试完成添加商品 * @throws SQLException */ public void update() throws SQLException { // sql语句 String sql = "update products set name='七角函数' where id=11 "; // 执行插入操作 int i = st.executeUpdate(sql); System.out.println(i); } @Test /** * 测试完成添加商品 * @throws SQLException */ public void select() throws SQLException { // sql语句 String sql = "select * from products"; // 执行插入操作 ResultSet executeQuery = st.executeQuery(sql); while(executeQuery.next()){ String id = executeQuery.getString("id"); String name = executeQuery.getString(2); System.out.println(id+":"+name); } MyDbUtils.release(conn, st, executeQuery); } }
@Before和@Test的导入方法,前面博文有,如果报错No tests found matching,首先记住加@Test。mac系统下如果多次报错:not match类的,删除Junit4多删除多导入几遍
测试对象
public class TestObject {
Connection conn=null;
@Before
public void init() throws SQLException{
// 获取数据库连接
conn= MyDbUtils.getConnection();
}
@Test
public void test1(String username,String password) throws SQLException{
String sql="select * from user1 where username= ? and password = ?";
PreparedStatement ps = conn.
f56a
prepareStatement(sql);
// 执行sql语句之前,对sql语句进行检查
ps.setString(1, "zhangsan");
ps.setString(2, "123");
ResultSet set = ps.executeQuery(sql);
while(set.next()){
String name = set.getString("username");
System.out.println(name);
}
}
JDBC常用类的总结
DriverManager类主要作用于用户及驱动程序之间,它是JDBC中的管理层,通过DriverManager类可以管理数据库的驱动程序。
Connection接口位于java.sql包中,相当于与特定数据库的连接会话。
Statement接口接口封装了对数据库的操作,提供了执行语句和获取查询结果的基本方法。
DriverMangerDriverManager.registerDriver()缺点:会导致驱动被创建两次替代方案:Class.forName("com.mysql.jdbc.Driver")
statement作用:向数据库发送并执行具体的sql语句常用方法:ResultSet executeQuery(String sql):只适合查询,返回查询的结果集。Set集合可以去除重复int executeUpdate(String sql):只适合适合增删改,返回影响的记录行数boolean execute(String sql):执行任何sql语句。有结果集的返回1,没有结果集的返回0
ResultSet用于存放结果集注意:Connection要尽量晚的创建,尽量早的释放。确保一定释放,所以要放在finally中
数据库连接池优点:节省创建连接和释放连接 性能消耗连接池中连接起到复用的作用,提高程序性能运行机制:(1)程序初始化时创建连接池(2)使用时向连接池申请可用连接(3)使用完毕,将连接返还给连接池(4)
public class MyDataPool {
// 创建一个池子,里面是Connection对象
List<Connection> list = new LinkedList<Connection>();
public MyDataPool() throws Exception {
for (int i = 0; i < 5; i++) {
Connection conn = MyDbUtils.getConnection();
list.add(conn);
}
}
/**
* 从池子中获取链接
*
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
if (list.size() == 0) {// 池子中没有东西
for (int i = 0; i < 5; i++) {
Connection conn = MyDbUtils.getConnection();
list.add(conn);
}
}
Connection connection = list.remove(0);
return connection;
}
/**
* 将连接归还到池子当中
*
* @throws Exception
*/
public void addBack(Connection conn) throws Exception {
if (list.size() > 8) {
conn.close();
}
list.add(conn);
}
}
测试
public class TestMyPool { public static void main(String[] args) throws Exception { MyDataPool pool = new MyDataPool(); // 获取数据库连接池中的连接 Connection conn = pool.getConnection(); String sql = "insert into account values(null,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, "lisi"); ps.setString(2, "234"); ps.setString(2, "yzp"); int update = ps.executeUpdate(); System.out.println(update); // 将连接返回给连接池 pool.addBack(conn); } }
手动DBCP(DataBase ConnectionPool)数据库连接池public class Demo1 {
public static void main(String[] args) throws SQLException {
// 创建数据库连接池
BasicDataSource dataSource = new BasicDataSource();
// 设置四大参数 读取配置文件
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///mydb1?characterEncoding=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// 获取连接
Connection conn = dataSource.getConnection();
String sql = "update user set username = ? where id=? ";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "吕布");
ps.setString(2, "3");
int i = ps.executeUpdate();
System.out.println(i);
ps.close();
conn.close();
}
}需要事先导入jar包commons-dbcp-1.4jar和commons-pool-1.5.6jar。不然无法创建数据库连接池,也无法调用相关方法配置文件的JDBCdriverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb1?characterEncoding=UTF-8
username =root
password=123456
测试代码
public class Demo2 { public static void main(String[] args) throws Exception { // 创建新的配置文件并加载 Properties p = new Properties(); p.load(new FileInputStream("src/dbcp.properties")); // 创建新的JDBC工厂 BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory(); DataSource dataSource = basicDataSourceFactory.createDataSource(p); // 获取连接 Connection conn = dataSource.getConnection(); String sql = "update user set username = ? where id=? "; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, "张飞"); ps.setString(2, "6"); int i = ps.executeUpdate(); System.out.println(i); ps.close(); conn.close(); } }
c3p0数据库连接池:配置文件如下c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///mydb1?characterEncoding=UTF-8
c3p0.user=root
c3p0.password=123456
测试代码如下public class Demo {
public static void main(String[] args) throws Exception {
// 获取c3p0的数据库原数据
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 获取数据库连接
Connection conn = dataSource.getConnection();
// 获取执行sql语句的对象
String sql = "select * from products ";
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
List<Product> list = new ArrayList<>();
while (resultSet.next()) {
Product product = new Product();
// 封装结果集
String id = resultSet.getString(1);
String name = resultSet.getString(2);
String price = resultSet.getString(3);
String category = resultSet.getString(4);
String pnum = resultSet.getString(5);
String description = resultSet.getString(6);
product.setId(Integer.parseInt(id));
product.setName(name);
product.setPrice(Double.parseDouble(price));
product.setCategory(category);
product.setPnum(Integer.parseInt(pnum));
product.setDescription(description);
list.add(product);
}
System.out.println(list.size());
MyDbUtils.release(conn, ps, resultSet);
}
}是的。。及其麻烦,所以引入apache的工具类jar包commons-dbutils-1.4jar
现在,用c3p0和刚才的工具类完成功能public class Demo2 {
public static void main(String[] args) throws SQLException {
// 创建数据库连接池的原数据
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 使用apache的工具类
QueryRunner runner = new QueryRunner(dataSource);
// 操作sql语句
// 查询操作,返回一条结果
String sql = "select * from products where id=?";
Product product = runner.query(sql, new BeanHandler<Product>(Product.class), 1);
System.out.println(product);
// 不需要关闭资源
}
}
注意,不用关闭资源。。。c3p0具有自动回收空闲连接的功能,还可以断线自动连接。query(sql,new BeanHandler<封装的实体类>(类名.class),参数可以多个)多条数据的话用 new BeanListHandler<>()
事务:单个逻辑工作单元执行的一系列操作,要么完全的执行,要么完全的不执行
事务的特性原子性:强调事务不可分割的特性,是执行的最小单位一致性:强调事务执行前后的数据保持一致隔离性:强调多个事务同时操作同一条数据的时候,保证事务事件互不干扰持久性:事务一旦结束,数据应该全部保存在数据库中设置事务的隔离级别Read uncommitted 相当于没有隔离级别Read committed 解决脏读问题Repeatable read(mysql默认隔离级别) 解决脏读和不可重复读Serializable 解决任何问题,但是效率最低不考虑隔离级别可能产生的问题脏读:一个事务读取到另一个事务未提交的数据不可重复读:事务中,两次读取到的数据不一致,其他事务有更新操作幻读:食物中两次事务读取到的数据不一致,另一事务存在插入操作mysql操作事务:mysql中的事务默认是开启的,一条sql语句一个事务1.开启事务 start transaction2.提交事务 commit(事务已经结束了,数据也永久的保存在数据库中了)3.回滚事务 rollback(代表事务已经结束了,回滚到了初始化状态)jdbc操作事务Connection接口管理事务void setAutoCommit(boolean auto commit)方法void commit()事务提交void rollback()事务回滚
事务的演示public class TestShiWu {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
//获取链接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1?characterEncoding=UTF-8","root","123456");
//获取执行sql语句的对象
// 西门庆花钱操作
Statement statement = conn.createStatement();
conn.setAutoCommit(false);
String sql ="update user1 set money = money - 100 where name='西门庆'";
int i = statement.executeUpdate(sql);
int h=i/0;
// 武大郎挣钱操作
String sql2 ="update user1 set money = money + 100 where name='武大郎'";
int j = statement.executeUpdate(sql2);
conn.commit();
//释放资源
statement.close();
conn.close();
}
}
这段代码精髓在于。。conn.setAutoCommit(false)和conn.commit();如果不设置为false,默认的是AutoCommit,对,自动提交,这个时候可能会发生西门庆花了钱,h处报错,然后武大郎没有收到钱的情况。但是加了事务的提交后,虽然依旧报错,但是只要扣了钱,另一个操作该数据的操作依旧会执行。
相关文章推荐
- 使用SlowCheetah扩展插件解决测试环境和生产环境xml配置文件内容切换
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
- 使用浏览器测试Web服务时出现提示“The test form is only available for requests from the local machine.”的解决办法
- windows7使用临时配置文件登录的解决办法
- 普通域用户登录Windows7提示已使用临时配置文件登录的解决方法
- windows下使用IIS配置的PHP无法上传文件的解决方法
- 解决:在php配置文件路径下,添加php.ini之后,测试页面无法显示
- jdbc数据库连接管理封装工具类,不同使用属性文件配置数据库连接信息(3)
- MySQL字符集问题解决方法(包括改配置文件、命令行修改和JDBC的问题)
- phpadmin 使用配置文件中定义的控制用户连接失败 解决方法
- Spring 使用配置文件读取jdbc.properties
- Spring使用配置文件读取jdbc.properties
- tomcat5.0+mysql配置JDBCRealm,DBCP,ssl,及中文乱码解决详解
- 花生壳phddns-2.0.5.19225在Raspberry Pi上无法使用配置文件的解决方法
- Spring配置文件中使用PropertyPlaceholderConfigurer配置获取jdbc的配置信息
- JAVA学习:JDBC连接DB2数据库(2):使用配置文件
- “使用了CFileDialog后就不能使用GetPrivateProfileString来读取配置文件”的解决办法
- 只有在配置文件或 Page 指令中将 enableSessionState 设置为 true 时,才能使用会话状态等错误解决方法(原)
- 使用Spring配置文件实现事务管理
- win 7 删除了用户文件夹后出现的&quot;你已使用临时配置文件登录&quot;提示的解决方法