今日内容
1.
JDBC
基本概念
2.
快速入门
3.
对
JDBC
中各个接口和类详解
JDBC
:
1.
概念
Java DataBase Connectivity Java
数据库连接,
Java
语言操作数据库
JDBC
本质:其实是官方(
sun
公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据
库厂商去实现这套接口,提供数据库驱动
jar
包。我们可以使用这套接口(
JDBC
)编程,真正执行
的代码是驱动
jar
包中的实现类。
2.
快速入门:
步骤:
1.
导入驱动
jar
包
mysql-connector-java-5.1.37-bin.jar
1.
复制
mysql-connector-java-5.1.37-bin.jar
到项目的
libs
目录下
2.
右键
-->Add As Library
2.
注册驱动
3.
获取数据库连接对象
Connection
4.
定义
sql
5.
获取执行
sql
语句的对象
Statement
6.
执行
sql
,接受返回结果
7.
处理结果
8.
释放资源
/*
*
快速入门
jdbc
* */
public class
JdbcDemo1
{
public static
void
main
(
String
[]
args
)
throws
ClassNotFoundException
,
SQLException
{
/*1.
注册驱动
2.
获取数据库连接对象
Connection
3.
定义
sql
4.
获取执行
sql
语句的对象
Statement
5.
执行
sql
,接受返回结果
6.
处理结果
7.
释放资源
*/
//1.
注册驱动
Class
.
forName
(
"com.mysql.jdbc.Driver"
);
//2.
获取数据库连接对象
Connection
Connection conn
=
DriverManager
.
getConnection
(
"jdbc:mysql://localhost:3306/jdbc"
,
"root"
,
"root"
);
//3.
准备
sql
语句
3.
详解各个对象:
3.1DriverManager
:驱动管理对象
功能:
1.
注册驱动:告诉程序该使用哪一个数据库驱动
jar
static void registerDriver(Driver driver) :
注册与给定的驱动程序
DriverManager
。
写代码使用:
Class.forName("com.mysql.jdbc.Driver");
通过查看源码发现:在
com.mysql.jdbc.Driver
类中存在静态代码块
注意:
mysql5
之后的驱动
jar
包可以省略注册驱动的步骤。
2.
获取数据库连接:
方法:
static Connection getConnection(String url, String user, String password)
参数:
url
:指定连接的路径
语法:
jdbc:mysql://ip
地址
(
域名
):
端口号
/
数据库名称
例子:
jdbc:mysql://localhost:3306/db3
细节:如果连接的是本机
mysql
服务器,并且
mysql
服务默认端口是
3306
,
则
url
可以简写为:
jdbc:mysql:///
数据库名称
user
:用户名
password
:密码
mysql8
及以上需要调整驱动包及配置信息
String
sql
=
"UPDATE t_user SET age=30 WHERE id=3"
;
//4.
获取执行
sql
语句的对象
Statement
Statement statement
=
conn
.
createStatement
();
//5.
执行
sql
,接受返回结果
//boolean execute = statement.execute(sql);//false
int
i
=
statement
.
executeUpdate
(
sql
);
System
.
out
.
println
(
i
);
//6.
释放资源
statement
.
close
();
conn
.
close
();
}
static
{
try
{
java
.
sql
.
DriverManager
.
registerDriver
(
new
Driver
());
}
catch
(
SQLException E
) {
throw new
RuntimeException
(
"Can't register driver!"
);
}
}
//String url="jdbc:mysql://localhost:3306/jdbc";
//String url="jdbc:mysql://127.0.0.1:3306/jdbc";
String
url
=
"jdbc:mysql:///jdbc"
;
3.2Connection
:数据库连接对象
1.
功能:
1.
获取执行
sql
的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
2.
管理事务:
开启事务:
setAutoCommit(boolean autoCommit)
:调用该方法设置参数为
false
,即
开启事务
提交事务:
commit()
回滚事务:
rollback()
3.3Statement
:执行
sql
的对象
1.
执行
sql
1. boolean execute(String sql)
:可以执行任意的
sql
了解
2. int executeUpdate(String sql)
:执行
DML
(
insert
、
update
、
delete
)语句、
DDL(create
,
alter
、
drop)
语句
返回值:影响的行数,可以通过这个影响的行数判断
DML
语句是否执行成功 返回值
>0
的则执行成功,反之,则失败。
3. ResultSet executeQuery(String sql)
:执行
DQL
(
select)
语句
2.
练习:
1. account
表 添加一条记录
2. account
表 修改记录
3. account
表 删除一条记录
Class
.
forName
(
"com.mysql.cj.jdbc.Driver"
);
//
此处注意
String
url
=
"jdbc:mysql://localhost:3306/test?
useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false"
/*
* sql
查询
* */
public class
JdbcDemo2
{
public static
void
main
(
String
[]
args
) {
Connection conn
=
null
;
Statement statement
=
null
;
try
{
//1.
加载驱动
Class
.
forName
(
"com.mysql.jdbc.Driver"
);
//2.
获取连接对象
String
url
=
"jdbc:mysql://127.0.0.1:3306/jdbc"
;
String
user
=
"root"
;
String
password
=
"root"
;
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
//3.
准备
sql
语句
String
sql
=
"select * from user where id=3"
;
//4.
获取语句执行对象
statement
=
conn
.
createStatement
();
//5.
执行
sql
语句
3.4 ResultSet
:结果集对象
,
封装查询结果
boolean next():
游标向下移动一行,判断当前行是否是最后一行末尾
(
是否有数据
)
,如果是,则返
回
false
,如果不是则返回
true
getXxx(
参数
):
获取数据
Xxx
:代表数据类型
如:
int getInt() , String getString()
参数:
1. int
:代表列的编号
,
从
1
开始
如:
getString(1)
2. String
:代表列名称。 如:
getDouble("balance")
注意:
使用步骤:
1.
游标向下移动一行
2.
判断是否有数据
3.
获取数据
//
循环判断游标是否是最后一行末尾。
ResultSet rs
=
statement
.
executeQuery
(
sql
);
//6.
结果集数据处理
}
catch
(
ClassNotFoundException e
) {
e
.
printStackTrace
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
finally
{
//7.
释放资源
try
{
if
(
statement
!=
null
){
statement
.
close
();
}
if
(
conn
!=
null
){
conn
.
close
();
}
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
}
}
/*
* sql
查询
* */
public class
JdbcDemo2
{
public static
void
main
(
String
[]
args
) {
Connection conn
=
null
;
Statement statement
=
null
;
try
{
//1.
加载驱动
Class
.
forName
(
"com.mysql.jdbc.Driver"
);
//2.
获取连接对象
String
url
=
"jdbc:mysql://127.0.0.1:3306/jdbc"
;
String
user
=
"root"
;
String
password
=
"root"
;
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
//3.
准备
sql
语句
//String sql="select * from t_user where id=3";
String
sql
=
"select * from t_user"
;
//4.
获取语句执行对象
statement
=
conn
.
createStatement
();
//5.
执行
sql
语句
ResultSet rs
=
statement
.
executeQuery
(
sql
);
//7.
定义一个集合存储
user
对象
List
<
User
>
list
=
new
ArrayList
<>
();
//6.
结果集数据处理
while
(
rs
.
next
()){
/* boolean next = rs.next();//
判断有没有数据
System.out.println("next"+next);*/
/*int id = rs.getInt(1);
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println(id+"------"+name+"---------
"+age);*/
//
创建
user
对象
//User user = new User(id, name, age);
User user1
=
new
User
();
user1
.
setId
(
rs
.
getInt
(
1
));
user1
.
setAge
(
rs
.
getInt
(
"age"
));
user1
.
setName
(
rs
.
getString
(
"name"
));
list
.
add
(
user1
);
}
//
遍历
list
集合
for
(
User u
:
list
){
System
.
out
.
println
(
u
.
toString
());
}
}
catch
(
ClassNotFoundException e
) {
e
.
printStackTrace
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
finally
{
//7.
释放资源
try
{
if
(
statement
!=
null
){
statement
.
close
();
}
if
(
conn
!=
null
){
conn
.
close
();
}
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
}
}
public class
User
{
private
int
id
;
private
String
name
;
private
int
age
;
public
User
() {
}
public
User
(
int
id
,
String
name
,
int
age
) {
this
.
id
=
id
;
this
.
name
=
name
;
this
.
age
=
age
;
}
public
int
getId
() {
return
id
;
}
public
void
setId
(
int
id
) {
this
.
id
=
id
;
}
public
String
getName
() {
return
name
;
}
public
void
setName
(
String
name
) {
this
.
name
=
name
;
}
public
int
getAge
() {
return
age
;
}
public
void
setAge
(
int
age
) {
this
.
age
=
age
;
}
@Override
public
boolean
equals
(
Object
o
) {
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
User user
=
(
User
)
o
;
return
id
==
user
.
id
&&
age
==
user
.
age
&&
Objects
.
equals
(
name
,
user
.
name
);
}
@Override
public
int
hashCode
() {
return
Objects
.
hash
(
id
,
name
,
age
);
}
练习:
定义一个方法,查询
emp
表的数据将其封装为对象,然后装载集合,返回。
1.
定义
Emp
类
2.
定义方法
public List findAll(){}
3.
实现方法
select * from emp;
3.5 PreparedStatement
:执行
sql
的对象
1. SQL
注入问题:在拼接
sql
时,有一些
sql
的特殊关键字参与字符串的拼接。会造成安全性问题
1.
输入用户随便,输入密码:
a' or 'a' = 'a
2. sql
:
select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
@Override
public
String
toString
() {
return
"User{"
+
"id="
+
id
+
", name='"
+
name
+
'\''
+
", age="
+
age
+
'}'
;
}
}
Connection conn
=
null
;
Statement statement
=
null
;
try
{
//1.
加载驱动
Class
.
forName
(
"com.mysql.jdbc.Driver"
);
//2.
获取连接对象
String
url
=
"jdbc:mysql://127.0.0.1:3306/jdbc"
;
String
user
=
"root"
;
String
password
=
"root"
;
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
//3.
准备
sql
语句
String
name
=
"zhangsan"
;
String
pwd
=
" 1' or '1'='1 "
;
String
sql
=
"select * from user where name='"
+
name
+
"' and
password='"
+
pwd
+
"'"
;
System
.
out
.
println
(
"sql:"
+
sql
);
//4.
获取语句执行对象
statement
=
conn
.
createStatement
();
//5.
执行
sql
语句
ResultSet rs
=
statement
.
executeQuery
(
sql
);
//6.
处理结果集
/*while(rs.next()){
}*/
if
(
rs
.
next
()){
//
登录成功
System
.
out
.
println
(
"
登录成功
"
);
}
else
{
System
.
out
.
println
(
"
用户名或密码有误!
"
);
}
}
catch
(
ClassNotFoundException e
) {
e
.
printStackTrace
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
finally
{
if
(
statement
!=
null
){
try
{
statement
.
close
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
if
(
conn
!=
null
){
try
{
conn
.
close
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
}
2.
解决
sql
注入问题:使用
PreparedStatement
对象来解决
3.
预编译的
SQL
:参数使用
?
作为占位符
4.
步骤:
1.
导入驱动
jar
包
mysql-connector-java-5.1.37-bin.jar
2.
注册驱动
3.
获取数据库连接对象
Connection
4.
定义
sql
注意:
sql
的参数使用?作为占位符。 如:
select * from user where username = ?
and password = ?;
5.
获取执行
sql
语句的对象
PreparedStatement Connection.prepareStatement(String sql)
6.
给?赋值:
方法:
setXxx(
参数
1,
参数
2)
参数
1
:?的位置编号 从
1
开始
参数
2
:?的值
7.
执行
sql
,接受返回结果,不需要传递
sql
语句
8.
处理结果
9.
释放资源
5.
注意:后期都会使用
PreparedStatement
来完成增删改查的所有操作
1.
可以防止
SQL
注入
2.
效率更高
Connection conn
=
null
;
PreparedStatement ps
=
null
;
ResultSet rs
=
null
;
try
{
//1.
加载驱动
Class
.
forName
(
"com.mysql.jdbc.Driver"
);
//2.
获取连接对象
String
url
=
"jdbc:mysql://127.0.0.1:3306/jdbc"
;
String
user
=
"root"
;
String
password
=
"root"
;
conn
=
DriverManager
.
getConnection
(
url
,
user
,
password
);
//3.
准备
sql
语句
String
name
=
"zhangsan"
;
//String pwd="123456";
String
pwd
=
" 1' or '1'='1 "
;
String
sql
=
"select * from user where name=? and password = ?"
;
System
.
out
.
println
(
"sql:"
+
sql
);
//4.
获取语句执行对象
//statement = conn.createStatement();
ps
=
conn
.
prepareStatement
(
sql
);
//4.2
对 ? 赋值
ps
.
setString
(
1
,
name
);
ps
.
setString
(
2
,
pwd
);
//5.
执行
sql
语句
//ResultSet rs = statement.executeQuery(sql);
rs
=
ps
.
executeQuery
();
//6.
处理结果集
/*while(rs.next()){
}*/
if
(
rs
.
next
()){
//
登录成功
System
.
out
.
println
(
"
登录成功
"
);
}
else
{
System
.
out
.
println
(
"
用户名或密码有误!
"
);
}
}
catch
(
ClassNotFoundException e
) {
e
.
printStackTrace
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
finally
{
if
(
rs
!=
null
){
//
关闭结果集
try
{
rs
.
close
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
if
(
ps
!=
null
){
//
关闭语句执行对象
try
{
ps
.
close
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
if
(
conn
!=
null
){
//
关闭连接对象
try
{
conn
.
close
();
}
catch
(
SQLException throwables
) {
throwables
.
printStackTrace
();
}
}
抽取
JDBC
工具类 :
JDBCUtils
1.
案例
目的:简化书写
分析:
1.
注册驱动也抽取
2.
抽取一个方法获取连接对象
需求:不想传递参数(麻烦),还得保证工具类的通用性。
解决:配置文件
jdbc.properties
url=
user=
password=
3.
抽取一个方法释放资源
2.
练习
需求:
1.
通过键盘录入用户名和密码
2.
判断用户是否登录成功
select * from user where username = "" and password = "";
如果这个
sql
有查询结果,则成功,反之,则失败
步骤:
1.
创建数据库表
user
}
2.
代码实现:
JDBC
控制事务:
1.
事务:
一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时
失败。
2.
操作:
1.
开启事务
2.
提交事务
3.
回滚事务
3.
使用
Connection
对象来管理事务
开启事务:
setAutoCommit(boolean autoCommit)
:调用该方法设置参数为
false
,即开启事务
在执行
sql
之前开启事务
提交事务:
commit()
当所有
sql
都执行完提交事务
回滚事务:
rollback()
在
catch
中回滚事务