unit07-JDBC
学习目标:
- 了解什么是JDBC?为什么要学习这门技术?
- 掌握通过JDBC连接并访问数据库
- 掌握PreparedStatement传输器的使用(SQL注入攻击)
- 掌握什么是连接池?为什么要使用连接池?
- 掌握C3P0连接池的用法
- 数据库事务(放在后面讲,框架之前)
JDBC概述
什么是JDBC?为什么要学习JDBC?
JDBC(Java DataBase Connectivity) Java数据库连接
其实就是利用Java语言/程序连接并访问数据库的一门技术
之前我们可以通过CMD或者navicat等工具连接数据库
但在企业开发中,更多的是通过程序(Java程序)连接并访问数据库,通过Java程序访问数据库,就需要用到JDBC这门技术。
如何通过JDBC程序访问数据库?
1、提出需求:
创建一个 jt_db 数据库,在库中创建一个account表,并插入三条记录,然后利用Java程序查询出account表中所有的记录,并将查询的结果打印在控制台上。
2、开发步骤:
(1)准备数据, 创建jt_db库, 创建account表
drop database if exists jt_db;
create database jt_db charset utf8;
use jt_db;
create table account(
id int primary key auto_increment,
name varchar(50),
money double
);
insert into account values(null, 'tom', 1000);
insert into account values(null, 'andy', 1000);
insert into account values(null, 'tony', 1000);
代码实现:
public static void main(String[] args) throws Exception {
//1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8",
"root", "root");
//3.获取传输器
Statement stat = conn.createStatement();
//4.发送SQL到服务器执行并返回执行结果
String sql = "select * from account";
ResultSet rs = stat.executeQuery( sql );
//5.处理结果
while( rs.next() ) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+" : "+name+" : "+money);
}
//6.释放资源
rs.close();
stat.close();
conn.close();
System.out.println("TestJdbc.main()....");
}
3、执行结果:
JDBC API总结
1、注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
所谓的注册驱动,就是让JDBC程序加载mysql驱动程序,并管理驱动
驱动程序实现了JDBC API定义的接口以及和数据库服务器交互的功能,加载驱动是为了方便使用这些功能。
2、获取连接之数据库URL
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8",
"root", "root" );
DriverManager.getConnection() 用于获取数据连接,返回的Connection连接对象是JDBC程序连接数据库至关重要的一个对象。
参数2和参数3分别是所连接数据库的用户名和密码。
参数1:"jdbc:mysql://localhost:3306/jt_db" 是连接数据库的URL,用于指定访问哪一个位置上的数据库服务器及服务器中的哪一个数据库,其写法为:
当连接本地数据库,并且端口为3306,可以简写为如下形式:
jdbc:mysql:///jt_db
3、Statement传输器对象
Statement stat = conn.createStatement();
该方法返回用于向数据库服务器发送sql语句的Statement传输器对象
该对象上提供了发送sql的方法:
executeQuery(String sql) --
用于向数据库发送查询类型的sql语句,返回一个ResultSet对象中
executeUpdate(String sql) --
用于向数据库发送更新(增加、删除、修改)类型的sql语句,返回一个int值,表示影响的记录行数
4、ResultSet结果集对象
ResultSet对象用于封装sql语句查询的结果,也是一个非常重要的对象。该对象上提供了遍历数据及获取数据的方法。
(1)遍历数据行的方法
next() – 使指向数据行的箭头向下移动一行,并返回一个布尔类型的结果,true表示箭头指向了一行数据,false表示箭头没有指向任何数据(后面也没有数据了)
(2)获取数据的方法
getInt(int columnIndex)
getInt(String columnLable)
getString(int columnIndex)
getString(String columnLable)
getDouble(int columnIndex)
getDouble(String columnLable)
getObject(int columnIndex)
getObject(String columnLable)
...
5、释放资源
rs.close();
stat.close();
conn.close();
此处释放资源必须按照一定的顺序释放,越晚获取的越先关闭。所以先关闭
rs对象,再关闭stat对象,最后关闭conn对象。
另,为了避免上面的程序抛出异常,释放资源的代码不会执行,应该把释放资源的代码放在finally块中.
try{
...
}catch(Exception e){
...
}finally{
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
rs = null;
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
stat = null;
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
conn = null;
}
}
}
增删改查
JDBC增删改查
1、新增:往account表中添加一个名称为john、money为3500的记录
/* 1、新增:往account表中添加一个名称为john、money为3500的记录 */
@Test
public void testInsert() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取连接
conn = JdbcUtil.getConn();
//获取传输器
stat = conn.createStatement();
//发送sql语句到服务器执行,并返回执行结果
String sql = "insert into account values(null, 'john', 3500)";
int rows = stat.executeUpdate( sql );
//处理结果
System.out.println( "影响行数: "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//通过JdbcUtil工具类中的close方法释放资源
JdbcUtil.close(conn, stat, rs);
}
}
2、修改:将account表中名称为john的记录,money修改为1500
/* 2、修改:将account表中名称为john的记录,money修改为1500 */
@Test
public void testUpdate() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取连接
conn = JdbcUtil.getConn();
//获取传输器
stat = conn.createStatement();
//发送sql语句到服务器执行,并返回执行结果
String sql = "update account set money=1500 where name='john'";
int rows = stat.executeUpdate( sql );
//处理结果
System.out.println( "影响行数: "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//通过JdbcUtil工具类中的close方法释放资源
JdbcUtil.close(conn, stat, rs);
}
}
3、查询:查询account表中名称为john的记录
/* 3、查询:查询account表中id为1的记录 */
@Test
public void testFindById() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取连接
conn = JdbcUtil.getConn();
//获取传输器
stat = conn.createStatement();
//执行sql语句,返回执行结果
String sql = "select * from account where id=1";
rs = stat.executeQuery( sql );
//处理结果
if( rs.next() ) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println( id+" : "+name+" : "+money);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.close(conn, stat, rs);
}
}
4、删除:删除account表中名称为john的记录
/* 4、删除:删除account表中名称为john的记录 */
@Test
public void testDelete() {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//注册驱动并获取连接
conn = JdbcUtil.getConn();
//获取传输器
stat = conn.createStatement();
//发送sql语句到服务器执行,并返回执行结果
String sql = "delete from account where name='john'";
int rows = stat.executeUpdate( sql );
//处理结果
System.out.println( "影响行数: "+rows );
} catch (Exception e) {
e.printStackTrace();
} finally {
//通过JdbcUtil工具类中的close方法释放资源
JdbcUtil.close(conn, stat, rs);
}
}