JDBK常用的类和接口
DriverManager类
——是JDBC的管理层,用于管理数据库中的驱动程序。
static { //1注册驱动 try { Class.forName("com.mysql.jdbc.Driver");//加载MySQL数据库驱动 } catch (Exception e) { e.printStackTrace(); } } *加载完后Java会自动将驱动程序注册到DriverManager类中,可通过DriverManager类的getConnection()方法连接相应的数据库
Connection 接口
——连接数据库执行sql语句并返回结果
——Connection 连接是通过 DriverManager 的静态方法 getConnection(.....)来得到的,
Statement 接口
——用于在已经建立连接的基础上向数据库发送SQL语句
分类:——Statement : 用于执行不带参数的简单SQL语句
——PreparedStatement (继承Statement):用于执行动态SQL语句
——CallableStatement(继承PreparedStatement):用于执行对数据库的存储过程的调用
Statement接口的常用方法
方法 | 功能描述 |
---|---|
execute(String sql) | 执行静态的SELECT语句,该语句可能返回多个结果集 |
executeQuery(String sql) | 执行给定的SQL语句,该语句返回单个ResultSet对象 |
clearBatch() | 清空此Statement对象的当前SQL命令列表 |
executeBatch() | 将一批命令提交给数据库来执行,若全部命令执行成功返回更新计数组成的数组(数组顺序与SQL语句添加顺序对应) |
add Batch(String sql) | 将给定的SQL命令添加到此Statement对象的当前命令列表中 |
close() | 释放Statement实例占用的数据库和JDBC资源 |
PreparedStatement 接口
——用于执行动态SQL语句,通过PreparedStatement实例执行的动态SQL语句,将被编译并保存到Prepared Statement实例中,从而可以反复地执行该SQL语句。
Prepared Statement接口提供的常用方法
方法 | 功能描述 |
---|---|
setInt(int index,int k) | 将指定位置的参数设置为 int 值 |
setFloat(int index,float a) | 将指定位置的参数设置为float值 |
setLong(int index,long l) | 将指定位置的参数设置为long值 |
setDouble(int index,double d) | 将指定位置的参数设置为double值 |
setBoolean(int index,boolean b) | 将指定位置的参数设置为boolean值 |
setDate(int index,date date) | 将指定位置的参数设置为对应的date值 |
executeQuery() | 在此PreparedStatement对象中执行SQL查询,并返回该查询生成的RsutSst对象 |
setString(int index,String s) | 将指定位置的参数设置为对应的String值 |
setNull(int index,intsqlType) | 将指定位置的参数设置为SQL NULL |
executeUpdate() | 执行前面包含的参数的动态INSERT、UPDATE或DELETE语句 |
clearParamenters() | 清除当前所有参数的值 |
ResultSet接口
——类似于一个临时表,用来暂存数据库查询操作所获得的结果集
JDBC编程步骤
——1、注册数据库驱动
推荐方式:Class.forName("com.mysql.jdbc.Driver");JAVA 规范中明确规定:所有的驱动程序必须在静态初始化代码块中将驱动注册到驱动程序管理器中。
——2、获取数据库链接
Connection con = DriverManager.getConnection("URL", "User", "Pasword");
*Oracle URL 的格式:jdbc:oracle:thin:@192.168.0.20:1521:test(所使用的库名)
MySQL URL 的写法:jdbc:mysql://192.168.8.21:3306/test
添加设置?useUnicode=true&useSSL=false&characterEncoding=utf8指定字符集连接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/blog?user=root&password=root&useUnicode=true&characterEncoding=utf8");如果使用了xml配置文件,url中的&符号需要转义:&
——3、获得 Statement 对象Statement stmt = con.createStatement();//有注入风险
(预编译)PreparedStatement prst = con.createPrepareStatement(sql);
——4、执行数据库事务
将 sql 语句通过连接发送到数据库中执行,以实现对数据库的操作。stmt.executeQuery(String sql); //返回一个查询结果集。stmt.executeUpdate(String sql); //返回值为 int 型,表示影响记录的条数。(新增,更新,删除操作使用该方法)
——5、如果是查询语句需要处理返回的记录
例: String sql = "select * from test"; ResultSet rs = str. executeQuery(String sql); // 执行SQL语句,执行后有结果集 // 遍历处理结果集信息 while(rs.next()){ System.out.println(rs.getInt("id")); System.out.println(rs.getString("name")) }
——6、关闭数据库连接 (释放资源)
rs.close(); stmt.close(); con.close();(ResultSet Statement Connection 依次关闭。)
连接数据库案例引入(查):
package JDBC; import java.sql.*; /* 1.注册驱动 2.获取连接 3.创建sql 4.处理sql 5.关闭连接,释放资源 */ public class JDBCDemo { static { //1注册驱动 try { Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { String url="jdbc:mysql://localhost:3306/demo?useUnicode=true&useSSL=false&characterEncoding=utf8"; Connection con = null; Statement sta = null; ResultSet rst = null; try { //2.获取连接 con = DriverManager.getConnection(url,"root","123456"); sta = con.createStatement(); //3.创建sql String sql = "select * from user"; //4.执行sql rst = sta.executeQuery(sql); //5处理结果集 while(rst.next()) {//判断是否存在下一个 //获取值 //1、根据下标获取,一种是根据属性获取 // int id = rst.getInt(1);//获取id // String name = rst.getString(2);//获取名字 // System.out.println("id="+id+";name="+name); //------- System.out.println("根据属性去处理结果集====="); int id = rst.getInt("id"); String name = rst.getString("username"); System.out.println("id="+id+";name="+name); } } catch (SQLException e) { e.printStackTrace(); } finally { try { rst.close(); sta.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
连接数据库案例引入(增):
String url="jdbc:mysql://localhost:3306/demo?useUnicode=true&useSSL=false&characterEncoding=utf8"; //获取连接 Date date = new Date(); String Date = sdf.format(date); Connection con =null; Statement sta = null; ResultSet rst = null; PreparedStatement prst = null; try { //通过DriverManager类的getConnection()方法连接相应的数据库 con = DriverManager.getConnection(url,"root","123456"); sta = con.createStatement(); String sql = "insert into booksystem.borrow(rid,bid,borrowtm)values (?,?,?)"; prst = con.prepareStatement(sql); prst.setInt(1,rid); prst.setInt(2,bid); prst.setString(3, Date); prst.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if(sta!=null) { sta.close(); } if(prst!=null) { prst.close(); } con.close(); } catch (SQLException e) { e.printStackTrace(); } }
连接数据库案例引入(改):
String url="jdbc:mysql://localhost:3306/demo?useUnicode=true&useSSL=false&characterEncoding=utf8"; //获取连接 Connection con =null; Statement sta = null; PreparedStatement prst = null; try { //通过DriverManager类的getConnection()方法连接相应的数据库 con = DriverManager.getConnection(url,"root","123456"); sta = con.createStatement(); String sql = "UPDATE booksystem.book set count=(count-1) where id= ?"; prst = con.prepareStatement(sql); prst.setInt(1,id1); prst.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if(sta!=null) { sta.close(); } if(prst!=null) { prst.close(); } con.close(); } catch (SQLException e) { e.printStackTrace(); } } }
连接数据库案例引入(删):
String url="jdbc:mysql://localhost:3306/demo?useUnicode=true&useSSL=false&characterEncoding=utf8"; //获取连接 Connection con =null; PreparedStatement prst = null; try { //通过DriverManager类的getConnection()方法连接相应的数据库 con = DriverManager.getConnection(url,"root","123456"); //创建sql String sql = "delete from booksystem.manager where id = ?"; prst = con.prepareStatement(sql); prst.setInt(1,mid); prst.executeUpdate(); System.out.println("删除成功!"); SuperManager(); } catch (SQLException e) { e.printStackTrace(); } finally { try { if(prst!=null) { prst.close(); } con.close(); } catch (SQLException e) { e.printStackTrace(); } }
JDBC事务处理
事物的定义:
——原子性:原子操作,也就是不可分割的操作,必须 一起成功一起失败。
——一致性:事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。
——分离性:分离性指并发的事务是相互隔离的。
——持久性:持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。
事务处理三部曲
——connection.setAutoCommit(false); // 开启事务
——正常的DB操作 //若有一条SQL语句失败了,自动回滚
——connection.commit() 主动提交或 connection.rollback() 回滚
连接池
c3p0
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- C3P0的缺省(默认)配置-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8</property> <property name="user">root</property>
<property name="password">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!-- <named-config name="xxx"> <property name="xxx">xxx</property> </named-config> --></c3p0-config>
c3p0的使用
为了方便处理,添加获取数据源的工具类
public class DataSourceUtils {
//定义数据源对象
private static DataSource dataSource;
static {
try {
dataSource = new ComboPooledDataSource();//读取了默认配置文件中的数据库配置信息
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return dataSource;
}
}
结合DBUtils工具类进行DAO层处理
public class EmployeeDao {
private QueryRunner runner = new QueryRunner(JDBCUtil.getDataSource());
}
示例
/**
* 添加员工信息
*
* @param emp 员工信息对象
* @return 返回1表示成功插入1条,返回0表示失败
*/
public int insert(Employee emp) {
int rlt = 0;
try {
rlt = runner.update("INSERT INTO tb_emp(number,name,gender,birthday,join,salary) " +
"VALUES(?,?,?,?,?,?)", emp.getNumber(), emp.getName(), emp.getGender(),
DateUtil.date2String(emp.getBirthday()), DateUtil.date2String(emp.getJoin()),
emp.getSalary());
} catch (SQLException e) {
e.printStackTrace();
}
return rlt;
}