干巴爹兔的博客 干巴爹兔的博客
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

干巴爹兔

卑微的前端打工人
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL基础

    • MySQL学习笔记1:数据库连接与字段认识
    • MySQL学习笔记2:数据库表的增删改与外键认识
    • MySQL学习笔记3:MySQL的增删改与基本查询语句
    • MySQL学习笔记4:MySQL的WHERE与JOIN语句
    • MySQL学习笔记5:分页、排序、子查询与常用函数
    • MySQL学习笔记6:聚合函数与事务初识
    • MySQL学习笔记7:MySQL索引配合大量数据的使用
    • MySQL学习笔记8:权限管理、数据库备份与设计
    • MySQL学习笔记9:JDBC
    • 《MySQL学习笔记》
    • MySQL基础
    干巴爹兔
    2020-06-03
    目录

    MySQL学习笔记9:JDBC

    # 1、前言

    学习视频源自:【狂神说Java】MySQL最新教程通俗易懂

    B站视频链接:https://www.bilibili.com/video/BV1NJ411J79W

    [video(video-4IYyPI1C-1589717216258)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=83395424)(image-https://ss.csdn.net/p?http://i0.hdslb.com/bfs/archive/efacc6aa636d653b8b5c2984988eaed4f428132c.jpg)(title-【狂神说Java】MySQL最新教程通俗易懂)]

    笔记为看视频自行撰写,仅限学习交流使用

    # 1.1、上一篇文章

    MySQL学习笔记8:权限管理、数据库备份与设计 (opens new window)

    # 11、JDBC

    # 11.1、数据库驱动

    驱动:声卡、显卡、数据库

    image-20200602185055519

    我们的程序会通过数据库驱动,和数据库打交道

    # 11.2、JDBC

    SUN公司为了简化开发人员对数据库统一的操作,提供了一个Java操作数据库的规范,俗称JDBC

    这些规范的实现由具体的厂商去做

    对于开发人员来说,我们只需要掌握JDBC接口的操作即可

    image-20200602185410234

    java.sql

    javax.sql

    还需要导入一个数据库驱动包 mysql-connector-java-8.0.17.JAR

    # 11.3、第一个JDBC程序

    创建测试数据库

    CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
    
    USE jdbcStudy;
    
    CREATE TABLE `users`(
    id INT PRIMARY KEY,
    NAME VARCHAR(40),
    PASSWORD VARCHAR(40),
    email VARCHAR(60),
    birthday DATE
    );
    
    INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
    VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),
    (2,'lisi','123456','lisi@sina.com','1981-12-04'),
    (3,'wangwu','123456','wangwu@sina.com','1979-12-04')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    1、创建一个普通项目

    2、导入数据库驱动

    image-20200602190242703

    3、编写测试代码

    package com.jdbc;
    
    import java.sql.*;
    
    // 第一个jdbc程序
    public class JdbcFirstDemo {
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            //1、加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver"); //固定写法,加载驱动
            //2、用户信息和url
            String url = "jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=TRUE&serverTimezone=GMT%2B8";
            String username = "root";
            String password = "123456";
            //3、连接成功,数据库对象 Connection代表数据库
            Connection connection = DriverManager.getConnection(url, username, password);
    
            //4、执行SQL的对象 Statement执行sql的对象
            Statement statement = connection.createStatement();
    
            //5、执行SQL,可能存在结果
            String sql = "SELECT * FROM users";
            ResultSet resultSet = statement.executeQuery(sql);//返回的结果集,结果集中封装了查询到结果
    
            while(resultSet.next()){
                System.out.println("id="+resultSet.getObject("id"));
                System.out.println("name="+resultSet.getObject("NAME"));
                System.out.println("password="+resultSet.getObject("PASSWORD"));
                System.out.println("email="+resultSet.getObject("email"));
                System.out.println("birthday="+resultSet.getObject("birthday"));
                System.out.println("=====================================");
            }
            //6、释放连接
            resultSet.close();
            statement.close();
            connection.close();
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38

    步骤总结:

    1、加载驱动

    2、连接数据库 DriverManager

    3、获取执行Sql的对象 Statement

    4、获得返回的结果集

    5、释放连接

    DriverManager

    //DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver()); 没必要
            Class.forName("com.mysql.cj.jdbc.Driver"); //固定写法,加载驱动
    
    // connection 代表数据库
    // 数据库设置自动提交
    // 自动回滚
    Connection connection = DriverManager.getConnection(url, username, password);
    
    connection.rollback();
    connection.commit();
    connection.setAutoCommit();
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    URL

    String url = "jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=TRUE&serverTimezone=GMT%2B8";
    
    // mysql --3306
    // jdbc:mysql://主机地址:端口号/数据库名?参数1&参数2&参数3
    
    // oracle --1521
    // jdbc:oracle:thin@localhost:1521:sid
    
    1
    2
    3
    4
    5
    6
    7

    Statement 执行SQL的对象 PrepareStatement 执行SQL的对象

    String sql = "SELECT * FROM users"; //编写SQL
    
    statement.executeQuery(); //查询操作返回ResultSet
    statement.execute(); //执行任何SQL
    statement.executeUpdate(); //更新、插入、删除都是用这个,返回一个受影响的行数
    
    1
    2
    3
    4
    5

    ResultSet 查询结果集:封装了所有的查询结果

    获得指定的数据类型

    resultSet.getObject(); //在不知道类型的情况下使用
    //如果知道类型
    resultSet.getString(); 
    resultSet.getInt();
    resultSet.getFloat();
    resultSet.getDate();
    resultSet.getObject();
    ...
    
    1
    2
    3
    4
    5
    6
    7
    8

    遍历,指针

    resultSet.beforeFirst(); //移动到最前面
    resultSet.afterLast(); //移动到最后面
    resultSet.next(); //移动到下一个数据
    resultSet.previous(); //移动到前一行
    resultSet.absolute(row); //移动到指定行
    
    1
    2
    3
    4
    5

    释放资源

    //6、释放连接
    resultSet.close();
    statement.close();
    connection.close(); //耗资源,用完关掉
    
    1
    2
    3
    4

    # 11.4、statement对象

    Jdbc中的statemlent对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改 查语句即可。 Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句, executeUpdate执行完后, 将会返回一个整 数(即增删改语句导致了数据库几行数据发生了变化)。 Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表 查询结果的ResultSet对象。

    CRUD操作-create

    使用executeUpdate(String sql)方法完成数据添加操作,示例操作:

    Statement st = conn.createstatement();
    String sql = "insert into user(...) values(...)";
    int num = st.executeUpdate(sql);
    if(num>0){
    system.out.println("插入成功!");
    }
    
    
    1
    2
    3
    4
    5
    6
    7

    CRUD操作-delete

    使用executeUpdate(String sql)方法完成数据删除操作,示例操作:

    Statement st = conn.createstatement();
    String sql = "delete from user where id = 1";
    int num = st.executeUpdate(sql);
    if(num>0){
    system.out.println("删除成功!");
    }
    
    1
    2
    3
    4
    5
    6

    CRUD操作-update

    使用executeUpdate(String sql)方法完成数据修改操作,示例操作:

    Statement st = conn.createstatement();
    String sql = "update user set name = '' where name = ''";
    int num = st.executeUpdate(sql);
    if(num>0){
    system.out.println("删除成功!");
    }
    
    1
    2
    3
    4
    5
    6

    CRUD操作-read

    使用executeQuery(String sql)方法完成数据修改操作,示例操作:

    Statement st = connection.createStatement();
    String sql = "SELECT * FROM users";
    ResultSet rs = statement.executeQuery(sql);
    while(rs.next()){
        //根据获取列的数据类型,分别调用rs的相应方法映射到java对象中       
    }
    
    1
    2
    3
    4
    5
    6

    代码实现

    1、提取工具类

    package com.jdbc.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");
                //1.驱动只用加载一次
                Class.forName(driver);
            }catch (Exception 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 e) {
                    e.printStackTrace();
                }
            }
            if(st!=null){
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    2、编写增删改的方法,excuteUpdate

    增

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class TestInsert {
        public static void main(String[] args) {
            Connection coon = null;
            Statement st = null;
            ResultSet rs = null;
            try {
                 coon = JdbcUtils.getConnection(); //获取数据库连接
                 st = coon.createStatement();//获得sql的执行对象
                 String sql = "INSERT INTO users(id,NAME,PASSWORD,email,birthday) VALUES(4,'chen','123456','929682749@qq.com','2020-01-01')";
    
                int i = st.executeUpdate(sql);
                if(i>0){
                    System.out.println("插入成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    删

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class TestDelete {
        public static void main(String[] args) {
            Connection coon = null;
            Statement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                st = coon.createStatement();//获得sql的执行对象
                String sql = "DELETE FROM users WHERE id = 4 ";
    
                int i = st.executeUpdate(sql);
                if(i>0){
                    System.out.println("删除成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    改

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class TestUpdate {
        public static void main(String[] args) {
            Connection coon = null;
            Statement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                st = coon.createStatement();//获得sql的执行对象
                String sql = "UPDATE users SET NAME='chen1',email='929682749@qq.com' WHERE id=1";
    
                int i = st.executeUpdate(sql);
                if(i>0){
                    System.out.println("更新成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    3、查询excuteQuery

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class TestSelect {
        public static void main(String[] args) {
            Connection coon = null;
            Statement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                st = coon.createStatement();//获得sql的执行对象
                String sql = "SELECT * FROM users WHERE id = 1";
    
                rs = st.executeQuery(sql);//查询
                while(rs.next()){
                    System.out.println(rs.getString("NAME"));
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    SQL注入的问题

    sql存在漏洞,会被攻击导致数据泄露,本质:SQL会被拼接

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class SQLIn {
        public static void main(String[] args) {
            //Login("chen1","123456"); 正常登录
            Login(" 'or '1=1","'or '1=1"); //SQL注入
        }
    
        //登录业务
        public static void Login(String username,String password){
            Connection coon = null;
            Statement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                st = coon.createStatement();//获得sql的执行对象
                //SELECT * FROM users WHERE `NAME` = 'chen1' AND `password` = '123456';
                //SELECT * FROM users WHERE `NAME` = ''or '1=1' AND `password` = ''or '1=1';
                String sql = "SELECT * FROM users WHERE `NAME` = '"+username+"' AND `password` = '"+password+"'";
    
                rs = st.executeQuery(sql);//查询
                while(rs.next()){
                    System.out.println(rs.getString("NAME"));
                    System.out.println(rs.getString("password"));
                    System.out.println("====================================");
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
    
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43

    # 11.5、PrepareStatement对象

    PrepareStatement可以防止SQL注入,效率更好

    1、新增

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.*;
    
    public class TestInsert2 {
        public static void main(String[] args) {
    
            Connection coon = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                //区别
                //使用?占位符代替参数
                String sql = "INSERT INTO users(id,NAME,PASSWORD,email,birthday) VALUES(?,?,?,?,?)";
    
                st = coon.prepareStatement(sql); //预编译SQL,先写SQL不执行
    
                //手动给参数赋值
                st.setInt(1,4);//给id
                st.setString(2,"chen2");
                st.setString(3,"123456");
                st.setString(4,"123456@qq.com");
                //注意点:sql.Date 数据库   util.Date Java  new java.util.Date().getTime()获得时间戳
                // new java.sql.Date转化为sql
                st.setDate(5,new java.sql.Date(new java.util.Date().getTime()));
    
                //执行
                int i = st.executeUpdate();
                if(i>0){
                    System.out.println("插入成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42

    2、删除

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class TestDelete2 {
        public static void main(String[] args) {
            Connection coon = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                //区别
                //使用?占位符代替参数
                String sql = "DELETE from users WHERE id = ?";
    
                st = coon.prepareStatement(sql); //预编译SQL,先写SQL不执行
    
                //手动给参数赋值
                st.setInt(1,4);//给id
    
                //执行
                int i = st.executeUpdate();
                if(i>0){
                    System.out.println("删除成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38

    3、更新

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class TestUpdate2 {
        public static void main(String[] args) {
            Connection coon = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                //区别
                //使用?占位符代替参数
                String sql = "UPDATE users SET `name` = ? WHERE id = ?";
    
                st = coon.prepareStatement(sql); //预编译SQL,先写SQL不执行
    
                //手动给参数赋值
                st.setString(1,"wangwu2");
                st.setInt(2,3);//给id
    
                //执行
                int i = st.executeUpdate();
                if(i>0){
                    System.out.println("更新成功!");
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    4、查询

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class TestSelect2 {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                conn = JdbcUtils.getConnection();
                String sql = "SELECT * FROM users WHERE id = ?";
                st = conn.prepareStatement(sql); //预编译
                st.setInt(1,2); //传递参数
                //执行
                rs = st.executeQuery();
    
                if(rs.next()){
                    System.out.println(rs.getString("NAME"));
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(conn,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    5、防止SQL注入

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.*;
    
    public class SQLIn2 {
        public static void main(String[] args) {
            //Login("chen1","123456"); //正常登录
            Login(" '' or '1=1","''or '1=1"); //SQL注入
        }
    
        //登录业务
        public static void Login(String username,String password){
            Connection coon = null;
            PreparedStatement st = null;
            ResultSet rs = null;
            try {
                coon = JdbcUtils.getConnection(); //获取数据库连接
                // PreparedStatement防止SQL注入的本质,把传递进来的参数当作字符
                // 假设其中存在转义字符,比如说 ' 会被直接转义
                String sql = "SELECT * FROM users WHERE `NAME` = ? AND password = ?";
                st = coon.prepareStatement(sql);//获得sql的执行对象
    
                st.setString(1,username);
                st.setString(2,password);
    
    
                rs = st.executeQuery();//查询
                while(rs.next()){
                    System.out.println(rs.getString("NAME"));
                    System.out.println(rs.getString("password"));
                    System.out.println("====================================");
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                JdbcUtils.release(coon,st,rs);
            }
    
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    # 11.6、使用IDEA连接数据库

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ff0O6SR7-1591191318668)(https://gitee.com/cyh199910/personal_picture_bed/raw/master/img/image-20200603193144150.png)]

    image-20200603193944277

    连接成功后,可以选择数据库

    image-20200603194054792

    双击数据库

    image-20200603194309026

    更新数据

    image-20200603194246506

    编写SQL代码

    image-20200603194430585

    /*创建账户表*/
    CREATE TABLE account(
        id INT PRIMARY KEY AUTO_INCREMENT,
        NAME VARCHAR(40),
        money FLOAT
    );
    
    /*插入测试数据*/
    insert into account(name, money) values ('A',1000);
    insert into account(name, money) values ('B',1000);
    insert into account(name, money) values ('C',1000);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    image-20200603194806840

    连接失败查看原因

    image-20200603195000091

    # 11.8、事务

    要么都成功要么都失败

    ACID原则

    原子性:要么全部完成,要么都不完成

    一致性:总数不变

    隔离性:多个进程互不干扰

    持久性:一旦提交不可逆,持久化到数据库

    隔离性的问题

    脏读:一个事务读取了另一个没有提交的事务

    不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了改变

    虚度(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来的数据不一致

    代码实现

    1、开启事务 conn.setAutoCommit(false);

    2、一组事务执行完毕,提交事务

    3、可以在catch语句中显示的定义回滚语句,但默认失败会回滚

    package com.jdbc;
    
    import com.jdbc.utils.JdbcUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class TestTransaction1 {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement st = null;
            ResultSet rs = null;
    
            try {
                conn = JdbcUtils.getConnection();
                //关闭数据库的自动提交功能,自动会开启事务
                conn.setAutoCommit(false); //开启事务
    
                String sql1 = "UPDATE account set money = money - 100 WHERE name = 'A'";
                st = conn.prepareStatement(sql1);
                st.executeUpdate();
    
                //int x = 1/0; //报错
    
                String sql2 = "UPDATE account set money = money + 100 WHERE name = 'B'";
                st = conn.prepareStatement(sql2);
                st.executeUpdate();
    
                //业务完毕,提交事务
                conn.commit();
                System.out.println("操作成功");
    
    
            } catch (SQLException e) {
                try {
                    //如果失败则默认回滚
                    conn.rollback(); //如果失败则回滚事务
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }finally {
                JdbcUtils.release(conn,st,rs);
            }
        }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    # 11.9、数据库连接池

    数据库连接--执行完毕--释放

    连接--释放 十分浪费系统资源

    池化技术:准备一些预先的资源,过来就连接预先准备好的

    -----开门--业务员:等待--服务---

    常用连接数 10个

    最小连接数 10

    最大连接数 15 业务最高承载上限

    等待超时:100ms

    编写连接池,实现一个接口DataSource

    开源数据源实现

    DBCP

    C3P0

    Druid:阿里巴巴

    使用了这些数据库连接池之后,我们在项目开发中就不需要编写数据库连接的代码

    DBCP

    需要用到的jar包

    commons-dbcp-1.4、commons-pool-1.6

    C3P0

    需要用到的jar包

    c3p0-0.9.5.5、mchange-commons-java-0.2.19

    结论

    无论使用什么数据源,本质还是一样的,DataSource接口不会变,方法就不会变

    Druid

    使用到的配置文件

    db.properties

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=TRUE&serverTimezone=GMT%2B8
    username=root
    password=123456
    
    1
    2
    3
    4

    dbcpconfig.properties

    #连接设置 这里的名字是预先定义好的
    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=TRUE&serverTimezone=GMT%2B8
    username=root
    password=123456
    
    #<!-- 初始化连接 -->
    initialSize=10
    
    #最大连接数量
    maxActive=50
    
    #<!-- 最大空闲连接 -->
    maxIdle=20
    
    #<!-- 最小空闲连接 -->
    minIdle=5
    
    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000
    #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
    #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
    connectionProperties=useUnicode=true;characterEncoding=utf8
    
    #指定由连接池所创建的连接的自动提交(auto-commit)状态。
    defaultAutoCommit=true
    
    #driver default 指定由连接池所创建的连接的只读(read-only)状态。
    #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
    defaultReadOnly=
    
    #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
    #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_COMMITTED
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    c3p0-config.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <c3p0-config>
        <!--
        C3P0的缺省(默认)配置,如果在代码中"ComboPooledDataSource ds = new ComboPooledDataSource();"这样写就表示使用的是C3P0的缺省(默认)
        -->
        <default-config>
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=TRUE&amp;serverTimezone=GMT%2B8</property>
            <property name="user">root</property>
            <property name="password">123456</property>
    
            <property name="acquireIncrement">5</property>
            <property name="initialPoolSize">10</property>
            <property name="maxPoolSize">20</property>
            <property name="minPoolSize">5</property>
        </default-config>
    
        <!--
       C3P0的命名配置,如果在代码中"ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");"这样写就表示使用的是name为MySQL的配置
       -->
        <named-config name="MySQL">
            <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=TRUE&amp;serverTimezone=GMT%2B8</property>
            <property name="user">root</property>
            <property name="password">123456</property>
    
            <property name="acquireIncrement">5</property>
            <property name="initialPoolSize">10</property>
            <property name="maxPoolSize">20</property>
            <property name="minPoolSize">5</property>
        </named-config>
    </c3p0-config>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    Apache基金会

    编辑 (opens new window)
    #MySQL
    上次更新: 2022/08/26, 15:52:02
    MySQL学习笔记8:权限管理、数据库备份与设计

    ← MySQL学习笔记8:权限管理、数据库备份与设计

    最近更新
    01
    使用Vscode开发一个小插件
    10-21
    02
    Vscode插件配置项监听
    10-18
    03
    使用has属性构造必填效果
    10-14
    更多文章>
    Theme by Vdoing | Copyright © 2020-2023 互联网ICP备案: 闽ICP备18027236号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式