JDBC:提供连接各种常用数据库的能力
Java应用程序(客户端)/应用服务器(JSP、Servlet)通过JDBC来连接数据库服务器
JDBC的工作原理:
工作原理.png
说明:
JDBC API:包含供程序员调用的接口与类,集成在java.sql 和 javax.sql中,如 DriverManager类, Connection接口, Statement接口, ResultSet接口。功能:与数据库建立连接、执行Sql语句、处理结果
DriverManager类:管理各种不同的JDBC驱动
JDBC驱动:负责连接各种不同的数据库,由数据库厂商提供
JDBC编程步骤:
1.加载JDBC驱动
2.与数据库建立连接
3.执行sql语句
4.处理结果
5.释放资源
编程模板
上代码(可执行):
import java.sql.*;
public class TestDemo {
public static void main(String[] args){
Connection connection = null;
ResultSet rs = null;
Statement statement = null;
try{
//注意是 com.mysql.cj.jdbc.Driver,不是com.mysql.jdbc.Driver
//第一步:加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
//第二步:建立连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/library_ltg?characterEncoding=utf-8&serverTimezone=UTC", "root", "0011");
System.out.println("连接数据库成功");
//第三步:执行SQL语句
statement = connection.createStatement();
String strSql = "insert into book values('Python','Denis')";
statement.execute(strSql);
//System.out.println("插入成功");
//第四步:处理结果
rs = statement.executeQuery("select * from book");
while (rs.next()){
System.out.println(rs.getString(1)+ " " + rs.getString("author"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//最后,关闭连接
try {
if(rs!=null){
rs.close();
}
if(statement != null){
statement.close();
}
if(connection!=null){
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
注意:pom文件里要包含以下依赖:
mysql
mysql-connector-java
8.0.16
tips:记得pom.xml右键 > maven > reload project
执行结果:
执行结果
Statement常用方法:
常用方法
ResultSet常用方法:
常用方法
注意事项:
ResultSet不能多个做笛卡尔积连接 (即不要嵌套遍历)
ResultSet最好不要超过百条,否则极其影响性能
ResultSet也不是一口气加载所有select结果数据
Connection很昂贵,及时关闭
ResultSetMetaData
用来获取ResultSet返回的属性
getColumnCount(),返回结果的列数
getColumnClassName(i), 返回第i列的数据的Java类名
getColumnTypeName(i), 返回第i列的数据库类型名称
getColumnType(i), 返回第i列的SQL类型
ResultMetaData meta = rs.getMetaData();
int cols = meta.getColumnCount();
for(int i=1; i<=cols; i++){ //i从1开始
//...
}
sql注入式攻击
举例:对于一个表 flowerowner 执行 select * from flowerowner where name = ‘小红’ and password = '123'
密码如果正确,会返回相应数据。错误则不返回
但是,如果在语句后面加上 or '1' = '1',这时所有语句都会被拿出来。这种方式就称为sql注入式攻击
解决方案:
使用PreparedStatement接口(该接口继承自Statement接口,比Statement接口更加灵活,更有效率,也更安全,可读性和可维护性也更强。是一种预编译的sql语句)
StringBuffer sbSql = new StringBuffer("select * from flowerowner where name = ? and password = ?"); //?为占位符
PreparedStatement pstmt = conn.getPreparedStatement(sbSql.toString());
pstmt.setString(1, "小红");
pstmt.setString(2, "123");
rs = pstmt.executeQuery();
PreparedStatement的好处:
防止注入攻击
防止繁琐的字符串拼接和错误
直接设置对象而不需要转换为字符串
使用预编译速度相对statement快很多
addBatch批量处理功能
SQL增删改查常见命令:
显示数据库列表:
show databases
创建:
create table tbl_name
(
id int unsigned not null auto_increment primary key,
name char(8) not null
);
插入:
insert into tbl_name values(1, '张三');
查询:
select * from tbl_name;
修改:
update tbl_name set name='李小四' where id = 1;
删除:
delete from tbl_name where id = 1;
drop table tbl_name;
数据库字段类型:
int 整数4个字节
double 小数8个字节
datetime 时间,7个字节
varchar 字符串,可变字节
数据库连接池:
运用共享技术来实现数据库连接池(享元模式),管理数据库连接
降低系统中数据库连接Connection对象的数量
降低数据库服务器的连接响应消耗
提高Connection获取的响应速度
常用的数据库连接池:
DBCP(Apache 性能较差)
C3P0
Druid(Alibaba )