目录
ResultSet executeQuery(sql): 执行DQL语句(DQL是指查询语句)
JDBC就是使用java语言操作关系型数据库的一套API-----全称(Java DataBase Connectivity--java数据库连接)
JDBC是sun公司定义的一套操作所有关系型数据库的规则,即标准接口,各个数据库厂商自己定义实现类(数据库驱动jar包)用来实现这个接口
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
JDBC好处:
各数据库厂商使用相同的接口,java代码不需要针对不同数据库分别开发
可随时替换底层数据库,访问数据库的java代码基本不变
DriverManager(驱动管理类)
作用:
1.注册驱动
2.获取数据库连接
Connection(数据库连接对象)
作用:
1.获取执行SQL的对象
普通执行SQL对象 Statement createStatement()
预编译SQL的执行SQL对象:防止SQL注入 PreparedStatement prepareStatement(sql)执行存储过程的对象 CallableStatement prepareCall(sql)
2.管理事务
MySql事务管理----mysql默认提交事务
开启事务:BEGIN;/START TRANSACTION;
提交事务:COMMIT;
回滚事务:ROLLBACK;
JDBC事务管理:
Connection接口中定义了3个对应的方法
开启事务:setAutoCommit(boolean autoCommit);
true为自动提交事务
false为手动提交事务,即为开启事务
提交事务:commit()
回滚事务:rollback()
Statement
作用:
执行SQL语句int executeUpdate(sql)
int executeUpdate(sql): 执行DML,DDL语句
返回值:
DML语句-影响的行数,可用返回值是否大于0来判断执行是否成功
DDL语句执行之后,执行成功也可能返回0
DML-数据操作
DDL-数据库定义
DQL-数据查询(数据检索语句)----用于从表中获取数据,确定数据怎样在应用程序中给出
ResultSet executeQuery(sql): 执行DQL语句(DQL是指查询语句)
返回值:
ResultSet结果集对象
ResultSet结果集对象作用:封装了DQL查询语句的结果
ResultSet stmt.executeQuery(sql):执行DQL语句返回ResultSet对象
获取查询结果
boolean next()
boolean next():
1.将光标从当前位置向前移动一行
2.判断当前行是否为有效行
boolean next()返回值:
true:有效行,当前行有数据
false:无效行,当前行没有数据
getXxx(参数)
用于获取数据
xxx: 数据类型:如:int getInt(参数); String getString(参数)
参数:int:列的编号,从1开始
String:列的名称
使用步骤
1.游标向下移动一行,并判断该行是否有数据:next()
2.获取数据:getXxx(参数)
例如:循环判断游标是否是最后一行末尾
while( rs.next() ) {
//获取数据
rs.getXxx(参数);
}
PreparedStatement
作用:预编译SQL语句并执行,预防SQL注入,将敏感字符进行转义
扩展:SQL注入-是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
示例sql注入语句: 'or'1' = '1 简单理解就是靠拼接字符串修改事先定义的sql语句来达到
执行其功能的方法
PreparedStatement预编译功能开启:useServerPrepStmts=true
在进行创建连接对象url时写入配置参数
配置mysql执行日志(重启mysql服务器后生效)
PreparedStatement原理:
1.在获取PreparedStatement对象时,将sql语句发送给sql服务器进行检查,编译(这些步骤很耗时)
2.执行时就不用进行这些步骤了,速度更快
3.如果sql模版一样,则只需要进行一次检查,编译
1.获取PreparedStatement对象
sql语句中的参数值,使用?占位符代替
String sql = "select * from user where username = ? and password = ?";
通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt - conn.preparedStatement(sql);
2.设置参数值
PreparedStatement对象: setXxx(参数1,参数2):
作用:给?赋值
Xxx: 表示数据类型,如 setInt(参数1,参数2) ,数据类型取决于参数的类型型号
参数:参数1:?的位置编号,从1开始
参数2:?的值
3.执行sql
executeUpdate();
或者
executeQuery();
这两种方法均不需要再传递sql
例如:
name = "changan";
password = "123456";
String sql = "select * from user where username = ? and password = ?";
PreparedStatement pstmt = conn.preparedStatement(sql); //获取对象
//设置?的值
pstmt.setString(1,name); //表示第一个?号的值为name
pstmt.setString(2,password); //表示第二个?问号的值为password//执行sql
RsultSet rs = pstmt.executeQuery(); // 不需要再传入sql参数
数据库连接池
数据库连接池是个容器,负责分配,管理数据库连接(Connection)
允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
好处:
资源重用
提升系统响应速度
避免数据库连接遗漏
数据库连接池实现:
标准接口DataSource
官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口
功能:获取连接
Connection getConnection()
常见的数据库连接池:
DBCP
C3P0
Druid
Druid(德鲁伊)
德鲁伊连接池是阿里巴巴开源的数据库连接池项目
功能强大,性能优秀,是java语言最好的数据库连接池之一
步骤:
1.导入jar包 druid-1.1.12.jar
2.定义配置文件
3.加载配置文件
4.获取数据库连接池对象
5.获取连接
JDBC实现步骤:
创建工程,导入驱动jar包
1.注册驱动
Class.forName("com.mysql.jdbc.Driver")
2.获取连接对象
String url = "jdbc:mysql://127.0.0.1:3306/db1?useSSL=false"
db1表示数据库名称,?号后面是参数键值对,可以写多个,中间用&连接
配置useSSL=false参数,表示禁用安全连接方式,解决警告提示
如果连接的是本机的mysql服务器,并且mysql服务默认端口是3306,则url可以简写为
jdbc:mysql:///数据库名称?参数键值对(去掉了IP号)
String username = "root" //数据库的账号
String password = "1234" //数据库的密码//获取连接对象
connection conn = DriverManager.getConnection(url,username,password)
3.定义SQL
String sql = "update testable set money = 2000 where id 1"
//定义SQL语句 testable为具体的数据表名
4.获取执行SQL的对象
Statement stmt = conn.createStatement();
5.执行SQL
int count = stmt.executeUpdate(sql)
//conut返回的是受影响的“行数”
为大于0的数字表示执行成功
否则为执行失败
6.处理结果
System.out.println(count); //打印受影响行数
7.释放资源
stmt.close();
conn.close();
示例代码
package JDBC;
import com.mysql.jdbc.Driver;
import java.sql.*;
import java.util.ArrayList;
public class teachingTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver"); //内部参数是固定的
//此行代码可有可无,因为 DriverManager中有代码块直接执行了注册程序
//获取连接
String url = "jdbc:mysql://127.0.0.1:3306/teaching"; //固定格式 jdbc:数据库类型://连接的数据库的ip:端口号/当前对应的数据库名字
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url,username,password);
//定义SQL语句
String sql = "SELECT * FROM student;";
// 查询语句
String sql1 = "update student set ssex = '男' where studentno = '193001' ";
// 修改student表中studentno为193001的字段修改ssex数据为男
String sql2 = "update student set ssex = '女' where studentno = '193002' ";
//获取执行SQL的对象
Statement stmt = conn.createStatement();
//执行SQL
ResultSet res = stmt.executeQuery(sql);
/* int count1 = stmt.executeUpdate(sql1);
int count2 = stmt.executeUpdate(sql2);
*/
//创建集合存储数据库中的数据
// ArrayList<student>
//遍历获取的数据
while(res.next()){
String studentno = res.getString(1);
String sname = res.getString(2);
String ssex = res.getString(3);
String sbirthday = res.getString(4);
String tc = res.getString(5);
String specialityno = res.getString(6);
System.out.println("学号:"+studentno+" "
+"姓名:"+sname+" "
+"性别:"+ssex+" "
+"出生日期:"+sbirthday+" "
+"学分:"+tc+" "
+"专业代码:"+specialityno);
}
//事务管理
//目的:多条SQL语句执行,但凡一条不成功都不成功
//把所有执行SQL的语句都设为事务
//所有SQL语句都执行成功后提交事务
//但凡一条SQL语句不成功则回滚事务
//用java的try...catch语句
try{
//开启事务---用连接开启事务
conn.setAutoCommit(false);
int count1 = stmt.executeUpdate(sql1);
System.out.println("受影响的行数"+count1);
//int i = 3/0; // 手动制造异常
int count2 = stmt.executeUpdate(sql2);
System.out.println("受影响的行数"+count2);
//提交事务
conn.commit();
}catch(Exception throwables){
//回滚事务
conn.rollback(); //出现异常时跳到此处执行此代码回滚事务
throwables.printStackTrace(); //打印异常
}
//返回执行结果
// System.out.println(res);
//释放资源
res.close(); //关闭结果集
stmt.close();
conn.close();
}
}