[数据库 04] JDBC java实现数据库连接
JDBC
1. JDBC
1. 驱动
构架:加一层
java.sql, javax.sql, 和数据库驱动包: mysql-connector-java.jar
2. JDBC程序
- 创建测试数据库
CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
USE jdbcStudy;
CREATE TABLE `users`(
id INT PRIMARY KEY,
NAME VARCHAR(40),
PASSWORD VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
TRUNCATE TABLE `users`;
INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','lisi@sina.com','1981-12-04'),
(3,'wangwu','123456','wangwu@sina.com','1979-12-04')
- 新建默认项目,项目下新建lib目录,导入maven repository 下载的mysql-connector-java.jar文件,
右键设置lib目录Add as Library,才能正常使用
- 万物皆对象
- 加载驱动
- 用户信息和url
- 连接成功返回数据库对象
- 执行sql对象
- 操作
- 释放连接
// 1. 加载驱动 固定写法,从jar包中加载驱动的Class对象
Class.forName("com.mysql.jdbc.Driver");
// 2. 用户信息和url
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";
//如果mysql版本高于jdbc驱动jar包版本,SSL改为false, 否则报错
// 时区问题: 加 &serverTimezone=GMT%2B8
String userName = "root";
String psw = "123456";
// 3. 连接,返回一个数据库对象(connection代表一个数据库)
Connection connection = DriverManager.getConnection(url, userName, psw);
// 4. 创建执行sql的对象
Statement statement = connection.createStatement();
// 5. 用执行sql的对象执行sql语句,并操作(查询query, 删除和插入都是update, )
String sql = "SELECT * from users";
ResultSet resultSet = statement.executeQuery(sql);
// 返回一个链表,resultSet封装了所有查询出来的记录
while(resultSet.next()){
System.out.println("id: "+ resultSet.getObject("id"));
System.out.println("name: "+ resultSet.getObject("name"));
}
// 6. 释放连接
resultSet.close();
statement.close();
connection.close();
3. JDBC中的对象
DriverManager:数据库驱动 Class.forName()获取
Connection: 连接数据库返回的对象 DtriverManager.getConnection()获取
Statement:执行sql语句的对象: connection.createStatement()获取
ResultSet: 返回记录的链表对象: statement.executeQ/U()获取
4. statement 对象(不推荐)
用于完成向数据库发送SQL语句的类
方法:
-
statement.executeQuery(sql) 用于发送查询语句,返回ResultSet对象
-
statement.executeUpdate(sql) 用于发送增,删,改 语句,返回一个整数(导致数据库的多少行发生了变化)
//判断是否插入成功: String sql = "insert into user('id') values ()"; int num = statement.executeUpdate(sql); if (num > 0){ sout("插入数据成成功"); }
实现对连接数据库和关闭数据库的工具类提取:
- src下添加配置文件 db.properties:
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username = root
psw = 123456
- 工具类:
public class JDBCUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String psw = null;
// 工具类写到static代码块中,需要用类加载器获取配置文件
static {
try{
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
//在static中要使用getResourceAsStream()方法,必须使用类加载器来调用,否则无法使用(反射中)
Properties properties = new Properties();
properties.load(is);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
psw = properties.getProperty("psw");
Class.forName(driver);
}catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username,psw);
}
//释放连接
public static void releaseConnection(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if(resultSet != null){
resultSet.close();
}
if(statement!= null){
statement.close();
}
if(connection!= null){
connection.close();
}
}
}
2. SQL注入(本质拼接)
select * from user where id = '' or '1=1' -- sql注入攻击
select * from user where id = '' or '1=1' # -- '#' 直接屏蔽后面的语句
因此, Statement
对象不安全
3. PreparedStatement对象
防止SQL注入,并且效率更高
PS extends Statement, 通过继承修改父类的不足
preparedStatement对象的创建和Statement对象的创建函数不同
String sql = "insert into users(id, name, password, email, birthday values (?, ?, ?, ?, ?)" ;
// 使用预编译的sql语句,语句中?为占位符,用于传入参数查询。
PreparedStatement ps = connection.prepareStatement(sql);
ps.setObject(1, "value");//也可以直接设置setInt(), 防止注入
ps.setObject(2, "value");
ps.setObject(3, "value");
ps.executeUpdate();
流程: 1. 编写SQL, 2. 预编译, 3. 传递参数, 4. 执行
PreparedStatement 防止SQL注入的实现:
防止SQL注入的本质:是把传递进来的参数当作字符
,如果其中存在'
等转义字符,会被直接转义
IDEA连接数据库,切换表:
点击,在弹出的窗口中选择Schema切换表
4. JDBC操作事务
java操作事务
try{
connection = ....getConnection();
//java 只需要执行setAutoCommit关闭,就自动打开了事务,不需要写start transaction
connection.setAutoCommit(false);
sql。。。
connection.commit();
}catch(SQLException e){
connection.rollback();
}finally{
connection.close();
}
5. 数据库连接池
原因: 数据库连接到释放过程十分浪费资源
池化技术: 准备一些预先的资源,过来就连接预先准备好的
eg: 本来: 开门--关门, 有池化技术: 派几个业务员等待开门(相当于池子)
3个重要参数:
最小连接数: 最大连接数 = 常用连接数: 业务最高承载量
如果业务数量超过最大连接数,需要排队等待
等待超时时间: 排队等待的最长时间
编写连接池,实现DataSource接口:
使用连接池后,开发不再需要编写连接数据库的代码
开源数据源实现:
DBCP, C3P0, Druid 可以去maven-repository找到相应的jar包
完全相同,实现连接的工具类需要修改,其他不修改。(jar包实现连接池)