JDBC与DAO篇--03 JDBC高级编程、DAO
2018-03-25 17:57
399 查看
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
/**
* 连接池版本的数据库连接管理工具类
* 适合于并发场合
* @author LvChaoZhang
*
*/
public class DbUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
private static int initSize;
private static int maxActive;
private static BasicDataSource bs;
static {
//连接池
bs=new BasicDataSource();
Properties cfg=new Properties();
try {
InputStream in =DbUtils.class.getClassLoader().getResourceAsStream("db.properties");
cfg.load(in);
//初始化参数
driver=cfg.getProperty("jdbc.driver");
url=cfg.getProperty("jdbc.url");
username=cfg.getProperty("jdbc.user");
password=cfg.getProperty("jdbc.password");
initSize=Integer.parseInt(cfg.getProperty("initSize"));
maxActive=Integer.parseInt(cfg.getProperty("maxActive"));
in.close();
//初始化连接池
bs.setDriverClassName(driver);
bs.setUrl(url);
bs.setUsername(username);
bs.setPassword(password);
bs.setInitialSize(initSize);
bs.setMaxActive(maxActive);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() {
try {
//getConnection()从连接池中获取重用的连接,如果连接池满了,则等待,如果有连接归还,则获取重用的连接
Connection conn = bs.getConnection();
return conn;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
public static void rollback(Connection conn) {
if(conn!=null) {
try {
conn.rollback();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void close(Connection conn) {
if(conn!=null) {
try {
//将用过的连接归还到连接池中
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.lcz.jdbc.day03; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; /** * 结果集 * @author LvChaoZhang * */ public class Demo01 { public static void main(String[] args) { Connection conn=null; try { conn=DbUtils.getConnection(); String sql="select * from student"; Statement st=conn.createStatement(); ResultSe 4000 t rs = st.executeQuery(sql); ResultSetMetaData meta = rs.getMetaData(); int n=meta.getColumnCount(); for(int i=1;i<=n;i++) { String name=meta.getColumnName(i); System.out.println(name); } } catch (Exception e) { e.printStackTrace(); }finally { DbUtils.close(conn); } } }
2.事务(Transaction)事务:数据库中保证交易可靠的机制JDBC支持数据库中的事务概念;在JDBC中,事务默认是自动提交的 事务特性ACID:(1)原子性:事务必须是原子工作单位;对于其数据修改,要么全都执行,要么全都不执行(2)一致性:事务在完成时,必须使所有的数据都保持一致状态。(3)隔离性:由并发事务所作的修改必须与任何其他并发事务所作的修改隔离(4)持久性:事务完成之后,它对于系统的影响是永久性的。 JDBC事务API相关API:Connection.getAutoCommit():获得当前事务的提交方式,默认为trueConnection.setAutoCommit():设置事务的提交属性,参数是true:默认提交;false:不自动提交Connection.commit():提交事务 例子:转账package com.lcz.jdbc.day03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Demo2 {
public static void main(String[] args) {
pay(2,1,1000);
System.out.println("ok");
}
public static void pay(int from,int to,double money) {
Connection conn=null;
String sql1="update lcz_account set balance=balance+? where id=?";
String sql2="select balance from lcz_account where id=?";
try {
conn=DbUtils.getConnection();
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement(sql1);
//减钱
ps.setDouble(1, -money);
ps.setInt(2, from);
int n=ps.executeUpdate();
if(n!=1) {
throw new Exception("扣错了");
}
//增钱
ps.setDouble(1, money);
ps.setInt(2, to);
n=ps.executeUpdate();
if(n!=1) {
throw new Exception("加错了");
}
ps.close();
//检查
ps=conn.prepareStatement(sql2);
ps.setInt(1, from);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
double bal=rs.getDouble("balance");
if(bal<0) {
throw new Exception("原账号透支");
}
}
conn.commit();
} catch (Exception e) {
e.printStackTrace();
DbUtils.rollback(conn);
}finally {
DbUtils.close(conn);
}
}
}
3.批量更新addBatch(String sql):Statement类的方法,可以将多条sql语句添加Statement的SQL语句列表中。addBatch():PreparedStament类的方法,可以将多条预编译的sql语句添加到PreparedStatement对象的SQL语句列表中。executeBatch():把Statement对象或PreparedStatement对象语句列表中的所有SQL语句发送给数据库进行处理。clearBatch():清空当前SQL语句列表 防止OutOfMemory:如果PreparedStatement对象中的SQL列表包含过多的待处理的SQL语句会产生OutOfMemeory错误,分段处理SQL语句列表。 例子:批量处理DDLpackage com.lcz.jdbc.day03;
import java.sql.Connection;
import java.sql.Statement;
/**
* 执行一批DDL
* @author LvChaoZhang
*
*/
public class Demo03 {
public static void main(String[] args) {
// String sql1="create table log_01(id int(8),msg varchar(100))";
// String sql2="create table log_02(id int(8),msg varchar(100))";
// String sql3="create table log_03(id int(8),msg varchar(100))";
String sql1="insert log_01(id,msg) values(1,'I')";
String sql2="insert log_02(id,msg) values(2,'LOVE')";
String sql3="insert log_03(id,msg) values(3,'U')";
//执行一批SQL
Connection conn=null;
try {
conn=DbUtils.getConnection();
Statement st=conn.createStatement();
//sql1添加到statement的缓冲区
st.addBatch(sql1);
st.addBatch(sql2);
st.addBatch(sql3);
//执行一批SQL
int[] arr = st.executeBatch();
System.out.println("OK");
} catch (Exception e) {
e.printStackTrace();
}finally {
DbUtils.close(conn);
}
}
}例子:执行批量参数处理package com.lcz.jdbc.day03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Arrays;
/**
* 执行批量参数处理
* @author LvChaoZhang
*
*/
public class Demo04 {
public static void main(String[] args) {
String sql="insert into user(id,name,pwd) values(?,?,?)";
Connection conn=null;
try {
conn=DbUtils.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
for(int i=0;i<100;i++){
//替换参数
ps.setInt(1, i);
ps.setString(2, "name"+i);
ps.setString(3, "123456");
//将参数添加到缓冲区
ps.addBatch();
//防止OutOfMemory
if((i+1)%8==0) {
ps.executeBatch();
ps.clearBatch();
}
}
//批量执行
int[] arr = ps.executeBatch();
System.out.println(Arrays.toString(arr));
} catch (Exception e) {
e.printStackTrace();
}finally {
DbUtils.close(conn);
}
}
}
4.返回自动主键 package com.lcz.jdbc.day03;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
* 数据库中
*
* @author LvChaoZhang
*
*/
public class Demo5 {
public static void main(String[] args) {
Connection conn=null;
try {
conn=DbUtils.getConnection();
conn.setAutoCommit(false);
//第一个sql
String sql1="insert into r_keywords(word) values(?)";
String[] cols= {"id"};//自动生成序号的列名
PreparedStatement ps = conn.prepareStatement(sql1,cols);
ps.setString(1, "雾霾");
int n = ps.executeUpdate();
if(n!=1) {
throw new Exception("话题添加失败");
}
//获取自动生成的ID
ResultSet rs = ps.getGeneratedKeys();
int id=-1;
while(rs.next()) {
id=rs.getInt(1);
}
//第二个sql
String sql2="insert into r_post(content,k_id) values(?,?)";
ps=conn.prepareStatement(sql2);
ps.setString(1, "今天天气不错,晚上有雾霾");
ps.setInt(2,id);
n = ps.executeUpdate();
if(n!=1) {
throw new Exception("天气太糟");
}
conn.commit();
System.out.println("ok");
} catch (Exception e) {
e.printStackTrace();
DbUtils.rollback(conn);
}finally {
DbUtils.close(conn);
}
}
}
相关文章推荐
- JDBC高级编程 、DAO
- JDBC Unit03 JDBC高级编程 、 DAO
- Linux高级编程--03.make和makfile
- Java高级篇(三)——JDBC数据库编程
- JDBC高级编程。分页
- 高级 DAO 编程
- 高级 DAO 编程
- spring的DAO编程(jdbc)
- Java笔记03:MySQL数据库与JDBC编程01
- javascript高级编程笔记03(正则表达式)
- JDBC高级编程
- 高级 DAO 编程
- JDBC与DAO篇--01 JDBC原理、JDBC基础编程
- JDBC高级应用 - DAO模式与JavaBean
- JDBC高级编程——批处理更新
- 高级 DAO 编程
- 高级 DAO 编程 (IBM developerWorks )
- JDBC高级编程——PreparedStatement
- JDBC编程——DAO设计模式
- C++面向对象高级编程笔记03--GeekBand