卖不甜枣 发表于 2024-6-20 18:13:17

JDBC教程:JDBC毗连Mysql数据库超具体解说(从入门到纯熟使用)

JDBC

1.概念:



[*]【 Java DataBase Connectivity 】,Java数据库毗连
[*]即 ,JDBC的作用是:用Java语言操作数据库
2.本质:



[*] 官方定义的一套操作所有关系型数据库的规则/规范( 即接口-- API(Application Programming Interface ))
[*] 且由关系型数据库厂商本身写JDBC的实现类,实现这套接口(数据库驱动)
[*] 真正实行的代码是驱动jar包中的实现类
3.快速入门

步调


[*] 导入驱动jar包
https://img-blog.csdnimg.cn/direct/8106e66068754c7faaacb4c22e14c625.png#pic_center
                                 图1--查看MySQL版本
https://img-blog.csdnimg.cn/direct/7e943b994f754d3b911f7f2d21f03f27.png#pic_center
                              图2---到官网下载对应版本的jar包
       https://downloads.mysql.com/archives/c-j/ 是旧版本 页面有所不同
    MySQL :: Download Connector/J 附上最新版下载所在
    https://img-blog.csdnimg.cn/direct/414564f8856f4f429260379674492699.png#pic_center
                                     图3---直接下载无需登录注册Oracle官网账号


[*] 在src中新建libs包
[*] 复制mysql-connector-java-8.0.26.jar 到项目libs目次下
https://img-blog.csdnimg.cn/direct/5f6ac0169da94cfb891d387e60bbb0ac.png#pic_center
https://img-blog.csdnimg.cn/direct/f5b71aa530574fc89e4ef3db1a5696d2.png#pic_center
https://img-blog.csdnimg.cn/direct/1097f7b9f7c7428798be129ef27db5fd.png#pic_center
                           图4.图5.图6--复制jar包并粘贴

[*] 右键—>add as library(添加为库)
https://img-blog.csdnimg.cn/direct/20e42f34252c4a3ea4ea148b5d43df79.png#pic_center
                                     图7--添加为库


[*] 注册驱动
Class.forName("com.mysql.jdbc.Driver");
https://img-blog.csdnimg.cn/direct/f365eef2ebaf4ea38fa8886c8739dceb.png#pic_center
https://img-blog.csdnimg.cn/direct/1c920fe53d0442bb96655a2b98f50e99.png#pic_center
https://img-blog.csdnimg.cn/direct/a898636292aa46c1b457eec5f83fb507.png#pic_center
注:需要抛出非常(如图)
   使用throws Exception取代具体的非常类型(如throws ClassNotFoundException)

[*] 获取数据库毗连对象 Connection
create database JDBC_study;
use JDBC_study;
create table account
(
    id      int auto_increment primary key ,
    name    varchar(10) null,
    balance double      null
);
https://img-blog.csdnimg.cn/direct/5176b184df6c44a191e27466e4c3f222.png#pic_center
​ 图8–提前准备的数据表
Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBC_study");
//JDBC_study是我的数据库名
   MySQL 8.0 以上版本的数据库毗连:

[*] com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver
[*] jdbc:mysql://localhost:3306/数据库名更换为jdbc:mysql://localhost:3306/数据库名?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC

[*] 定义sql语句
String sql="update account set balance =500 where id=1";

[*] 获取实行sql语句的对象 statement
Statement statement =connection.createStatement();

[*] 实行sql,接收返回结果
int count=statement.executeUpdate(sql);

[*] 处置惩罚结果
System.out.println(count);//

[*] 开释资源
statement.close();
connection.close();

   完整代码:
/*JDBC快速入门*/public class jdbcDemo1 { public static void main(String[] args) throws Exception {//      1. 导入驱动jar包(已完成)//      2. 注册驱动   Class.forName("com.mysql.cj.jdbc.Driver");//可省略//      3. 获取数据库毗连对象 Connection                //第二、三个参数是毗连数据库的用户名和密码                        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", "root", "Hky6600115");//      4. 定义sql语句   String sql="update account set balance =500 where id=1";
//      5. 获取实行sql语句的对象 statement   Statement statement =connection.createStatement();
//      6. 实行sql,接收返回结果   int count=statement.executeUpdate(sql);
//      7. 处置惩罚结果   System.out.println(count);//
      8. 开释资源   statement.close();   connection.close(); }}运行查验:
https://img-blog.csdnimg.cn/direct/3903b52208c042a98a39898f24ea68b6.png#pic_center
                                 图9--控制台输出(暂时不解读)
https://img-blog.csdnimg.cn/direct/9798e4f46ae548eb9b770c6afc1030c6.png#pic_center
                                 图10--刷新数据库可见数据已修改

详解各对象

1️⃣.DriverManager 驱动管理对象

【一个类】
功能:


[*] 一、注册驱动:告诉程序应当使用哪一个数据库去驱动jar包

[*] static void registerDriver(Driver driver) DriverManager 的方法
         上面快速入门的时候没有注册驱动 ,取而代之的是Class.forName(“com.mysql.jdbc.Driver”)也乐成运行,原因如下:
[*] 查看mysql.jdbc.Driver的源码可知
//这是com.mysql.jdbc.Driver的静态代码块,只要使用这个类,就会执行这段代码
//而Class.forName("com.mysql.jdbc.Driver")就正好使用到了这个类
static {
        try {
                java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
                throw new RuntimeException("Can't register driver!");
        }
}
因此,我们是通过给forName指定了MySQL的驱动,它帮助我们注册驱动
[*] 注意:MySQL5.0之后可以省略注册驱动的步调
         在jar包中,存在一个java.sql.Driver设置文件,文件中指定了com.mysql.jdbc.Driver

[*] 二、获取数据库毗连

[*] 方法:static Connection getConnection(String url, String user, String password); 带三个参数
[*] 参数:

[*] url:指定毗连的路径

[*] 语法:jdbc:mysql://ip所在(域名):端口号/数据库名称【MySQL5.0写法】
[*] 语法:jdbc:mysql://ip所在(域名):端口号/JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC【MySQL8.0写法】
                   ip所在(域名)可以找到某一台盘算机
          端口号可以找到盘算机上安装的MySQL服务器
[*] 细节:若毗连的是本机mysql服务器,而且mysql服务默认端口是3306,则url可以简写为jdbc:mysql:///数据库名称【MySQL5.0写法】,即省略 ip所在(域名):端口号

[*] user:用户名(本机常为root)
[*] password:密码



2️⃣. Connection 数据库毗连对象

功能:


[*] 一、获取实行sql的对象

[*]获取普通实行者对象:Statement createStatement();
[*]获取预编译实行者对象:PreparedStatement prepareStatement(String sql);

[*] 二、管理事件
       业务操作的多个步调:要么同时乐成,要么同时失败
    数据库可以:开启/提交/回滚事件,针对此有以下三个对应方法:

[*]开启事件:setAutoCommit(boolean autoCommit); 参数为false,则开启事件
[*]提交事件:commit();
[*]回滚事件:rollback();


3️⃣.statement 实行sql的对象⭐

功能:
实行sql对象


[*] boolean execute(String sql); 可以实行任意sql语句(相识即可)
[*] int executeUpdate(String sql); 实行DML(insert、update、delete)语句以及DDL(create、alert、drop)

[*] 返回值:影响的行数
[*] eg. 前面运行过的,原先的表格经修改,id=1的balance由1000酿成500,则这一行数据受到影响被改变返回值为1(见图9)
   idnamebalance1zhangsan1000---->5002lisi1000
[*] 作用:可以通过这个影响的行数判定DML语句是否实行乐成 返回值>0的则实行乐成;反之,则失败

[*] ResultSet executeQuery(String sql); 实行DQL(select)

练习:基础

1.accunt表 添加一条记载
2.account表 修改记载
3.account表 删除一条记载
import java.sql.*;/*1.accunt表 添加一条记载 */public class jdbcDemo2 {    public static void main(String[] args) throws Exception{      Statement statement=null;      Connection connection=null;      try {            //1.注册驱动            Class.forName("com.mysql.cj.jdbc.Driver");            //2.定义sql            String sql="insert into account values(null,'wangwu',3000)";            //3.获取connection对象            connection= DriverManager.getConnection("jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", "root", "Hky6600115");            //4.获取实行sql的对象statement            statement=connection.createStatement();            //5.实行sql            int count=statement.executeUpdate(sql);
//影响行数【增长一行,应返回1】            //6.处置惩罚结果            System.out.println(count);            if (count>0){                System.out.println("实行乐成");            }else {                System.out.println("实行失败");            }      }catch (ClassNotFoundException e){            e.printStackTrace();      }catch (SQLException e){            e.printStackTrace();            /*            开释但因作用域问题报错-->因此提拔作用域                statement.close();                connection.close();             */      }finally {            //7.开释资源            //制止空指针非常            if(statement!=null){                try {                  statement.close();                }catch (SQLException e){                  e.printStackTrace();                }            }            if(connection!=null){                try {                  connection.close();                }catch (SQLException e){                  e.printStackTrace();                }            }      }    }}   请仿造以上练习1的代码 ,完成练习2以及练习3

4️⃣.ResultSet 结果集对象



[*]boolean next()

[*]如果有数据返回true,且光标向下移动一行
[*]没有则返回false

[*]XXX getXxx(列名/列编号)

[*]XXX 表示数据类型 eg.int、String
[*]例如:int getInt(int)可以有 int getInt(1)或者int getInt("id")

代码示例:
import java.sql.*;

public class jdbcDemo5 {
    public static void main(String[] args) {
      Connection connection=null;
      Statement statement=null;
      ResultSet resultSet=null;
      try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String sql="select * from account";
            connection= DriverManager.getConnection("jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","Hky6600115");
            statement=connection.createStatement();
            resultSet= statement.executeQuery(sql);
            //处理结果
            //1.让光标向下移动一行(默认在列名一行)
            resultSet.next();
            //2.获取数据
            int id=resultSet.getInt("id");
            String name=resultSet.getString("name");
            double balance=resultSet.getDouble("balance");
            //3.打印数据
            System.out.println(id+"---"+name+"---"+balance);
      } catch (ClassNotFoundException e) {
            e.printStackTrace();
      } catch (SQLException e) {
            e.printStackTrace();
      }finally {
            if(resultSet!=null){
                try {
                  resultSet.close();
                } catch (SQLException e) {
                  e.printStackTrace();
                }
            }
            if(statement!=null){
                try {
                  statement.close();
                } catch (SQLException e) {
                  e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                  connection.close();
                } catch (SQLException e) {
                  e.printStackTrace();
                }
            }
      }
    }
}
https://img-blog.csdnimg.cn/direct/16895338e6dc4f7cb4a8fee40e17142a.png#pic_center
                                        图--运行结果

练习:遍历

案例代码:
   其他步调不变,仅改变数据处置惩罚过程
//处理结果(输出全部数据)
//1.判断游标是否为最后一行末尾
while (resultSet.next()){
        //2.获取数据
        int id=resultSet.getInt("id");
    String name=resultSet.getString("name");
    double balance=resultSet.getDouble("balance");
    //3.打印数据
    System.out.println(id+"---"+name+"---"+balance);
}

练习:封装对象

数据准备:
insert into emp VALUES
(1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
(100,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
(1006,'宋江',2,1009, '2001-05-01','28500.00',NULL,30),
(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
   要求:定义一个方法,查询emp表中的数据并将其封装为对象,然后装载集合,返回
步调:

[*]定义emp类
[*]定义方法 public List< EMP > findAll(){}
[*]实现方法 select*from emp;
代码实现:

[*]设置文件jdbc.properties
url="jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"
user=root
password=Hky6600115'
driver=com.mysql.cj.jdbc.Driver

[*]JDBCUtils工具类
public class JDBCUtils{
    private static String url;
    private static String user;
    private static
}

抽取JDBC工具类(JDBCUtils)



[*] 目的:简化书写
[*] 分析:

[*] 注册驱动
[*] 毗连对象

[*] 需求:

[*] 传递参数❌(太麻烦)
[*] 保障工具类的通用性(MySQL5.0/MySQL8.0的url不同)

[*] 解决:设置文件jdbc.properties【在src下创建】
https://img-blog.csdnimg.cn/direct/a12883b236064f8987b72efebd191765.png#pic_center
               url=“”
      user=“”
      password=“”
      driver=“”


实现代码:
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

/*
    JDBC工具类
*/
public class JDBCUtils {
    /*
    文件的读取只需要一次,便可以得到所有值
            利用【静态代码块】
   */
    private static String url;
    private static String user;
    private static String password;
    private static String driver;
    static {
      //读取资源文件,获取值
      try {
            //1.创建properties集合类
            Properties properties=new Properties();

            //获取src路径下的文件的方式--->classLoader 类加载器
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            URL resource= classLoader.getResource("jdbc.properties");
            String path = resource.getPath();
            //System.out.println(path);
            //2.加载文件
//            properties.load(new FileReader("jdbc.properties"));
            properties.load(new FileReader(path));

            //3.获取数据,赋值
            url=properties.getProperty("url");
            user=properties.getProperty("user");
            password=properties.getProperty("password");
            driver=properties.getProperty("driver");
            //4.注册驱动
            Class.forName(driver);
      } catch (IOException e) {
            e.printStackTrace();
      } catch (ClassNotFoundException e) {
            e.printStackTrace();
      }
    }
//    获取连接
    public static Connection getConnection() throws SQLException {
      return DriverManager.getConnection(url, user, password);
    }


//    释放资源
    public static void close(ResultSet resultSet, Statement statement, Connection connection){
      if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
      if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
      if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
    }

    public static void close(PreparedStatement preparedStatement, Connection connection) {
      if(preparedStatement!=null){
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
      if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
    }
}

工具类练习

   需求:

[*]通过键盘录入用户名和密码
[*]判定用户是否登录乐成

[*]select * from user where username=““and password =””;
[*]如果该sql语句有查询结果,则表示乐成,反之则失败

    步调:

[*] 创建数据表user
create table user(
    id int primary key auto_increment,
    username varchar(32),
    password varchar(32)
);
insert into user values (null,'zhangsan','123');
insert into user values (null,'lisi','234');

[*] 编写登录方法
代码实现:
/*
    登录方法
   */
    public boolean logion(String username,String password) {
      if(username==null||password==null){
            return false;
      }
      //连接数据库判断是否登录成功
      Connection connection=null;
      Statement statement=null;
      ResultSet resultSet=null;
      try {
            connection= JDBCUtils.getConnection();
            String sql="select * from user where username='"+username+"'and password='"+password+"' ";
            statement=connection.createStatement();
            resultSet=statement.executeQuery(sql);
            return resultSet.next();
      } catch (SQLException e) {
            e.printStackTrace();
      }finally {
            JDBCUtils.close(resultSet,statement,connection);
      }

      return false;
    }

5️⃣.PreparedStatement 实行sql的对象



[*] sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题

[*] 以上面的练习为例

[*] 输入用户名:随机(eg.wangwu)
[*] 输入密码:a ’ or ’ a ’ = ’ a

[*]sql语句:select * from user where username =‘wangwu’ and password='a’or’a’=‘a’;
[*]原sql语句:“select * from user where username='”+username+“‘and password=’”+password+"’ "
               仔细对比观察
      


[*] 经典例子:

[*] https://img-blog.csdnimg.cn/direct/49599d82baf648aa8a66fba40df039b3.png#pic_center
[*] https://img-blog.csdnimg.cn/direct/fbff61ddd35948688f7f0085312e5094.png#pic_center
   漫画中,该门生的姓名为“Robert’); DROP TABLE students;–”,导致students表被删除:


[*] 解决:使用PreparedStatement 对象
[*] 预编译sql:参数使用?作为占用符
[*] 步调(稍复杂):

[*]导入驱动jar包
[*]注册驱动
[*]获取数据库毗连对象 connection
[*]定义sql

[*]sql的参数使用?作为占位符
[*]如:select * from user where username = ? and password = ?;

[*]获取实行sgl语句的对象 PreparedStatement

[*]Connection.PreparedStatement (String sql)需要传参

[*]给?赋值:

[*]方法:setXxx(参数1,参数2)
[*]参数1:?的位置
[*]参数2:?的值

[*]实行sql,接受返回结果 不需要传参
[*]处置惩罚结果
[*]开释资源

代码修改:
/*
    登录方法,使用PreparedStatement 对象
   */
    public boolean logion(String username,String password) {
      if(username==null||password==null){
            return false;
      }
      //连接数据库判断是否登录成功
      Connection connection=null;
      ResultSet resultSet=null;
      PreparedStatement preparedStatement=null;
      try {
            connection= JDBCUtils.getConnection();
            String sql="select * from user where username=?and password=?";
            PreparedStatement=connection.preparedStatement(sql);
            preparedStatement.setString(1,username);
            preparedStatement.setString(2,password);
            resultSet=preparedStatement.executeQuery();
            return resultSet.next();
      } catch (SQLException e) {
            e.printStackTrace();
      }finally {
            JDBCUtils.close(resultSet,preparedStatement,connection);
      }

      return false;
    }


[*]注意:后期改用 preparedStatement 来完成增删改查的操作

[*]上风:
[*]防止sql注入
[*]效率更高



JDBC控制事件



[*] 事件 :一个包罗多个步调的业务操作。如果这个业务操作被事件管理,则这多个步调要么同时乐成,要么同时失败。
[*] 操作:

[*]开启事件
[*]提交事件
[*]回滚事件

[*] 使用connection对象来管理事件

[*]开启事件 setAutoCommit(boolean autoCommit) : 调用该方法设置参数为 false,即开启事件

[*]在实行sql之前开启事件

[*]提交事件 commit()

[*]当所有sql都实行完提交事件

[*]回滚事件 rollback()

[*]在catch中回滚事件


练习:转账

代码实现:

import cn.itcast.util.JDBCUtils;
import java.sql.*;

/*
事务操作
*/
public class jdbcDemo10 {
    /*
    转账方法
   */
    public static void main(String[] args) throws Exception {
      Connection connection=null;
      PreparedStatement preparedStatement1=null;
      PreparedStatement preparedStatement2=null;
      ResultSet resultSet=null;
      try {
            //1.获取连接
            connection= JDBCUtils.getConnection();
//                开启事务
            connection.setAutoCommit(false);
            //2.定义sql
            //2.1. 张三-500
            //2.2. 李四+500
            String sql1="update account set balance = balance - ? where id = ?";
            String sql2="update account set balance = balance + ? where id = ?";
            //3.获取执行对象
            preparedStatement1=connection.prepareStatement(sql1);
            preparedStatement2=connection.prepareStatement(sql2);
            //4.设置参数
            preparedStatement1.setDouble(1,500);
            preparedStatement1.setInt(2,1);

            preparedStatement2.setDouble(1,500);
            preparedStatement2.setInt(2,2);

            //5.执行sql
            preparedStatement1.executeUpdate();
            preparedStatement2.executeUpdate();
//                提交事务
            connection.commit();
      } catch (Exception e) {
//                事务回滚
            try {
                if(connection!=null){
                  connection.rollback();
                }
            }catch (SQLException e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
      }finally {
            JDBCUtils.close(preparedStatement1,connection);
            JDBCUtils.close(preparedStatement2,null);
      }
    }
}


数据库与毗连池

1. 概念:

存放数据库毗连的一个容器(集合)Connection
   当系统运行起来之后,这个毗连池就被创建,在这个毗连池当中,会申请一些对象,当有用户来访问数据库的时候,就从这个毗连池当中获取毗连对象,用户访问竣事之后,毗连池对象会归还给容器
https://img-blog.csdnimg.cn/direct/8a635e2f166c4f8ab76c8ba65712a636.png#pic_center
2.优点:



[*]节约资源
[*]用户访问高效
3. 毗连池实现:



[*]java官方提供的数据库毗连池规范(接口):DataSource (javax.sql包下)

[*]方法:【获取毗连:getConnection();】
[*]【归还毗连池对象:conn.close();】

[*]由数据库厂商为我们实现该接口

[*]C3P0
[*]Druid (阿里巴巴开辟)

4.C3P0

步调:

1. 导入jar包

   官网:https://sourceforge.net/
进入官网,搜索框中输入c3p0,并点击下面的提示
https://img-blog.csdnimg.cn/direct/0bae0f8e2cdc4507b15b19548be4a27a.png#pic_center
点击下载即可
https://img-blog.csdnimg.cn/direct/6f597377a9344855b90c883908b32629.png#pic_center
解压后,在lib文件夹中,复制如下两个jar包到项目lib文件夹中(还有不能忘记数据库驱动jar包mysql-connector-java-8.0.26.jar)
https://img-blog.csdnimg.cn/direct/676d413e2b924f5991f40a384eff4269.png#pic_center
https://img-blog.csdnimg.cn/direct/c38b3fa5518e4baf802a52b36e83208a.png#pic_center
右键libs添加为库
https://img-blog.csdnimg.cn/direct/b234ae2a48e947ff953800deb87eded4.png#pic_center
2. 定义设置文件:



[*]文件命名为:c3p0.properties 或者 c3p0-config.xml
[*]位置:src目次下
[*]1.自定义的c3p0-config.xml
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
        <!--连接参数 -->
    <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_study</property>
    <property name="user">root</property>
    <property name="password">Hky6600115</property>
   
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">10</property>
    <property name="checkoutTimeout">3000</property>
</default-config>

<named-config name="otherc3p0">
    <!--连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
    <property name="user">root</property>
    <property name="password">root</property>
   
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>


[*]2.参数表明

[*]initialPoolSize:初始化申请的毗连数量
[*]maxPoolSize:最大的毗连数量
[*]checkoutTimeout:超时时间

3. 创建核心对象

数据库毗连池对象 ComboPooledDataSource
4. 获取毗连

getConnection
代码实现:
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;

/*
c3p0的演示
*/
public class c3p0Demo1 {
    public static void main(String[] args) throws Exception {
      //1.创建数据库连接池对象
      DataSource dataSource=new ComboPooledDataSource();
      //2.获取连接对象
      Connection connection = dataSource.getConnection();
      //3.打印
      System.out.println(connection);
    }
}

参数查验:

   5
10
3000
1. 查验最大毗连数量

public class c3p0Demo2 {
    public static void main(String[] args) throws Exception {
      DataSource dataSource=new ComboPooledDataSource();
      for (int i=1;i<=10;i++){
            Connection connection=dataSource.getConnection();
            System.out.println(i+":"+connection);
      }
    }
}
运行结果:(正常)
https://img-blog.csdnimg.cn/direct/50db9ec3945f4ddfa1e53431d60595b2.png#pic_center
2. 查验超时时间

–> 运行有错误会等带一段时间再报错
for (int i=1;i<=11;i++){
    Connection connection=dataSource.getConnection();
    System.out.println(i+":"+connection);
}
运行结果:(先输出正常部分,隔3秒报错)
https://img-blog.csdnimg.cn/direct/1f2f5701f2f547ea97935852175c74f1.png#pic_center
   若中途归还对象,即可正常(重复使用)
public static void main(String[] args) throws SQLException {
      DataSource dataSource=new ComboPooledDataSource();
      for (int i=1;i<=11;i++){
            Connection connection=dataSource.getConnection();
            System.out.println(i+":"+connection);
            
            if(i==5){
                connection.close();
            }
      }
    }
注:



[*]DataSource dataSource=new ComboPooledDataSource();表示使用默认设置
[*]DataSource dataSource=new ComboPooledDataSource("otherc3p0");表示使用指定名称设置

5.Druid

步调:

1. 导入jar包

官网下载所在:Central Repository: com/alibaba/druid (maven.org)
https://img-blog.csdnimg.cn/direct/8a31af92205e49f2bbbde50c4431ff3f.png#pic_center
https://img-blog.csdnimg.cn/direct/f02d9c483ede4833a49b5ff922288272.png#pic_center
(详见c3p0)
2.定义设置文件



[*]是properties情势的
[*]可以叫任意名称,可以放在任意目次下

[*]不会自动加载,需要手动

//示例 druid.properties
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
username=root
password=password
# 初始化连接数量
initialSize=5
#最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
步调+1:加载设置文件
3. 获取数据库毗连池对象

通过工厂类来获取 DruidDataSourceFactory
4. 获取毗连

getConnection
代码实现:

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class DruidDemo {
    public static void main(String[] args) throws Exception {
      //加载配置文件
      Properties properties=new Properties();
      InputStream inputStream=DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
      properties.load(inputStream);

      //获取连接池对象
      DataSource dataSource =DruidDataSourceFactory.createDataSource(properties);

      //获取连接
      Connection connection=dataSource.getConnection();
      System.out.println(connection);
    }
}

定义工具类

1. 定义一个类

2. 静态代码块



[*]提供静态代码块加载设置文件,初始化毗连池对象
3. 提供方法



[*]获取毗连方法;通过数据库毗连池获取毗连
[*]开释资源
[*]获取毗连池的方法
代码实现:

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/*
Druid连接池工具类
*/
public class JDBCUtils {
    private static DataSource dataSource;
    static {
      try {
            Properties properties=new Properties();
            properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            dataSource= DruidDataSourceFactory.createDataSource(properties);
      } catch (IOException e) {
            e.printStackTrace();
      } catch (Exception e) {
            e.printStackTrace();
      }
    }
    /*
    获取连接的方法
   */
    public static Connection getConnection() throws SQLException {
      return dataSource.getConnection();
    }

    /*
    释放资源
   */
    public static void close(ResultSet resultSet,Statement statement, Connection connection){
      if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
      if (statement!=null){
         try {
               statement.close();
         } catch (SQLException e) {
               e.printStackTrace();
         }
      }
      if (connection!=null){
            try {
                connection.close();//归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
      }
    }
    public static void close(Statement statement, Connection connection){
      close(null,statement,connection);
    }

    /*
    获取连接池
   */
    public static DataSource getDataSource(){
      return dataSource;
    }
}


JDBCTemplate

Spring框架对JDBC的简单封装,提供了一个JdbcTemplate对象,大大的简化了开辟
步调

1. 导入jar包

以下是我的下载参考页面所在↓
spring jar包 以及 jdbcTemplate 相关jar包下载_jdbctemplate的jar包-CSDN博客
https://img-blog.csdnimg.cn/direct/f5906ecfe05e425781741057cb991e8a.png#pic_center
2.创建JdbcTemplate对象



[*]依靠于数据源DataSource
JdbcTemplate template = new jdbcTemplate(dataSource);
import cn.itcast.JDBC数据库与连接池.datasource.utils.JDBCUtils;
import org.springframework.jdbc.core.JdbcTemplate;

/*
JDBCTemplateDemo1 入门
*/
public class JDBCTemplateDemo1 {
    public static void main(String[] args) {
//      1.导入jar包
//      2.创建JDBCTemplate
      JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
//      3.调用方法
      String sql="update account set balance=5000 where id=?";
      int count =template.update(sql,2);
      System.out.println(count);
    }
}
3. 调用JdbcTemplate的方法来完成CRUD的操作



[*]update():实行DML语句。增、删、改语句
[*]queryForMap():查询结果将结果集封装为map集合
[*]queryForList():查询结果将结果集封装为list集合
[*]query():查询结果,将结果封装为JavaBean对象
[*]queryForobject:查询结果,将结果封装为对象
4. 练习



[*]修改1号数据的 salary 为 10000
[*]添加一条记载
[*]删除刚才添加的记载
[*]查询id为1的记载,将其封装为Map集合
[*]查询所有记载,将其封装为List
[*]查询所有记载,将其封装为Emp对象的List集合
[*]查询总记载数

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: JDBC教程:JDBC毗连Mysql数据库超具体解说(从入门到纯熟使用)