• JDBC 1


    目录

    JDBC概括

    JAR包下载使用

     JDBC的操作步骤

    粗略步骤

    JDBC操作核心类:

    DriverManger:驱动管理器

    Connection:数据库连接对象

    Statements:sql语句执行

    ResultSet:结果查询

    sql注入

             概述

    解决

    例子:


    JDBC概括

        JDBC(Java与数据库连接):Java DataBase Connectivity

            此技术是Java提供的一种数据库操作技术,提供了统一标准,但是此技术不在JDK中,需要下载相应的JAR包。

            JAR包:其他人写好的类打包

    JAR包下载使用

    下载::https://mvnrepository.com/搜索mySQL

    使用步骤:

                     1,在项目的根目录下创建文件夹,这个文件夹必须命名为lib

                     2,将需要使用的jar包拷贝到lib文件夹下

                     3,选择jar包,点击右键选择add as libxxx

     JDBC的操作步骤

    粗略步骤

    1,加载驱动,反射的技术

            一个进程一次就行

            Class.forName("驱动类所在的包名.类名");

            如果不写的话也可以运行成功,这是因为JDBC4.0以后新增了新特性:JDBC4.0不再需要显式调用class.forName()注册驱动,DriverManager初始化中会通过ServiceLoader类,在我们classpath中jar(数据库驱动包)中查找,使用META-INF\services\java.sql.Driver文本中的类名称去注册。

    2,创建连接

            通过DriverManager建立连接

            Connection c = DriverManger.getConnection(数据库url,数据库账号, 数据库密码)

    3,获取sql语句执行对象

            //存在sql注入问题 Statement s = c.createStatement();

            //解决了sql注入问题 PreparedStatement s = c.prepareStatement(sql);

    4,执行sql语句

            //用于执行DML操作,返回值时受影响行数 int num = s.executeUpdate();

            //用于执行DQL操作,返回值时查询到的结果 ResultSet set = s.executeWQuery();

    5,处理结果

            根据需求处理

    6,关闭资源

            如果执行的时查询操作需要关闭查询结果集

            关闭sql语句执行

            关闭连接对象

    JDBC操作核心类:

    DriverManger:驱动管理器

            作用:获取连接

            提供的静态方法方法: Connection getConnection(url,username,password);

    1. Class.forName("com.mysql.jdbc.Driver");//使用反射获取类对象
    2. Connection connection = DriverManager.getConnection(URL, USER, PASSMI);
    3. //使用getConnection方法,驱动管理,获取连接

     URL:

    1. String URL = "jdbc:mysql://localhost:3306/zday0301?useSSL=false&characterEncoding=utf-8";
    2. url要写服务器地址和端口号,表名

    useSSL=false和true的区别:


                      SSL(Secure Sockets Layer 安全套接字协议),useSSL=false通过账号 密码进行连

                      接,跳过安全验证。useSSL=true是进行安全验证,mysql的版本是5.7之前会默

                      认useSSL=false。之后包括5.7则不会,为了能连接上使用useSSL=false。

                                         

    USER:数据库账号

    USER = "root";

    PASSMI:数据库密码

    PASSMI= "123456"

    Connection:数据库连接对象

            作用:获取sql语句执行对象,执行事物

            注意:默认自动提交

              提供的方法:

                            Statement createStatement(); //有sql注入风险

                            PreparedStatement prepareStatement(sql);    //解决了sql注入风险

                            CallableStatement prepareCall(String sql); //用于调用存储过程

                            void rollback();//回滚

                            void commit();//提交

                            c.setAutoCommit(false);设置是否自动添加,默认为true //

                            void setAutoCommit(boolean autoCommit);     关闭自动条件并开启事物

    Statements:sql语句执行

                    作用:执行sql语句

                    提供的方法:

      1. int executeUpdate():用于执行DML操作   数据的增加或删除

            返回值为int型,为多少行受到了影响

      2.ResultSet executeWQuery():用于执行DQL操作    数据的查询

            ResultSet 包含符合 SQL 语句中条件的所有行,并且它通过一套 get 方法(这些 get 方法可以访问当前行中的不同列)提供了对这些行中数据的访问。ResultSet.next 方法用于移动到 ResultSet 中的下一行,使下一行成为当前行,此方法是从表头开始移动的

      3.boolean execute():用于执行DDL操作

              Statements 的 子类: PreparedStatement

                                   作用:解决sql注入问题

                                         提供的方法:

                                                    setInt(?号的位置,替换?号的值);

                                                    setString(?号的位置,替换?号的值);

                                                                                            ...

                                                                            注意:?表示占位符,位置从1开始

                  Statements    子类: CallableStatement

                                                    作用:调用存储过程

    ResultSet:结果查询

                    作用:存储查询的结果

                    提供的方法:

                                    boolean next():移动游标

                                    getInt(列名);

                                    getString(列名);

    sql注入

             概述

            程序对用户输入数据的合法性没有判断和处理,导致用户可以在应用程序中事先定义好的 SQL 语句中添加额外的 SQL 语句,以此来实现欺骗数据库服务器,来执行非任意查询语句。

    例:恶意拼接查询

            SELECT * FROM users WHERE user_id = $user_id

    其中,$user_id 是传入的参数,

    如果传入的参数值为“1234; DELETE FROM users”,

    那么最终的查询语句会变为:

    SELECT * FROM users WHERE user_id = 1234; DELETE FROM users

    如果以上语句执行,则会删除 users 表中的所有数据。

    解决

    参数化查询:

            参数化查询目前被视作是预防 SQL 注入攻击最有效的方法。参数化查询是指在设计与数据库连接并访问数据时,在需要填入数值或数据的地方,使用参数(Parameter)来给值。
            MySQL 的参数格式是以“?”字符加上参数名称而成,如下所示:

    UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4

            在使用参数化查询的情况下,数据库服务器不会将参数的内容视为 SQL 语句的一部分来进行处理,而是在数据库完成 SQL 语句的编译之后,才套用参数运行。因此就算参数中含有破坏性的指令,也不会被数据库所运行。

            

    例子:

             做一个使用数据库登录注册功能

    1. import java.sql.*;
    2. import java.util.Scanner;
    3. public class Main {
    4. static {//静态只在类加载时加载一次
    5. try {
    6. Class.forName("com.mysql.jdbc.Driver");
    7. }catch (ClassNotFoundException e){
    8. e.printStackTrace();
    9. }
    10. }//加载驱动
    11. private static final String URL = "jdbc:mysql://localhost:3306/zday0301?useSSL=false&characterEncoding=utf-8";
    12. //url要写服务器地址和端口号,表名
    13. private static final String USER = "root";//数据库账号 上面的useSSL=false跳过安全验证,
    14. private static final String PASSMI= "123456";//数据库密码
    15. public static void main(String[] args) throws SQLException {
    16. login();
    17. // regisr();//调用两个方法
    18. }
    19. public static void regisr() throws SQLException {
    20. System.out.println("输入账号");
    21. Scanner scanner = new Scanner(System.in);
    22. String usrname = scanner.next();
    23. System.out.println("输入密码");
    24. String mima = scanner.next();
    25. System.out.println("输入性别");
    26. String sex = scanner.next();
    27. System.out.println("输入年龄");
    28. String age = scanner.next();
    29. Connection connection = DriverManager.getConnection(URL, USER, PASSMI);//驱动管理,获取连接
    30. Statement statement = connection.createStatement();//获取sql语句执行对象,执行事物
    31. String sql = "select u_username from yinhang where u_username='"+usrname+"'";//查询语句
    32. ResultSet set = statement.executeQuery(sql);//执行DQL操作
    33. //这东西返回的结果是个集合
    34. if (set.next()){//向下移动,从表头开始的,如果不能移动的那就一个数据都没有,能移动表名可移动,说明有重复的
    35. System.out.println("账号以存在");
    36. return;
    37. }
    38. String intoSQL = "insert into yinhang (u_username,u_mima,u_sex,u_age)values('"+usrname+"','"+mima+"','"+sex+"',"+age+")";//插入语句
    39. int i = statement.executeUpdate(intoSQL);//向里面插入数据,执行
    40. if (i>0){
    41. System.out.println("注册成功");
    42. }else {
    43. System.out.println("注册失败");
    44. }
    45. if (statement != null&&!statement.isClosed()){//不判断的话会空指针异常
    46. statement.close();
    47. }
    48. if (connection != null && !connection.isClosed()){
    49. connection.close();
    50. }
    51. }
    52. public static void login() throws SQLException {
    53. System.out.println("输入账号");
    54. Scanner scanner = new Scanner(System.in);
    55. String usrname = scanner.next();
    56. System.out.println("输入密码");
    57. Scanner scanner2 = new Scanner(System.in);
    58. String mima = scanner2.next();
    59. Connection connection = DriverManager.getConnection(URL, USER, PASSMI);//驱动管理,获取连接
    60. PreparedStatement statement = connection.prepareStatement( "select u_username from yinhang where u_username = ? and u_mima = ?");
    61. statement.setString(1,usrname);//前面的参数代表第几个?后面的参数代表需要替换的值
    62. statement.setString(2,mima);
    63. /*
    64. *
    65. Statement statement = connection.createStatement();//获取sql语句执行对象,执行事物
    66. String sql = "select u_username from yinhang where u_username="+"'usrname'"+"and"+" u_mima = "+ "'mima'";//查询语句
    67. ResultSet set = statement.executeQuery(sql);
    68. 用此方法会产生sql注入问题,一般插入删除会比较关注注入问题,需要用 PreparedStatement方法解决
    69. *
    70. */
    71. ResultSet set = statement.executeQuery();//执行dml操作
    72. System.out.println(set.next());
    73. //这东西返回的结果是个集合
    74. if (set.next()){//向下移动,从表头开始的,如果不能移动的那就一个数据都没有,能移动表名可移动,说明有重复的
    75. System.out.println("账号以存在");
    76. }
    77. if(set != null && !set.isClosed()){
    78. set.close();//关闭结果
    79. }
    80. if (statement != null && !statement.isClosed()){
    81. statement.close();//关闭提交
    82. }
    83. if (connection != null && !connection.isClosed()){
    84. connection.close();//关闭连接
    85. }
    86. }
    87. }

  • 相关阅读:
    【Spring Cloud】全面解析服务容错中间件 Sentinel 持久化两种模式
    for...in 和 for...of 的区别
    pytorch 使用DataParallel 单机多卡和单卡保存和加载模型的正确方法
    招聘| 嵌入式軟件(单片机)工程师
    基于opencv,卡尺工具
    liburl请求http
    JVM性能优化案例:优化垃圾回收器的年轻代和老年代占比
    Spring AOP
    包裹骨髓间充质干细胞/捕获内源性细胞因子的磺化/载有活性蛋白的壳聚糖水凝胶的制备与研究
    Mocha Pro 2024 v11.0.1 Mac版摄像机反求跟踪插件更新:优化AE/PR/OFX/达芬奇工作流程
  • 原文地址:https://blog.csdn.net/weixin_44207220/article/details/127677605