• MySQL-JDBC


    1. JDBC介绍

            JDBC(Java Database Connectivity)是 Java 连接数据库的标准接口,它提供了一种与数据库交互的统一方式,使得 Java 程序能够通过标准 API 访问和操作各种关系型数据库。

    2. JDBC使用步骤

            第0步:导bao

            第1步:注册驱动(仅需一次)

            第2步:建立链接(Connection)

            第3步:创建语句传输对象(Statement)

            第4步:运行sql语句

            第5步:处理运行结果(ResultSet)

            第6步:释放资源

            其中,如果是添加,删除,更新操作,可以没有第五步,查询肯定有第五步。

            2.0 导包

            下载相应版本的jar包(下载地址:Maven Repository: MySQL (mvnrepository.com)) 

            

            创建Java项目 ——> 在项目下创建lib文件夹——> 将jar包复制到lib文件夹下——> 右键——> Build Path ——> Add to Build Path

            

            2.1 注册驱动

            创建java类 JDBC_00 (类名随意)

    1. // 1. 注册驱动
    2. Class.forName("com.mysql.cj.jdbc.Driver");
              2.2 建立链接
    1. // 2. 创建链接对象
    2. // 如果出现乱码等问题 可以在url后添加设置编码方式
    3. // url : jdbc:mysql://IP:端口/数据库?useUnicode=true&characterEncoding=utf-8
    4. Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02","root", "root");
            2.3 创建语句传输对象
    1. // 3. 创建语句传输对象
    2. Statement statement = conn.createStatement();
    3. String sql = "select * from student";
            2.4 运行语句
    1. // 4. 执行sql语句获取结果集
    2. ResultSet rs = statement.executeQuery(sql);
            2.5 处理运行结果
    1. // 5. 处理结果集数据
    2. while (rs.next()) {
    3. // 根据列名获取数据
    4. int id = rs.getInt("id");
    5. // 根据列的索引获取数据,不建议使用,
    6. // int id = rs.getInt(1);
    7. String name = rs.getString("name");
    8. int tid = rs.getInt("teacher_id");
    9. double score = rs.getDouble("score");
    10. System.out.println(id + "--" + name + "--" + tid + "--" + score);
    11. }
            2.6 释放资源
    1. // 6. 关闭资源
    2. rs.close();
    3. statement.close();
    4. conn.close();

    3.代码优化

            添加try...catch...finally异常处理

    1. public class JDBC_00 {
    2. public static void main(String[] args) {
    3. Connection conn = null;
    4. Statement statement = null;
    5. ResultSet rs = null;
    6. try {
    7. // 1. 注册驱动
    8. Class.forName("com.mysql.cj.jdbc.Driver");
    9. // 2. 创建链接对象
    10. // 如果出现乱码等问题 可以在url后添加东西
    11. // url : jdbc:mysql://IP:端口/数据库?useUnicode=true&characterEncoding=utf-8
    12. conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02","root", "abc280619SS");
    13. // 3. 创建语句传输对象
    14. statement = conn.createStatement();
    15. String sql = "select * from student";
    16. // 4. 执行sql语句获取结果集
    17. rs = statement.executeQuery(sql);
    18. // 5. 处理结果集数据
    19. while (rs.next()) {
    20. // 根据列名获取数据
    21. int id = rs.getInt("id");
    22. // 根据列的索引获取数据,不建议使用,
    23. // int id = rs.getInt(1);
    24. String name = rs.getString("name");
    25. int tid = rs.getInt("teacher_id");
    26. double score = rs.getDouble("score");
    27. System.out.println(id + "--" + name + "--" + tid + "--" + score);
    28. }
    29. } catch (Exception e) {
    30. e.printStackTrace();
    31. }finally {
    32. try {
    33. // 6. 关闭资源,先打开的后关闭
    34. rs.close();
    35. statement.close();
    36. conn.close();
    37. } catch (SQLException e) {
    38. e.printStackTrace();
    39. }
    40. }
    41. }
    42. }

    4. DML

            Data Manipulation Language : 数据操作语言

            涉及的关键字有 : delete,update,insert

            和查询的操作几乎一样,就是把第4步和第5步更改一下

    1. public class JDBC_02 {
    2. public static void main(String[] args) {
    3. Connection conn = null;
    4. Statement statement = null;
    5. try {
    6. // 加载驱动
    7. Class.forName("com.mysql.cj.jdbc.Driver");
    8. // 创建链接对象
    9. conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02", "root", "abc280619SS");
    10. // 创建语句传输对象
    11. statement = conn.createStatement();
    12. // 编写sql语句
    13. // 添加
    14. String sql = "insert into teacher(id,`name`) values(3,'宋老师')";
    15. // 修改
    16. sql = "update teacher set `name` = '赵老师' where id = 3";
    17. // 删除
    18. sql = "delete from teacher where id = 3";
    19. // 执行sql语句,增删改使用executeUpdate()方法,查询使用executeQuery()方法
    20. int count = statement.executeUpdate(sql);
    21. System.out.println("成功,影响了"+ count + "行。" );
    22. } catch (Exception e) {
    23. e.printStackTrace();
    24. }finally {
    25. // 关闭资源
    26. try {
    27. statement.close();
    28. conn.close();
    29. } catch (SQLException e) {
    30. e.printStackTrace();
    31. }
    32. }
    33. }
    34. }

    5. PrepareStatement

            添加或删除的时候,尽量使用PrepareStatement,而不是Statement

            Statement和PrepareStatement的区别:

            Statement 用于执行静态SQL语句,在执行的时候,必须指定一个事先准备好的SQL语句,并且相对不安全,会有SQL注入风险。

            PrepareStatement 是预编译的SQL语句对象,SQL语句被预编译i并保存在对象中,被封装的SQL语句中,可以使用动态包含的参数?,在执行的时候可以为?传递参数。

            使用PrepareStatement对象执行SQL语句的时候,sql被数据库进行预编译和预解析,然后被放到缓冲区中,每当执行一个PrepareStatement对象时,他就会被解析一次,但不会被再次编译,可以重复使用,减少编译次数,提高数据库性能。并且能够避免SQL注入,相对安全(把’ 单引号 使用 \ 转义,避免SQL注入 )。

            SQL注入:

            SQL注入(SQL Injection)是一种常见的网络安全攻击技术,通过在应用程序中插入恶意的SQL查询语句,来利用程序缺陷或漏洞,从而对数据库进行非法操作或获取敏感信息。

            SQL注入攻击通常发生在需要用户输入数据并将其嵌入到 SQL 查询语句中的地方,比如登录表单、搜索框、参数化查询等。攻击者利用这些地方未对用户输入进行有效验证和过滤,直接将恶意的SQL代码注入到查询中,从而执行恶意操作。

            

    1. /*
    2. * PrepareStament
    3. */
    4. public class JDBC_05 {
    5. public static void main(String[] args) {
    6. Scanner scanner = new Scanner(System.in);
    7. System.out.println("请输入用户名:");
    8. String username = scanner.nextLine();
    9. System.out.println("请输入密码:");
    10. String password = scanner.nextLine();
    11. // login(username, password);
    12. // updatePwd(username, password);
    13. loginUser(username, password);
    14. }
    15. // 用户登录方法
    16. public static boolean login(String username,String password) {
    17. Connection conn = null;
    18. PreparedStatement statement = null;
    19. ResultSet rs = null;
    20. try {
    21. // 加载驱动
    22. conn = DBUtil.getConnection();
    23. // 编写sql语句
    24. String sql = "select count(*) from user where name = ? and password = ?";
    25. // 创建输出对象
    26. statement = conn.prepareStatement(sql);
    27. // 给问号赋值
    28. statement.setString(1, username);
    29. statement.setString(2, password);
    30. // 创建结果集,执行sql语句
    31. rs = statement.executeQuery();
    32. rs.next();
    33. // 返回结果
    34. int count = rs.getInt(1);
    35. if (count == 0) {
    36. System.out.println("登录失败");
    37. return false;
    38. }else {
    39. System.out.println("登录成功");
    40. return true;
    41. }
    42. } catch (Exception e) {
    43. e.printStackTrace();
    44. } finally {
    45. // 关闭资源
    46. DBUtil.close(rs);
    47. DBUtil.close(statement);
    48. DBUtil.close(conn);
    49. }
    50. return false;
    51. }
    52. // 修改密码的方法
    53. public static void updatePwd(String username,String password) {
    54. Connection conn = null;
    55. PreparedStatement statement = null;
    56. try {
    57. // 加载驱动
    58. conn = DBUtil.getConnection();
    59. // 编写sql语句
    60. String sql = "update user set password = ? where name = ?";
    61. // 创建输出对象
    62. statement = conn.prepareStatement(sql);
    63. // 给问号赋值
    64. statement.setString(1, password);
    65. statement.setString(2, username);
    66. // 执行sql语句
    67. int count = statement.executeUpdate();
    68. System.out.println("修改了"+count+"条数据");
    69. } catch (Exception e) {
    70. e.printStackTrace();
    71. } finally {
    72. // 关闭资源
    73. DBUtil.close(statement);
    74. DBUtil.close(conn);
    75. }
    76. }
    77. // 使用statement的登录方法,容易发生sql注入问题
    78. // 由于Statement在执行sql语句之前进行了字符串的拼接,所以如果username输入类似'or 1=1 or'格式
    79. // 即使用户不存在也能实现登录
    80. public static boolean loginUser(String username,String password) {
    81. Connection conn = null;
    82. Statement statement = null;
    83. ResultSet rs = null;
    84. try {
    85. // 加载驱动
    86. conn = DBUtil.getConnection();
    87. // 创建输出对象
    88. statement = conn.createStatement();
    89. // 编写sql语句
    90. String sql = "select count(*) from user where name = '"+username+"' and password = '"+password+"'";
    91. // 创建结果集,执行sql语句
    92. rs = statement.executeQuery(sql);
    93. rs.next();
    94. // 返回结果
    95. int count = rs.getInt(1);
    96. if (count == 0) {
    97. System.out.println("登录失败");
    98. return false;
    99. }else {
    100. System.out.println("登录成功");
    101. return true;
    102. }
    103. } catch (Exception e) {
    104. e.printStackTrace();
    105. } finally {
    106. // 关闭资源
    107. DBUtil.close(rs);
    108. DBUtil.close(statement);
    109. DBUtil.close(conn);
    110. }
    111. return false;
    112. }
    113. }

            

    6. 封装工具类

            以上代码中创建链接和关闭资源操作都是相同的,因此可以把这一部分逻辑抽离出来,形成独立的类和方法,在实际应用中直接调用相应的类和方法即可。

            创建JDBCUtil类,提供获取链接的方法和释放资源的方法

    1. public class DBUtil {
    2. // 封装方法加载驱动创建链接
    3. public static Connection getConnection() throws ClassNotFoundException, SQLException{
    4. Class.forName("com.mysql.cj.jdbc.Driver");
    5. Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/_day_02","root", "abc280619SS");
    6. return conn;
    7. }
    8. // 封装方法关闭资源
    9. public static void close(AutoCloseable obj) {
    10. if (obj != null) {
    11. try {
    12. obj.close();
    13. } catch (Exception e) {
    14. e.printStackTrace();
    15. }
    16. }
    17. }
    18. }

    7. Batch 多语句操作

            在一次任务中执行多条语句

    1. public class JDBC_Batch {
    2. public static void main(String[] args) {
    3. // testStatement();
    4. testPrepareStatement();
    5. }
    6. // 使用Statement添加多条数据
    7. public static void testStatement() {
    8. Connection conn = null;
    9. Statement statement = null;
    10. try {
    11. conn = DBUtil.getConnection();
    12. statement = conn.createStatement();
    13. statement.addBatch("insert into user(name,password,nickname) values('test1',111,'用户1')");
    14. statement.addBatch("insert into user(name,password,nickname) values('test2',222,'用户2')");
    15. statement.addBatch("insert into user(name,password,nickname) values('test3',333,'用户3')");
    16. statement.executeBatch();
    17. System.out.println("添加成功");
    18. } catch (ClassNotFoundException | SQLException e) {
    19. e.printStackTrace();
    20. } finally {
    21. DBUtil.close(statement);
    22. DBUtil.close(conn);
    23. }
    24. }
    25. // 使用PrepareStatement添加多条数据
    26. public static void testPrepareStatement() {
    27. Connection conn = null;
    28. PreparedStatement preparedStatement = null;
    29. try {
    30. conn = DBUtil.getConnection();
    31. preparedStatement = conn.prepareStatement("insert into user(name,password,nickname) values(?,?,?)");
    32. preparedStatement.setString(1, "test1");
    33. preparedStatement.setInt(2, 111);
    34. preparedStatement.setString(3, "用户1");
    35. preparedStatement.addBatch();
    36. preparedStatement.setString(1, "test2");
    37. preparedStatement.setInt(2, 222);
    38. preparedStatement.setString(3, "用户2");
    39. preparedStatement.addBatch();
    40. preparedStatement.setString(1, "test3");
    41. preparedStatement.setInt(2, 333);
    42. preparedStatement.setString(3, "用户3");
    43. preparedStatement.addBatch();
    44. preparedStatement.executeBatch();
    45. System.out.println("添加成功");
    46. } catch (ClassNotFoundException | SQLException e) {
    47. e.printStackTrace();
    48. } finally {
    49. DBUtil.close(preparedStatement);
    50. DBUtil.close(conn);
    51. }
    52. }
    53. }

  • 相关阅读:
    github push 失败 git did not exit cleanly(exit code 128) 账号登录失败 解决经验
    PREPARE TO FAIL(OVER)
    maven 初学
    大数据与人工智能的交融:向量数据库在具体应用案例中的探索
    设计模式—创建型模式之单例模式
    基于Redis(SETNX)实现分布式锁,案例:解决高并发下的订单超卖,秒杀
    aarch64 麒麟v10系统使用docker部署nvidia_gpu_exporter监控GPU
    倾斜单体化模型技术实现
    猿创征文|Java之static关键字【实例变量与类变量、实例方法与类方法】
    【JavaEE】Java的前世今身
  • 原文地址:https://blog.csdn.net/apple_59745077/article/details/136306690