zoukankan      html  css  js  c++  java
  • 原生JDBC

    JDBC
    Java DataBase Connectivity,java数据库连接,是一种用于执行SQL语句的Java API。
    JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。

    驱动
    JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。

    JDBC规范(掌握四个核心对象
    DriverManager:用于注册驱动
    Connection: 表示与数据库创建的连接
    Statement: 操作数据库sql语句的对象
    ResultSet: 结果集或一张虚拟表

    使用JDBC技术,通过mysql提供的驱动程序,操作数据库实现步骤:
    1.注册驱动
    告知JVM我们使用的是什么驱动程序(mysql,oracle....)
    DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用
    原因有2个:
    >导致驱动被注册2次。
    >强烈依赖数据库的驱动jar
    解决办法:
    Class.forName("com.mysql.jdbc.Driver");
    2.获取数据库的连接
    数据库是TCP程序服务器,连接服务器(通过3次握手)
    就相当于建立了一条java程序通往数据库服务器的连接通路
    static Connection getConnection(String url, String user, String password)
    试图建立到给定数据库 URL 的连接。
    参数说明:url 需要连接数据库的位置(网址) user用户名 password 密码
    例如:getConnection("jdbc:mysql://localhost:3306/day06", "root", "root");
    URL:SUN公司与数据库厂商之间的一种协议。
    jdbc:mysql://localhost:3306/day06
    协议子协议 IP :端口号数据库
    mysql: jdbc:mysql://localhost:3306/day04或者jdbc:mysql:///day14(默认本机连接)
    oracle数据库: jdbc:oracle:thin:@localhost:1521:sid
    3.获取执行者对象
    执行SQL语句的对象,作用就是执行SQL
    接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
    Statement createStatement(); //创建操作sql语句的对象
    4.执行SQL语句,获取结果集
    使用执行者对象执行SQL语句
    获取SQL语句的结果集(增删改:整数,执行有效行数 查询:返回的就是一个结果集)
    常用方法:
    ? int executeUpdate(String sql); --执行insert update delete语句.
    ? ResultSet executeQuery(String sql); --执行select语句.
    ? boolean execute(String sql); --仅当执行select并且有结果时才返回true,执行其他的语句返回false.
    5.处理结果集
    ResultSet实际上就是一张二维的表格,我们可以调用其boolean next()方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,这时就可以使用ResultSet提供的getXXX(int col)方法(与索引从0开始不同个,列从1开始)来获取指定列的数据:
    rs.next();//指向第一行
    rs.getInt(1);//获取第一行第一列的数据
    常用方法:
    ? Object getObject(int index) / Object getObject(String name) 获得任意对象
    ? String getString(int index)/ String getString(String name) 获得字符串
    ? int getInt(int index)/int getInt(String name) 获得整形
    ? double getDouble(int index)/ double getDouble(String name) 获得双精度浮点型
    6.释放资源
    与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。
    使用JDBC对数据库进行增删改查代码演示:

      1 public static void main(String[] args) throws Exception {
      2         //1.注册驱动
      3         Class.forName("com.mysql.jdbc.Driver");
      4         //2.获取数据库连接
      5         String url = "jdbc:mysql://localhost:3306/mybase4";
      6         String user = "root";
      7         String password = "root"; 
      8         Connection conn = DriverManager.getConnection(url, user, password);
      9         //3.获取执行者对象
     10         Statement stat = conn.createStatement();
     11         //调用更新数据的方法
     12         //update(stat);
     13         //调用删除数据的方法
     14         //delete(stat);
     15         //调用增加数据的方法
     16         //insert(stat);
     17         //调用查询数据的方法
     18         select(stat);
     19         //6.释放资源
     20         stat.close();
     21         conn.close();
     22     }
     23 
     24     /*
     25      * 使用JDBC技术,查询数据库中表的数据
     26      */
     27     private static void select(Statement stat) throws Exception {
     28         //拼接sql语句
     29         String sql = "SELECT * FROM category";
     30         /*
     31          * 4.执行sql语句
     32          * 使用Statement中的方法
     33          * ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 
     34          * 返回值ResultSet标准接口的实现类对象,实现类对象由mysql驱动提供,可以使用ResultSet接口接收
     35          */
     36         ResultSet rs = stat.executeQuery(sql);
     37         System.out.println(rs);//com.mysql.jdbc.JDBC4ResultSet@1acb189
     38         /*
     39          * 5.处理结果
     40          * ResultSet中有一个方法
     41          * boolean next() 将光标从当前位置向前移一行。
     42          * 如果新的当前行有效,则返回 true;如果不存在下一行,则返回 false 
     43          * 如果有结果集返回true,若果没有结果集返回false
     44          * 相当于迭代器中的hasNext方法
     45          */
     46         while(rs.next()){
     47             /*
     48              * next返回true,有结果集
     49              * 取出结果集
     50              * 使用ResultSet中的方法getXXX(参数);
     51              * 参数:
     52              *     int columnIndex:列所在的索引,从1开始
     53              *     String columnLabel:列名
     54              * 注意:
     55              *     如果使用getInt,getDouble指定数据类型的方法,返回值就是对应的数据类型
     56              *     如果使用getObject方法返回值是object类型(只是打印可用)
     57              * 如果使用getString方法返回值是String类型
     58              */
     59             /*int i1 = rs.getInt(1);
     60             String s2 = rs.getString(2);
     61             System.out.println(i1+"	"+s2);*/
     62             
     63             //System.out.println(rs.getObject(1)+"	"+rs.getObject(2));
     64             System.out.println(rs.getObject("cid")+"	"+rs.getObject("cname"));
     65             //5.释放资源
     66             rs.close();
     67         }
     68     }
     69 
     70     /*
     71      * 使用JDBC技术,对数据库中的表数据进行增加
     72      */
     73     private static void insert(Statement stat) throws SQLException {
     74         //拼接sql语句
     75         String sql = "INSERT INTO category(cname) VALUES('玩具')";
     76         //4.执行sql语句
     77         int row = stat.executeUpdate(sql);
     78         //5.处理结果
     79         if(row>0){
     80             System.out.println("增加数据成功!");
     81         }else{
     82             System.out.println("增加数据失败!");
     83         }
     84         
     85     }
     86 
     87     /*
     88      * 使用JDBC技术,对数据库中的表数据进行删除
     89      */
     90     private static void delete(Statement stat) throws Exception {
     91         //拼接sql语句
     92         String sql = "DELETE FROM category WHERE cid=5";
     93         //4.执行sql语句
     94         int row = stat.executeUpdate(sql);
     95         //5.处理结果
     96         if(row>0){
     97             System.out.println("删除数据成功!");
     98         }else{
     99             System.out.println("删除数据失败!");
    100         }
    101     }
    102 
    103     /*
    104      * 使用JDBC技术,对数据库中的表数据进行更新
    105      */
    106     private static void update(Statement stat) throws Exception {
    107         //拼接sql语句
    108         String sql = "UPDATE category SET cname='鞋帽' WHERE cid=6";
    109         //4.执行sql语句
    110         int row = stat.executeUpdate(sql);
    111         //5.处理结果
    112         if(row>0){
    113             System.out.println("更新数据成功!");
    114         }else{
    115             System.out.println("更新数据失败!");
    116         }
    117     }
     1 JDBC工具类
     2 “获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象的方法,从而达到代码的重复利用。
     3 代码演示:
     4 public class JDBCUtils {
     5     
     6     //私有构造方法,防止外界创建对象调用方法
     7     private JDBCUtils() {
     8     }
     9     
    10     //定义Connectionn变量
    11     private static Connection conn;
    12     
    13     //保证代码只执行一次,可以放入静态代码块中
    14     static{
    15         try {
    16             //注册驱动
    17             Class.forName("com.mysql.jdbc.Driver");
    18             //获取连接
    19             String url="jdbc:mysql://127.0.0.1:3306/mybase4";
    20             String user="root";
    21             String password = "root";
    22             conn = DriverManager.getConnection(url, user, password);
    23         } catch (Exception e) {
    24             //注意,如果连接数据库失败,停止程序
    25             throw new RuntimeException(e+"连接数据库失败");
    26         }
    27     }
    28     
    29     //创建一个静态方法,获取数据库连接对象,并返回
    30     public static Connection getConnection(){
    31         return conn;
    32     }
    33     
    34     /*
    35      * 创建一个静态方法,对资源进行释放
    36      * ResultSet rs
    37      * Statement stat
    38      * Connection conn
    39      */
    40     public static void close(ResultSet rs,Statement stat,Connection conn){
    41         try {
    42             if(rs!=null){
    43                 rs.close();
    44             }
    45         } catch (SQLException e) {
    46             e.printStackTrace();
    47         }
    48         try {
    49             if(stat!=null){
    50                 stat.close();
    51             }
    52         } catch (SQLException e) {
    53             e.printStackTrace();
    54         }
    55         try {
    56             if(conn!=null){
    57                 conn.close();
    58             }
    59         } catch (SQLException e) {
    60             e.printStackTrace();
    61         }
    62     }
    63 }

    sql注入问题
    SQL注入:用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义。
    假设有登录案例SQL语句如下:
    SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;
    此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’ OR ‘a’=’a时,则真正执行的代码变为:
    SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’a’=’a’;
    此时,上述查询语句时永远可以查询出结果的。那么用户就直接登录成功了,显然我们不希望看到这样的结果,这便是SQL注入问题。
    为此,我们使用PreparedStatement来解决对应的问题。

    preparedStatement:预编译对象,是Statement对象的子类。
    特点:
    性能高
    会把sql语句先编译
    能过滤掉用户输入的关键字。

    PreparedStatement预处理对象,处理的每条sql语句中所有的实际参数,都必须使用占位符?替换。
    String sql = "select * from user where username = ? and password = ?";
    PreparedStatement使用,需要通过以下3步骤完成:
    1.PreparedStatement预处理对象代码:
    获得预处理对象,需要提供已经使用占位符处理后的SQL语句
    PreparedStatement psmt = conn.prepareStatement(sql)
    2.设置实际参数
    void setXxx(int index, Xxx xx) 将指定参数设置指定类型的值
    参数1:index 实际参数序列号,从1开始。
    参数2:xxx 实际参数值,xxx表示具体的类型。
    例如:
    setString(2, "1234") 把SQL语句中第2个位置的占位符?替换成实际参数 "1234"
    3.执行SQL语句:
    int executeUpdate(); --执行insert update delete语句.
    ResultSet executeQuery(); --执行select语句.
    boolean execute(); --执行select返回true 执行其他的语句返回false.

  • 相关阅读:
    [MacOS]Sublime text3 安装(一)
    [RHEL8]开启BBR
    PAT Advanced 1136 A Delayed Palindrome (20分)
    PAT Advanced 1144 The Missing Number (20分)
    PAT Advanced 1041 Be Unique (20分)
    PAT Advanced 1025 PAT Ranking (25分)
    PAT Advanced 1022 Digital Library (30分)
    PAT Advanced 1019 General Palindromic Number (20分)
    PAT Advanced 1011 World Cup Betting (20分)
    PAT Advanced 1102 Invert a Binary Tree (25分)
  • 原文地址:https://www.cnblogs.com/caigq/p/7049215.html
Copyright © 2011-2022 走看看