您的位置:首页 > 编程语言

JDBC与DAO篇--03 JDBC高级编程、DAO

2018-03-25 17:57 399 查看


1.ResultSetMetaDataResultSetMetaData:数据结果集的元数据和查询出来的结果集相关,从结果集(ResultSet)中获取。ResultSetMetaData用于描述列信息例子:DbUtils.java:package com.lcz.jdbc.day03;

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);
}
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: