JDBC
今日内容
1. JDBC基本概念
2. 快速入门
3. 对JDBC中各个接口和类的详解
JDBC
1. 概念:Java DataBase Connectivity java数据库连接,java语言操作数据库
* JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,既接口。哥哥数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口JDBC编程,真正执行的代码是jar包中的实现类
2. 快速入门:
* 步骤:
1. 导入jar:mysql-connector-java-8.0.25.jar
1. 复制mysql-connector-java-8.0.25.jar到lib下
2. 右键-->add as Library
2. 注册驱动
Class.forName("com.mysql.jc.jdbc.Driver");
3. 获取数据库连接对象Connection
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/DataBaseName?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","1234");
4. 定义SQL
String sql = "update accout set balance = 500 where id = 1";
5. 获取执行sql对象Statement
Statement stmt = conn.createStatement();
6. 执行sql ,接受返回的对象
int count = stmt.executeUpdate(sql);
7. 处理结果
System.out.println(count);
8. 释放资源
stmt.close();
conn.close();
3. 详解各个对象
1. DriverManager: 驱动管理对象
* 功能:
1. 注册驱动:
static void registerDriver(Driver driver):注册与给定的驱动程序
写代码时:Class.forName("com.mysql.cj.jdbc.Driver");
通过查看源码:发现在com.mysql.cj.jdbc.Driver类中有静态代码块:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
**注意**:mysql5之后注册驱动可以省略
2. 获取数据库连接
* 方法:static Connection getConnection(String url,String user,String password)
* 参数:
* url:指定连接的路径
* 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
* 例如:jdbc:mysql://localhost:3306/DataBaseName?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
* 细节:如果连接的是本地mysql数据库,且默认端口为3306,则url可以写为:jdbc:mysql:///数据库名称
* user:用户名
* password:密码
2. Connection: 数据库连接对象
1. 功能:
1. 获取执行sql的对象
* Statement createStatement()
* PrepareStatement prepareStatement(String sql)
2. 管理事务:
* 开启事务:void setAutoCommit(boolean autoCommit):该方法设置参数为false,即开启事务
* 提交事务:commit()
* 回滚事务: rollback()
3. Statement: 执行sql的对象
1. 执行sql
1. boolean execute(String sql): 可以执行任意的SQL语句
2. int executeUpdate(String sql): 执行DML(insert,update,delete)语句,DDL(create,alter,drop)语句
* 返回值:影响的行数
3. ResultSet executeQuery(String sql): 执行DQL(select)语句
2. 练习:
1. accout表 添加一条记录
2. account表 修改记录
3. account表 删除一条记录
4. ResultSet:结果集对象,封装查询结果
1. boolean next(): 右边向下移动一行,判读当前行是否是最后一行末尾,是否有数据,是false,不是true
2. getXxx(): 获取数据
* Xxx代表数据类型 如:int getInt() String getString()
* int :代表列的编号,从1开始
* String:代表列名称
* **注意**:
* 使用步骤:
1. 游标向下移动一行
2. 判断是否有数据
3. 获取数据
5. PreparedStatement:执行sql的对象
1. sql注入问题: 在拼接sql时有一些sql的特使关键字参与字符串的拼接,会造成安全问题
1. 输入任意用户与密码
2. sql:select * from user where username = 'sss' and password = 'adsa' or 'a' = 'a'
2. 解决:使用PreparedStatement对象
3. 预编译sql:参数?做占位符
1. 步骤:
1. 导入jar:mysql-connector-java-8.0.25.jar
2. 注册驱动
3. 获取数据库连接对象Connection
4. 定义SQL
* 注意:sql参数?做占位符
* 如:select * from user where username = ? and password = ?;
5. 获取执行sql对象PreparedStatement
* 调用:Connevtion.prepareStatement(String sql)
6. 给?赋值:
1. 方法:setXxx(参数1,参数2)
* 参数1:?的位置标号,从一开始
* 参数2:?的值
7. 执行sql ,接受返回的对象
8. 处理结果
9. 释放资源
5. 注意:后期都用prepareStatement
抽取JDBC工具类 :JDBCUtils
* 目的:简化书写
* 分析:
1. 注册驱动也抽取
2. 抽取一个方法获取连接对象
1. 需求:不想传递参数,还要保证工具类的通用性
2. 解决:配置文件
jdbc.properties
url=
user=
password=
3. 抽取一个方法去释放资源
代码实现
static {
//读取资源文件
try {
//1.创建Properties集合类
Properties pro = new Properties();
//获取src下路径文件的方式 Classloader
ClassLoader classLoader = JdbcUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
assert res != null;
String path = res.getPath();
System.out.println(path);
//2.加载文件
pro.load(new FileReader(path));
//3.获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4.注册驱动
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
* 练习:
* 需求:
1. 通过键盘录入用户名和密码
2. 判断用户是否登入成功
* 步骤:
1. 创建表 user
CREATE table USER(
id INT PRIMARY KEY AUTO_INCREMENT ,
username VARCHAR (32),
PASSWORD VARCHAR (32)
);
INSERT INTO user VALUES (NULL ,'zhangsan',"123");
INSERT INTO user VALUES (NULL ,'lisi',"234");
代码
public boolean login2(String username,String password){
if (username == null && password == null){
return false;
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
//连接数据库来判断是否成功
try {
conn = JdbcUtils.getConnection();
//定义SQL
String sql = "select * from user where username = ? and PASSWORD = ?";
//获取执行sql对象PreparedStatement
pstmt = conn.prepareStatement(sql);
//给?赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
//执行sql ,接受返回的对象
rs = pstmt.executeQuery();
//处理结果
return rs.next();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
//释放资源
JdbcUtils.close(rs,pstmt,conn);
}
return false;
}
}
JDBC控制事务
1. 事务:一个包含多个步骤的业务操作。如果这个事务操作被事务管理,则这些步骤要么同时成功,要么同时失败
2. 操作:
1. 开启事务
2. 提交事务
3. 回滚事务
3. 使用Connection对象来管理事务
1. 开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false及开启事务
* 在sql之前开启事务
2. 提交事务:commit() :
* 当所有sql都执行完提交事务
3. 回滚事务: rollback()
* 在catch中回滚事务
代码
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtils.getConnection();
//开起事务
conn.setAutoCommit(false);
//定义SQL
String sql1 = "update account set balance = balance - ? where id = ?";
String sql2 = "update account set balance = balance + ? where id = ?";
assert false;
//获取执行sql对象PreparedStatement
pstmt1 = conn.prepareStatement(sql1);
pstmt2 = conn.prepareStatement(sql2);
//给?赋值
pstmt1.setDouble(1, 500);
pstmt1.setInt(2, 1);
pstmt2.setDouble(1, 500);
pstmt2.setInt(2, 2);
//执行sql ,接受返回的对象
pstmt1.executeUpdate();
pstmt2.executeUpdate();
//提交事务
conn.commit();
}catch (Exception e){
//回滚事务
try {
if (conn != null){
conn.rollback();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}finally {
JdbcUtils.close(null,pstmt1,conn);
JdbcUtils.close(null,pstmt2,null);
}
}