Java Jdbc的详解
Posted 路宇
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Jdbc的详解相关的知识,希望对你有一定的参考价值。
一、Jdbc原理示意图
二、Jdbc的概述
三、JDBC的快速入门
代码如下,具体讲解在注释中已经说明
public class Jdbc01
public static void main(String[] args) throws SQLException
//前置工作:在项目下创建一个文件夹比如libs
//将mysql.jar拷贝到该目录下,点击add to project ..加入到项目
//1.注册驱动
Driver driver = new Driver();//创建Driver对象
//2.得到连接
//解读
//1.jdbc:mysql:// 规定好的协议,通过jdbc的方式连接mysql
//2.localhost 主机,可以是ip地址
//3.3306 表示sql监听的端口
//4.db_ly 连接到mysql dbms的哪个数据库
//5.mysql的连接本质就是socket连接
String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
//将用户名和密码放入到Properties对象
Properties properties = new Properties();
//说明 user 和 password 是规定好的,后面的值根据实际情况写
properties.setProperty("user", "root");//用户
properties.setProperty("password", "123456");//密码
Connection connect = driver.connect(url, properties);
//3.执行sql
// String sql = "insert into actor values(null,'刘德华','男','1970-01-01','110')" +
// ",(null,'周星驰','男','1980-01-03','123456789')";
String sql = "update actor set name='王宝强' where id = 3";
// String sql = "delete from actor where id =1";
//statement:用于执行静态的sql语句并返回其生成的结果对象
Statement statement = connect.createStatement();
//如果是dml语句,返回的就是影响行数
int rows = statement.executeUpdate(sql);
System.out.println(rows);
System.out.println(rows > 0 ? "成功" : "失败");
//4.关闭连接资源
statement.close();
connect.close();
输出结果如下
成功
四、Java操作数据库需要获得Connection连接,获取Connection连接的五种方式如下
public class JdbcConn
//方式1
@Test
public void connect01() throws SQLException
//1.注册驱动
Driver driver = new Driver();//创建Driver对象
String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
//将用户名和密码放入到Properties对象
Properties properties = new Properties();
//说明 user 和 password 是规定好的,后面的值根据实际情况写
properties.setProperty("user", "root");//用户
properties.setProperty("password", "123456");//密码
Connection connect = driver.connect(url, properties);
System.out.println(connect);
//方式2
@Test
public void connect02() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException
//使用反射获取Driver类,动态加载,更加的灵活,减少依赖性
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
//将用户名和密码放入到Properties对象
Properties properties = new Properties();
//说明 user 和 password 是规定好的,后面的值根据实际情况写
properties.setProperty("user", "root");//用户
properties.setProperty("password", "123456");//密码
Connection connect = driver.connect(url, properties);
System.out.println(connect);
//方法3 使用DriverManager 替代driver 进行统一管理
@Test
public void connect03() throws IllegalAccessException, InstantiationException, ClassNotFoundException, SQLException
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
Driver driver = (Driver) aClass.newInstance();
//创建url和user的password
String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
String user = "root";
String password = "123456";
//注册driver驱动
DriverManager.registerDriver(driver);
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("第三种方式:" + connection);
//方式4:使用Class.forName() 自动完成注册驱动,简化代码
//这种方式获取连接是使用的最多的,推荐使用
@Test
public void connect04() throws ClassNotFoundException, SQLException
//使用反射加载了Driver类
//在加载Driver类时,完成注册
/*
源码:1.静态代码块,在类加载时,会执行一次
2. DriverManager.registerDriver(new Driver());
3.因此注册driver的工作已经完成
static
try
DriverManager.registerDriver(new Driver());
catch (SQLException var1)
throw new RuntimeException("Can't register driver!");
*/
Class.forName("com.mysql.cj.jdbc.Driver");
//创建url和user的password
String url = "jdbc:mysql://localhost:3306/db_ly?serverTimezone=GMT";
String user = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("第四种方式:" + connection);
//方式5:在方式4的基础上改进,增加配置文件,让连接mysql更加灵活
@Test
public void connect05() throws IOException, ClassNotFoundException, SQLException
//通过Properties,获取相关配置文件的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\\\mysql.properties"));
//获取相关的值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
Class.forName(driver);
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println("第五种方式:" + connection);
输出结果
com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
第三种方式:com.mysql.cj.jdbc.ConnectionImpl@7f77e91b
第四种方式:com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
第五种方式:com.mysql.cj.jdbc.ConnectionImpl@1a38c59b
四、ResultSet的详解
对应的代码如下
@SuppressWarnings("all")
public class ResultSet_
public static void main(String[] args) throws Exception
//通过Properties配置相关信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\\\mysql.properties"));
//获取相关的值
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//建立与给定数据库的url连接
//2.建立连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.得到Statement
Statement statement = connection.createStatement();
//4.组织sql
String sql = "SELECT id,name,sex,borndate,phone FROM ACTOR";
//执行给定的SQL语句,该语句返回单个 ResultSet对象。
/*
+----+--------+-----+---------------------+-----------+
| id | NAME | sex | borndate | phone |
+----+--------+-----+---------------------+-----------+
| 1 | 刘德华 | 男 | 1970-01-01 00:00:00 | 110 |
| 2 | 王宝强 | 男 | 1980-01-03 00:00:00 | 123456789 |
+----+--------+-----+---------------------+-----------+
*/
/*
resultSet对象的结构,debug进行阅读
查询到的数据,底层使用byte[] 数组存的,比如id =1 存放的1对应的ASCII码49
*/
ResultSet resultSet = statement.executeQuery(sql);
//5.使用while取出数据
while (resultSet.next()) //让光标向后移动,如果没有更多行,则返回false
// int id = resultSet.getInt(1);//获取该行的第一列数据
int id = resultSet.getInt("id");//通过列名来获取值,推荐使用
String name = resultSet.getString(2);//获取该行第二列
String sex = resultSet.getString(3);//获取该行第三列
Date date = resultSet.getDate(4);//获取该行第四列
String phone = resultSet.getString(5);//获取该行第五列
System.out.println(id + "\\t" + name + "\\t" + sex + "\\t" + date + "\\t" + phone);
//6.关闭连接
resultSet.close();
statement.close();
connection.close();
输出结果
1 刘德华 男 1970-01-01 110
2 王宝强 男 1980-01-03 123456789
resultSet对象的结构如下
Statement的介绍
使用Statement会存在SQL注入的风险,所以开发中一般使用PreparedStatement。
SQL注入演示:
CREATE TABLE ADMIN(
NAME VARCHAR(32) NOT NULL UNIQUE,
pwd VARCHAR(32) NOT NULL DEFAULT ''
);
INSERT INTO ADMIN VALUES('jack','123456');
SELECT * FROM ADMIN WHERE NAME='jack' AND pwd = '12456';
-- name 输入 1'or
-- pwd 输入or '1'='1
-- 条件'1'='1' 永远成立 能查到数据库中的数据,JAVA程序在拼接的时候就发生了SQL注入
SELECT * FROM ADMIN
WHERE NAME='1'or' AND pwd = 'or '1'='1';
下面演示使用Statement会发生SQL注入的风险
public class Statement_
public static void main(String[] args) throws Exception
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.println("请输入管理员的名字:");//next():当接收到空格或者 '就是表示结束
String admin_name = scanner.nextLine();//如果希望看到SQL注入效果,这里需要nextLine() 这个回车才表示结束
System.out.println("请输入管理员的密码:");
String admin_pwd = scanner.nextLine();
//通过Properties配置相关信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\\\mysql.properties"));
//获取相关的值
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//建立与给定数据库的url连接
//2.建立连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.得到Statement
Statement statement = connection.createStatement();
//4.组织sql
String sql = "SELECT NAME,pwd FROM ADMIN WHERE NAME='" + admin_name + "' AND pwd= '" + admin_pwd + "'";
ResultSet resultSet = statement.executeQuery(sql);
if (resultSet.next()) //如果查询到一条记录,则说明该管理存在
System.out.println("恭喜登录成功!");
else
System.out.println("登录失败!");
//关闭连接
resultSet.close();
statement.close();
connection.close();
输出结果如下
请输入管理员的名字:
1'or
请输入管理员的密码:
or '1'='1
恭喜登录成功!
五、PrepareStatement的介绍与使用
PrepareStatement的好处
1、下面是演示代码,解决了SQL注入的问题
public class PrepareStatement_
public static void main(String[] args) throws Exception
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.println("请输入管理员的名字:");//next():当接收到空格或者 '就是表示结束
String admin_name = scanner.nextLine();//如果希望看到SQL注入效果,这里需要nextLine() 这个回车才表示结束
System.out.println("请输入管理员的密码:");
String admin_pwd = scanner.nextLine();
//通过Properties配置相关信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\\\mysql.properties"));
//获取相关的值
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//建立与给定数据库的url连接
//2.建立连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.组织sql语句,sql语句的? 就相当于占位符
String sql = "SELECT name,pwd FROM ADMIN WHERE name=? AND pwd=?";
//4.得到preparedStatement
//preparedStatement对象是实现了PreparedStatement接口的实现类对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//给?赋值
preparedStatement.setString(1, admin_name);
preparedStatement.setString(2, admin_pwd);
//执行select语句,使用executeQuery()
//如果执行的是dml(update,insert,delete) 使用executeUpdate()
//这里执行executeQuery,不要写sql
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) //如果查询到一条记录,则说明该管理存在
System.out.println("登录成功!");
else
System.out.println("登录失败!");
//关闭连接
resultSet.close();
preparedStatement.close();
connection.close();
输出结果
请输入管理员的名字:
1 'or
请输入管理员的密码:
or '1'='1
登录失败!
2、使用PrepareStatement进行DML操作
public class PrepareStatement_DML
public static void main(String[] args) throws Exception
Scanner scanner = new Scanner(System.in);
//让用户输入管理员名和密码
System.out.println("请输入要删除的管理员的名字:");//next():当接收到空格或者 '就是表示结束
String admin_name = scanner.nextLine();//如果希望看到SQL注入效果,这里需要nextLine() 这个回车才表示结束
// System.out.println("请输入管理员的密码:");
// String admin_pwd = scanner.nextLine();
//通过Properties配置相关信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\\\mysql.properties"));
//获取相关的值
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String driver = properties.getProperty("driver");
//1.注册驱动
Class.forName(driver);
//建立与给定数据库的url连接
//2.建立连接
Connection connection = DriverManager.getConnection(url, user, password);
//3.组织sql语句,sql语句的? 就相当于占位符
//添加记录
// String sql = "insert into admin values(?,?)";
//修改记录
// String sql = "update admin set name=? where pwd=?";
//删除记录
String sql = "delete from admin where name=?";
//4.得到preparedStatement
//preparedStatement对象是实现了PreparedStatement接口的实现类对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//给?赋值
preparedStatement.setString(1, admin_name);
// preparedStatement.setString(2, admin_pwd);
//如果执行的是dml(update,insert,delete) 使用executeUpdate()
int rows = preparedStatement.executeUpdate();
System.out.println(rows > 0 ? "执行成功" : "执行失败");
//关闭连接
preparedStatement.close();
connection.close();
输出结果
请输入要删除的管理员的名字:
smith
执行成功
以上是关于Java Jdbc的详解的主要内容,如果未能解决你的问题,请参考以下文章