• 20.java-JDBC连接mysql数据库详解


    1.JDBC介绍

    jdbc(java database connectivity)为java开发者使用数据库提供了统一的编程接口,它由一组java类和接口组成。

    JDBC需要用到的类和接口有:

    DriverManager、Connection、Statement、ResultSet         

     

    2. mysql-connector-java下载

    本机的mysql版本是5.7.26 win32的,所以本章访问mysql都以该版本为例:

     

    然后进入https://dev.mysql.com/downloads/connector/j/下载mysql-connector-java.jar包,用于连接mysql

    如下图所示,只有8.0.19版本,那我们下载它就好了,反正不管64位还是32位都能访问:

     

    下载解压后,就有个mysql-connector-java-8.0.19.jar:

     

    接下来就来测试,能不能访问

     

    3.JDBC使用过程

    3.1 通过DriverManager. registerDriver(Driver driver)来注册驱动程序

    需要注意,new Driver的时候,需要选择com.mysql.cj.jdbc.Driver:

     

    因为com.mysql.jdbc.Driver已经被弃用了.

    PS:也可以直接将DriverManager. registerDriver(Driver driver)改为:

    Class.forName("com.mysql.cj.jdbc.Driver");
    //加载一下这个类就可以注册驱动,因为mysql Driver类的静态代码块中已经调用了registerDriver()来注册驱动程序.

    3.2 然后通过 Connection DriverManager.getConnection(String url, String user, String password)来连接数据库,并获取Connection对象

    url: 填入“jdbc:子协议://ip地址:端口号/数据库名” ,如果是mysql则填入“jdbc:mysql://localhost:3306/数据库名”

    针对mysql-connector-java-8.0以上的版本,则还要追加"?characterEcoding=utf-8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"

    username:mysql用户名

    password:mysql密码

    3.3 通过Connection对象获取statement对象

    Statement statement = connection.createStatement();

    3.4 通过statement对象的executeQuery(String)来执行查询sql语句,并返回ResultSet数据库结果集

    比如:

    ResultSet  resultSet = statement. executeQuery("select * from student");       //获取student表里的数据

    除此之外还有int executeUpdate(String sql)方法.用来实现INSERT、UPDATE 或 DELETE 语句,返回值表示执行sql语句之后影响到的数据行数 (后面示例有讲)

    3.5 然后通过ResultSet来读出query内容

    ResultSet常用方法如下:

    boolean first();             //移到内容第一行数据处
    
    boolean  last();             //移到内容最后一行数据处
    
    int getRow() ;             //获取当前光标处于的行号
    
    boolean isLast()           //获取光标是否位于此 ResultSet 对象的最后一行。
    
    boolean   next();          //移到下一行数据处,然后就可以通过getXXX()获取完当前一行数据后,则通过next()来移动到下行继续getXXX(),直到next()返回为false为止
    
    boolean   previous();     //移到上一行数据处
    
    String getString(String columnLabel);  //获取当前一行的columnLabel列名的内容                             
    
    String  getString(int columnIndex);   //获取当前一行的第columnIndex列的内容,第一列是从1开始的.
    
             String getInt (String columnLabel);  //获取当前一行的columnLabel列名的内容                     
    
    String  getInt(int columnIndex);  //获取当前一行的第columnIndex列的内容,第一列是从1开始的.
    
     
    //...除此之外,还有getFloat(),getLong(),getShort(),getURL(),getBoolean(),getRowId()

     PS:获取到ResultSet后,必须先next()一次才能getXXX(),来获取内容

     

    3.6 访问结束后,释放Mysql资源(毕竟mysql连入个数是有限的) 

        try {
                if(resultSet!=null){
                resultSet.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } 
            try {
                if(statement!=null){
                statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

    4.本章要访问的数据库以students为例:

     

    5.首先来写JdbcUtils工具类

    JdbcUtils工具类里主要写getConnection(),releaseResc()这两个类,这样避免后续的重复代码产生.

    JdbcUtils.java代码如下所示:

    public class JdbcUtils {
    
        private static String driver;
        private static String url;
        private static String user;
        private static String pwd;
    
        static{
            
            driver = "com.mysql.cj.jdbc.Driver";
            url = "jdbc:mysql://localhost:3306/students?characterEcoding=utf-8&"    
                    + "useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
        
            user = "root";
            pwd = "sql";
            
        }
        
        
        //获取一个链接mysql的Connection对象
        static public Connection getConnection(){
            
            try {
                Class.forName(driver);
                 Connection connection = DriverManager.getConnection(url,user,pwd);
                 return connection;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            
        }
        
        /**
         * 释放Mysql资源(毕竟mysql连入个数是有限的)    
         * @param resultSet 结果集
         * @param statement 
         * @param connection 链接
         */
        public static void releaseResc(ResultSet resultSet, Statement statement, Connection connection) {
        
            try {
                if(resultSet!=null){
                resultSet.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } 
            try {
                if(statement!=null){
                statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    6.数据库查询示例

    查询所有学生的信息:

    @Test
        public void jdbcQuery(){
            
            ResultSet resultSet = null;
            Statement statement = null;
            Connection connection = null;
            try {
                connection = JdbcUtils.getConnection();        //通过JdbcUtils获取connection
                statement = connection.createStatement();
                
                String sql = "select * from student";
                
                resultSet = statement.executeQuery(sql);
            
                while(resultSet.next()){
                    
                    String name = resultSet.getString("name");
                    String score = resultSet.getString("score");
                    String classs = resultSet.getString("class");
                    
                    System.out.println("姓名:"+name+"  成绩:"+score+"  班级:"+classs);
                }
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                
                JdbcUtils.releaseResc(resultSet, statement, connection);        //释放资源
            }
        }

    打印如下所示:

     

    7.数据库插入示例

    @Test
        public void jdbcInser(){
            
            ResultSet resultSet = null;
            Statement statement = null;
            Connection connection = null;
             
            try {
                connection = JdbcUtils.getConnection();
                statement = connection.createStatement();
                
                String name = "小f";
                int score = 99;
                String classs = "初2-4班";
                
                String sql = "INSERT INTO  student(name,score,class) "        
                           +" values('"+name+"','"+String.valueOf(score)+"','"+classs+"')";
                
                int result = statement.executeUpdate(sql); 
                //executeUpdate:用来实现INSERT、UPDATE 或 DELETE 语句,返回值表示执行sql语句之后影响到的数据行数 
                
                System.out.println("插入了"+result+"条数据");
                
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                
                JdbcUtils.releaseResc(resultSet, statement, connection);        //释放资源
            }
        }

    运行打印:

     

    查看数据库:

     

    8.数据库更新示例

    将所有低于60分的同学的成绩改为0:

    @Test
        public void jdbcUpdate(){
            
            ResultSet resultSet = null;
            Statement statement = null;
            Connection connection = null;
            
            try {
                connection = JdbcUtils.getConnection();
                 statement = connection.createStatement();
                
            
                String sql = "update student  SET score='0'  WHERE  score<60";
                
                
                int result = statement.executeUpdate(sql); 
                //executeUpdate:用来实现INSERT、UPDATE 或 DELETE 语句,返回值表示执行sql语句之后影响到的数据行数 
                
                System.out.println("更新了"+result+"条数据");
                
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                
                JdbcUtils.releaseResc(resultSet, statement, connection);        //释放资源
            }
            
        }

    查看数据库:

     

    9.SQL 注入攻击

    Statement采取直接编译 SQL 语句的方式,扔给数据库去执行,所以很容易进行被SQL注入攻击.

    比如:

    我们登陆执行时需要执行:

    statement.executeQuery("select id from users where name ='"+username+"' and password = '"+password+"'");

    而黑客则将字符串直接改为:

    statement.executeQuery("select id from users where name ='"+username+"' or '1==1' and password = '"+password+"'");

    就可以直接乱输入密码也能实现登录了,所以java中提供了另一个类PreparedStatement, 采用"?"占位符预编译,再填充参数,用来避免SQL注入攻击.

    PreparedStatement类介绍

    采用"?"占位符预编译,再填充参数,然后通过setXXX()来填充参数.比如setString():

    setString(int parameterIndex, String x);       //向第parameterIndex个占位符填入x内容
    // parameterIndex:第一个?占位符是1,第二个是2....
    
    //...除了该方法之外,还有setFloat(),setLong(),setBoolean()....等等

    修改登录界面之PreparedStatement使用如下所示:

    public static boolean login(String username,String password){
              Connection connection = JdbcUtils.getConnection();                  //获取
                      try {
    
                              String sql = "select id from users where username =? and password = ?"; //要运行的sql语句,通过?来替换登录账号和密码
    
                              PreparedStatement preparedStatement = connection.prepareStatement(sql);
    
                              //第一个? 用username字符串去替换
                              preparedStatement.setString(1, username);
    
                              //第二个? 用password字符串去替换
                              preparedStatement.setString(2, password);
    
                              ResultSet resultSet = preparedStatement.executeQuery();
    
                              return resultSet.next();            //有值则返回true,否则返回false;
    
                      } catch (SQLException e) {
                              e.printStackTrace();
                              return false;
                      }
     }

     

     

     

     

  • 相关阅读:
    最精简的django程序
    spring+mongo
    从零搭建mongo分片集群的简洁方法
    java对redis的基本操作
    awk输出指定列
    sed输出指定行
    Bash的循环结构(for和while)
    用ffmpeg切割音频文件
    Python判断字符串是否全是字母或数字
    Python函数: any()和all()的用法
  • 原文地址:https://www.cnblogs.com/lifexy/p/12193035.html
Copyright © 2020-2023  润新知