准备和资源
看的狂神说https://www.bilibili.com/video/BV1NJ411J79W?p=38
笔记参考https://blog.csdn.net/qq_33956536/article/details/107195051
mysql-connector-java文件下载http://mvnrepository.com/artifact/mysql/mysql-connector-java
commons-dbcp-1.4和commons-pool-1.6文件下载https://mvnrepository.com/artifact/commons-pool/commons-pool/1.6
————————————————
版权声明:本文为CSDN博主「断桨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42093700/article/details/116457517
sun 公司为了简化开发 人员的(对数据库的统一)操作,提供一个(Java操作数据库的)规范,俗称JDBC这些规范的实现由具体的厂商去做~
没有什么是加一层解决不了的
第一个JDBC程序
1.建立数据库
CREATE TABLE `student` (
`sid` int(4) NOT NULL,
`sname` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
`sage` int(2) DEFAULT NULL,
`classid` int(4) NOT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
2.创建项目
3.导入文件
3.1 在项目下创建lib文件夹,并放入 mysql-connector-java-8.0.16.jar
3.2 开启驱动
4. 测试代码
package le1;
import java.sql.*;
public class JdbcDemo01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver"); //固定写法
//2.用户信息和url
String url="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC";
String name="root";
String password="123456";
//3.连接成功,返回数据库对象,connection代表数据库
Connection connection = DriverManager.getConnection(url, name, password);
//4.执行SQL的对象statement
Statement statement = connection.createStatement();
//5.执行SQL的对象,去执行SQL 可能存在结果,查看返回结果
String sql="SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("sid:" + resultSet.getObject("sid") + "sname:" + resultSet.getObject("sname"));
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
}
}
步骤总结:
加载驱动——连接数据库(DriverManager)——获取执行SQL的对象(Statement)——获得返回结果集——释放连接
Statement对象详解
创建db.properties存储配置信息
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
username=root
password=123456
写工具类读取信息
package le2.utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JdbcUtils {
private static String driver=null;
private static String url=null;
private static String username=null;
private static String password=null;
static{
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver=properties.getProperty("driver");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
System.out.println(driver);
//驱动只需要加载一次
//Class.forName(driver);
Class.forName("com.mysql.jdbc.Driver");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
//释放连接资源
public static void release(Connection conn, Statement st,ResultSet rs){
if(rs!=null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
————————————————
版权声明:本文为CSDN博主「断桨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42093700/article/details/116457517
查询
package com.itheima;
import java.sql.*;
public class JDBCDemo {
public static void main(String[] args) throws SQLException {
//获得数据库对象connection
Connection connection = JDBCUtils.getConnection();
//获取sql执行对象:statement
Statement statement = connection.createStatement();
//执行sql
String sql = "select * from student";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("sid:" + resultSet.getObject("sid") + "sname:" + resultSet.getObject("sname"));
}
//释放连接
JDBCUtils.release(connection,statement,resultSet);
}
}
SQL注入问题
所谓SQL注入,就是通过把SQL命令插入到Web表单提交,最终达到欺骗服务器执行恶意的SQL命令。
程序示例:以SQL语句:select * from student where sname = ‘不存在的用户名’ or 1=1;为例
public class TestDemo1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.获取数据库连接
connection = JDBCUtils.getConnection();
//2.创建statement对象
statement = connection.createStatement();
//3.编写SQL语句
/*
如果输入数据库表单中有的用户名,可以获得正确的结果
如果输入不存在的用户名,查询会失败
如果输入select * from users where name = '不存在的用户名' or 1=1;
*/
System.out.print("请输入你要查询的用户名:");
String username = scanner.nextLine();
String sql = "select * from users where name =" +username;
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println(resultSet.getString("name"));
System.out.println(resultSet.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//5.释放资源
JDBCUtils.closeAll(resultSet,statement,connection);
}
}
}
" class="reference-link">运行结果:
02 PreparedStatement对象
PreperedStatement是Statement的子类,它的实例对象可以通过调用Connection.preparedStatement()方法获得
PreperedStatement可以解决SQL注入问题:PreparedStatement可对SQL进行预编译,从而提高数据库的执行效率。并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。
/*
preparedStatement的占位符:
preparedStatement.setXXX [xxx:对应占位符数据的类型] (?索引[从1开始] ,传入的值)
示例:
preparedStatement = connection.prepareStatement("select * from users where id = ?and name = ?");
preparedStatement.setInt(1,id);
preparedStatement.setString(1,username);
resultSet = preparedStatement.executeQuery();
*/
程序示例:
public class TestDemo2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//1.获取数据库连接
connection = JDBCUtils.getConnection();
//2.输入SQL语句
System.out.print("请输入你要查询的用户名:");
String username = scanner.nextLine();
//3.获取preparedStatement对象,预编译SQL语句
preparedStatement = connection.prepareStatement("select * from users where name = ?");
preparedStatement.setString(1,username);
//4.执行SQL语句
resultSet = preparedStatement.executeQuery();
//5.获取结果
while (resultSet.next()){
System.out.println(resultSet.getString("name"));
System.out.println(resultSet.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//6.释放资源
JDBCUtils.closeAll(resultSet,preparedStatement,connection);
}
}
}
运行结果:不能通过SQL注入获取用户名和密码。
03 PreparedStatement和statement的区别
**相同点 : **
都是用来执行sql语句的
不同点 :
Statement 不安全 , 不能预编译SQL , 不能使用占位符 , 容易造成SQL语句拼接错误,不能防止SQL注入攻击
preparedStatement 安全 ,可以防止SQL注入攻击,可以预编译SQL语句 , 可以使用 ?作为占位符 。
Statement 先写SQL语句再执行;
preparedStatement 直接编译SQL , 调用方法执行 ; preparedStatement.execute();
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明,KuangStudy,以学为伴,一生相伴!