首页 > 数据库 > JavaWeb--JDBC:概述,DriverManager,Connection,Statement,ResultSet,PreparedStatement、数据库连接池--2022年9月23日

JavaWeb--JDBC:概述,DriverManager,Connection,Statement,ResultSet,PreparedStatement、数据库连接池--2022年9月23日

时间:2022-09-25 10:58:36浏览次数:67  
标签:DriverManager JDBC String -- sql mysql SQL password conn

第一节   JDBC概述

  1、JDBC概念

    JDBC就是使用java语言操作关系数据库的一套API

    全称:(Java DataBase Connectivity)Java数据库连接

  2、JDBC本质

    官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口

    各个数据库厂商去实现这套接口,提供数据库驱动jar包,其实就是实现类

    我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

    

    

  3、JDBC好处

    各数据厂商使用相同的接口,Java代码不需要针对不同数据库分别开发

    可随时替换底层数据库,访问数据库的Java代码基本不变

    

第二节    JDBC快速入门

  1、Java操作数据库的流程

    

  2、编写代码步骤

    A、创建工程,导入驱动jar包

    B、注册驱动:Class.forName("com.mysql.jdbc.Driver");//把这个类加载进内存

    C、获取连接:Connection conn = DriverManager.getConnection(url,username,password);//Java代码需要发送SQL给MySQL服务端,就需要先建立连接

    D、定义SQL语句:String sql = "update.....";

    E、获取执行SQL对象:statement stmt = conn.createStatement();//执行SQL语句需要SQL执行对象,而这个执行对象就是Statement对象

    F、执行SQL:stmt.executeUpdate(sql);

    G、处理返回结果

    H、释放资源

    示例

/**
* JDBC快速入门
*/
public class JDBCDemo {
public static void main(String[] args) throws
Exception {
//1. 注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接
String url =
"jdbc:mysql://127.0.0.1:3306/db1";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
//3. 定义sql
String sql = "update account set money =
2000 where id = 1";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5. 执行sql
int count = stmt.executeUpdate(sql);//受影响
的行数
//6. 处理结果
System.out.println(count);
//7. 释放资源
stmt.close();
conn.close();
}
}

第三节   JDBC-API详解

  1、DriverManager(驱动管理类)

    A、注册驱动

      Class.forName("com.mysql.jdbc.Driver");

      之前的入门案例,注册驱动是上面这么写的,但其实DriverManager类也提供了一个方法可以注册驱动:static void registerDriver(Driver driver)--使用DriverManager注册给定的驱动程序

      

 

 

       

    B、获取数据库连接--参数说明

      static Connection getConnection(String url,String user,String password)--尝试建立与给定数据库URL的连接

      url:连接路径

        

 

 

       user:用户名

      password:密码

  2、Connection(数据库连接对象)

    A、Connection作用

      获取执行SQL的对象

      管理事务

    B、获取执行对象

      普通执行对象:Statement createStatement()

      预编译SQL的执行SQL对象,防止SQL注入:PreparedStatement prepareStatement(sql)

      执行存储过程的对象:CallableStatement prepareCall(sql)

    C、事务管理

      JDBC事务管理的方法:

      void setAutoCommit(boolean autoCommit)--参与autoCommit表示是否自动提交事务,true表示自动提交事务,false表示手动提交事务。所以开启事务需将参数设置为false

      void commit()--提交事务

      void rollback()--回滚事务

/**
* JDBC API 详解:Connection
*/
public class JDBCDemo3_Connection {
public static void main(String[] args) throws
Exception {
//1. 注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接:如果连接的是本机mysql并且端口是默认
的 3306 可以简化书写
String url = "jdbc:mysql:///db1?
useSSL=false";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
//3. 定义sql
String sql1 = "update account set money =
3000 where id = 1";
String sql2 = "update account set money =
3000 where id = 2";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
try {
// ============开启事务==========
conn.setAutoCommit(false);
//5. 执行sql
int count1 = stmt.executeUpdate(sql1);//
受影响的行数
//6. 处理结果
System.out.println(count1);
int i = 3/0;
//5. 执行sql
int count2 = stmt.executeUpdate(sql2);//
受影响的行数
//6. 处理结果
System.out.println(count2);
// ============提交事务==========
//程序运行到此处,说明没有出现任何问题,则需求提
交事务
conn.commit();
} catch (Exception e) {
// ============回滚事务==========
//程序在出现异常时会执行到这个地方,此时就需要回
滚事务
conn.rollback();
e.printStackTrace();
}
//7. 释放资源
stmt.close();
conn.close();
}
}

  3、Statement对象:执行SQL语句

    A、执行DDL、DML语句:int executeUpdate(String sql)

    B、执行DQL语句:ResultSet executeQuery(String sql)

    执行DML语句

/**
* 执行DML语句
* @throws Exception
*/
@Test
public void testDML() throws Exception {
//1. 注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接:如果连接的是本机mysql并且端口是默认的
3306 可以简化书写
String url = "jdbc:mysql:///db1?
useSSL=false";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
//3. 定义sql
String sql = "update account set money = 3000
where id = 1";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5. 执行sql
int count = stmt.executeUpdate(sql);//执行完
DML语句,受影响的行数
//6. 处理结果
//System.out.println(count);
if(count > 0){
System.out.println("修改成功~");
}else{
System.out.println("修改失败~");
}
//7. 释放资源
stmt.close();
conn.close();
}

    执行DQL语句

/**
* 执行DDL语句
* @throws Exception
*/
@Test
public void testDDL() throws Exception {
//1. 注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接:如果连接的是本机mysql并且端口是默认的3306 可以简化书写
String url = "jdbc:mysql:///db1?
useSSL=false";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
//3. 定义sql
String sql = "drop database db2";
//4. 获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5. 执行sql
int count = stmt.executeUpdate(sql);//执行完
DDL语句,可能是0
//6. 处理结果
System.out.println(count);
//7. 释放资源
stmt.close();
conn.close();
}

  4、ResultSet

    A、作用:封装了SQL查询语句的结果:ResultSet executeQuery(sql)--执行SQL语句,返回ResultSet对象

    B、ResultSet对象提供的操作查询结果的方法:

    

 

 

     

 

 

     C、实现代码

/**
* 执行DQL
* @throws Exception
*/
@Test
public void testResultSet() throws Exception {
//1. 注册驱动
//Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接:如果连接的是本机mysql并且端口是默认的
3306 可以简化书写
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
//3. 定义sql
String sql = "select * from account";
//4. 获取statement对象
Statement stmt = conn.createStatement();
//5. 执行sql
ResultSet rs = stmt.executeQuery(sql);
//6. 处理结果, 遍历rs中的所有数据
/* // 6.1 光标向下移动一行,并且判断当前行是否有数据
while (rs.next()){
//6.2 获取数据 getXxx()
int id = rs.getInt(1);
String name = rs.getString(2);
double money = rs.getDouble(3);
System.out.println(id);
System.out.println(name);
System.out.println(money);
System.out.println("--------------");
}*/
// 6.1 光标向下移动一行,并且判断当前行是否有数据
while (rs.next()){
//6.2 获取数据 getXxx()
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id);
System.out.println(name);
System.out.println(money);
System.out.println("--------------");
}
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}

  5、PreparedStatement

    A、PreparedStatement作用:

      预编译SQL语句并执行:预防SQL注入问题

    B、SQL注入

      SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法

    C、代码模拟SQL注入问题

@Test
public void testLogin() throws Exception {
//2. 获取连接:如果连接的是本机mysql并且端口是默认的
3306 可以简化书写
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
// 接收用户输入 用户名和密码
String name = "sjdljfld";
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where
username = '"+name+"' and password = '"+pwd+"'";
// 获取stmt对象
Statement stmt = conn.createStatement();
// 执行sql
ResultSet rs = stmt.executeQuery(sql);
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}

    

    D、获取PreparedStatement对象

// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username =
? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt =
conn.prepareStatement(sql);

    E、设置参数值

    

 

     F、执行SQL语句

    

    G、使用PreparedStatement改进

@Test
public void testPreparedStatement() throws
Exception {
//2. 获取连接:如果连接的是本机mysql并且端口是默认的
3306 可以简化书写
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
// 接收用户输入 用户名和密码
String name = "zhangsan";
String pwd = "' or '1' = '1";
// 定义sql
String sql = "select * from tb_user where
username = ? and password = ?";
// 获取pstmt对象
PreparedStatement pstmt =
conn.prepareStatement(sql);
// 设置?的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
// 执行sql
ResultSet rs = pstmt.executeQuery();
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
//7. 释放资源
rs.close();
pstmt.close();
conn.close();
}

    执行上面语句就可以发现不会出现SQL注入漏洞问题了。那么PreparedStatement又是如何解决的呢?它是将特殊字符进行了转义,转义的SQL如下

    

 

     H、PreparedStatement原理

    

 

     上图解释:

      将sql语句发送到MySQL服务器端

      MySQL服务端会对sql语句进行如下操作

        检查SQL语句,检查SQL语句的语法是否正确

        编译SQL语句。将SQL语句编译成可执行的函数。检查SQL和编译SQL花费的时间比执行SQL的时间还要长。如果我们只是重新设置参数,那么检查SQL语句和编译SQL语句将不需要重复执行,这样就提高了性能。

        执行SQL语句

    I、可通过查询日志看一下原理

    

 

     测试代码如下:

/**
* PreparedStatement原理
* @throws Exception
*/
@Test
public void testPreparedStatement2() throws
Exception {
//2. 获取连接:如果连接的是本机mysql并且端口是默认的
3306 可以简化书写
// useServerPrepStmts=true 参数开启预编译功能
String url = "jdbc:mysql:///db1?
useSSL=false&useServerPrepStmts=true";
String username = "root";
String password = "1234";
Connection conn =
DriverManager.getConnection(url, username,
password);
// 接收用户输入 用户名和密码
String name = "zhangsan";
String pwd = "' or '1' = '1";
// 定义sql
String sql = "select * from tb_user where
username = ? and password = ?";
// 获取pstmt对象
PreparedStatement pstmt =
conn.prepareStatement(sql);
Thread.sleep(10000);
// 设置?的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
ResultSet rs = null;
// 执行sql
rs = pstmt.executeQuery();
// 设置?的值
pstmt.setString(1,"aaa");
pstmt.setString(2,"bbb");
// 执行sql
rs = pstmt.executeQuery();
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
//7. 释放资源
rs.close();
pstmt.close();
conn.close();
}

    

第四节   数据库连接池

  1、数据库连接池简介

    数据库连接池是个容器,负责分配、管理数据库连接(Connection)

    它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

    释放空闲时间长超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏

    好处:1.资源重用  2.提升系统响应速度  3.避免数据库连接遗漏

  2、数据库连接池实现

  

  3、常见的数据库连接池

    DBCP

    C3P0

    Druid--德鲁伊(目前使用更多,性能比上面两个要好)

      Druid连接池是阿里巴巴开源的数据库连接池项目

      功能强大,性能优秀,是Java语言最好的数据库连接池之一

  4、Druid使用

    导入jar包 druid-1.1.12.jar

    定义配置文件

    加载配置文件

    获取数据库连接池对象

    获取连接

配置文件如下
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///db1? useSSL=false&useServerPrepStmts=true username=root password=1234 # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000
/**
* Druid数据库连接池演示
*/
public class DruidDemo { public static void main(String[] args) throws Exception { //1.导入jar包 //2.定义配置文件 //3. 加载配置文件 Properties prop = new Properties(); prop.load(new FileInputStream("jdbcdemo/src/druid.properties")); //4. 获取连接池对象 DataSource dataSource = DruidDataSourceFactory.createDataSource(prop); //5. 获取数据库连接 Connection Connection connection = dataSource.getConnection(); System.out.println(connection); //获取到了连接 后就可以继续做其他操作了 //System.out.println(System.getProperty("user.dir") ); } }

标签:DriverManager,JDBC,String,--,sql,mysql,SQL,password,conn
From: https://www.cnblogs.com/Flower--Dance/p/16723282.html

相关文章

  • 三次握手和四次挥手详解
    1.三次握手原理1.1为什么需要三次握手,两次不行吗?1.2什么是半连接队列?1.3ISN(InitialSequenceNumber)是固定的吗?1.4三次握手过程中可以携带数据吗?1.5SYN攻击是什......
  • 我们对 HTML 和其他可访问性更改的首次研究
    我们对HTML和其他可访问性更改的首次研究本周,我重温了我的青春时光,并与一些新学徒一起参加了卡迪夫的Fresher'sFayre。尽管感觉自己已经100岁左右,但我还是设法吃到......
  • Linux 安装 JDK
    Linux安装JDK1.上传jdk-8u141-linux-x64.tar.gz安装包#创建文件夹[root@node-01~]#mkdirapps#解压安装包[root@node-01~]#tar-xzvfjdk-8u141-linux-x6......
  • 大三上学期学习日记2
    1.在node1输入start-all.sh2.在node1node2node3上都输入/export/server/zookeeper/bin/zkServer.shstart3.在node1上输入nohup/export/server/hive/bin/hive--servicem......
  • 分区数量与reduce个数怎样才能不报错
    reduce数量只能是1个或者比分区的数量多,否则数据写入会出现问题报错。因为系统有自带的方法,也可以自定义,如果自定义就跑自定义的方法,是1就用系统默认的。大于的时候会产......
  • COBBLER
    COBBLERcobbler目录cobbler[cobler部署]设置服务开机自启[web界面自动安装]COBLER部署部署yum源和epel源#yum源[root@localhost~]#cd/etc/yum.repos.......
  • Spring(九):Bean的自动装配
    一、Bean装配的方式在Spring中Bean有三种装配的方式:1.在xml中显式的配置。2.在java中显式的配置。3.隐式的自动装配。前面我们一直在用的都是第一种xml中的配置,这里我......
  • 03 MyBatis自定义映射
    一、MyBatis环境搭建1.1、数据的准备CREATEDATABASEIFNOTEXISTSdb_test;USEdb_test;CREATETABLEIFNOTEXISTSt_emp( emp_idintPRIMARYKEYauto_increme......
  • 程序员修炼之道 从小工到专家 二
    第二章注重实效的途径7、重复的危害系统中的每一项知识都必须具有单一、无歧义、权威的表示。不要重复你自己。我们所见到的重复一般有加强的重复,无意义的重复,无耐性的......
  • Java踩坑
    一.基础关键字与标识符,一般全小写的就是关键字命名规则硬性规范标识符包含英文字母26个(区分大小写),0-9数字,$(美元符号)和_下划线标识符不能以数字开头标识符不能......