JDBC
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC相关的知识,希望对你有一定的参考价值。
1、什么是jdbc
java database Connector java与数据库的连接器
一套接口,是java代码与数据库的桥梁
2、重要接口和类
1)java.sql.Connection (连接接口--代表了java代码与数据库服务器之间的连接)
2)java.sql.Statement (语句接口--代表了语句对象,可以用来执行各种sql)
3)java.sql.ResultSet (结果集接口--代表查询结果)
4)DriverManager (驱动管理器) 辅助类 -- 获取Connection连接
5)java.sql.Driver (驱动接口)
6)java.sql.SQLException 检查异常, 需要处理
###3
1) 加载驱动 (在新版的jdbc中可以省略此步骤)只需要执行一次即可
Class.forName("com.mysql.jdbc.Driver");// mysql 5.1
Class.forName("com.mysql.cj.jdbc.Driver"); // mysql 8.8
2) 创建连接,创建Connection对象
// jdbc:mysql: 称为连接协议
// localhost: mysql服务器的ip地址 连接本电脑用 localhost
// 3306: 连接端口号
// test3: 数据库名称
// serverTimezone=GMT%2B8 设置连接时区与数据库服务器一致 (连接8.0 mysql时新增 )
String url = "jdbc:mysql://localhost:3306/test3?serverTimezone=GMT%2B8&useSSL=false"; // 数据库的连接字符串
String username="root"; // 数据库用户名
String password="root"; // 数据库的密码(自己定义的数据库密码)
以上三个定义可以写在工具类中方便以后的使用
Connection conn = DriverManager.getConnection(url, username, password);
常见问题:
(1):在连接过程中一旦发生异常:java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed
需要添加allowPublicKeyRetrieval=true
参数,此异常一种可能的发生情况是MySQL服务重启后,立刻用jdbc连接时
(2):不写 serverTimezone=GMT%2B8`参数,否则会出现异常:java.sql.SQLException: The server time zone value ‘?D1ú±ê×?ê±??‘,
另外`GMT%2B8`也必须加 ,否则会出现连接方和数据库时区不一致问题
(3):WARN: Establishing SSL connection without server‘s identity verification is not recommended
要消除这个警告信息,需要加入参数`useSSL=false 参数之间连接用&
3) 创建Statement 对象
Statement stmt = conn.createStatement();
4) 执行sql语句(执行增删改或查询)
stmt.executeUpdate(sql) // 用来执行 insert, update, delete 返回结果是int 类型 表示影响的行数
stmt.executeQuery(sql) // 用来执行 select
stmt.execute(sql) //都可以执行
返回值是boolean类型 如果执行了增删改,返回false, 如果执行的是查询,那么返回true,
5)结果集
ResultSet rs = stmt.executeQuery(sql);
rs.next();返回的是boolean值表示是否有下一条记录
next()方法用来移动到下一行记录 getXXX方法用来获取某列数据
while (rs.next()) {
int sid = rs.getInt(1); //(1) 代表从第几行开始
String sname = rs.getString(2);
Date birthday = rs.getDate(3);
String sex = rs.getString(4);
}
情况1: getXXX(int 列下标) 用来获取结果集中某一列的数据,其中XXX为数据类型,如果是字符串使用 getString 如果是整数,使用getInt ... ,列下标从1开始
情况2: getXXX(int 列名) 用来获取结果集中某一列的数据,其中XXX为数据类型,如果是字符串使用 getString 如果是整数,使用getInt
如:int deptno = rs.getInt("deptno");
String dname = rs.getString("dname");
String loc = rs.getString("loc");
6) 关闭资源 先打开的后关闭
rs.close(); // 关闭ResultSet
stmt.close(); // 关闭Statement对象
conn.close(); // 关闭数据库连接
###4 获取自增列的值 Statement.RETURN_GENERATED_KEYS 代表自增的值
Statement stmt = conn.createStatement();
String sql = "insert into student(sid,sname,birthday,sex) values (null,‘XXX‘,‘1999-1-1‘,‘男‘)";
stmt.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
rs.next();
System.out.println(rs.getInt(1));
###5 sql 注入×××问题
问题: Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
Statement stmt = conn.createStatement();
// 拼接字符串的办法生成了sql语句
String sql = "select * from user where username=‘" +username+"‘ and password=‘"+password+"‘";
如果结果为:String password = "‘ or ‘1=1"; 会与之匹配从而登录成功
解决方法: // PreparedStatement 预编译的Statement ,可以避免SQL注入×××漏洞
// 让代码的可读性更好
Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
// sql语句是预先准备好的, 用?作为值的占位符
String sql = "select * from USER where username=? and password=?";
PreparedStatement stmt = conn.prepareStatement(sql);
// 给sql语句中的? 赋值
stmt.setString(1, username); // 将username变量赋值给sql语句中第一个?, ?下标从1开始
stmt.setString(2, "aaa‘ or ‘1‘=‘1"); // 会将整个值当做一个整体,把or当做了值而不是关键字
ResultSet rs = stmt.executeQuery();; // 会将sql语句以及通过set方法设置的参数值,一起发送给数据库服务器
例: public static boolean login2(String deptno,String dname) {
Connection conn = null;
PreparedStatement pre = null;
ResultSet rst =null;
try {
conn = DriverManager.getConnection(URL, username, password);
String sql = "select * from emp where deptno=?and ename=?" ;
pre = conn.prepareStatement(sql);
pre.setString(1, deptno);
pre.setString(2, dname);
rst = pre.executeQuery();
if(rst.next()){
return true;
}else{
return false;
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("失败",e); //无返回值抛出异常
}finally {
if(rst!=null){
try {
rst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pre!=null){
try {
pre.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
以上是关于JDBC的主要内容,如果未能解决你的问题,请参考以下文章