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

2022-10-10,,,,

1.jdbc介绍

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

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

drivermanager、connection、statement、resultset         

 

2. mysql-connector-java下载

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

 

然后进入下载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;
                  }
 }

 

 

 

 

 

 

《20.java-JDBC连接mysql数据库详解.doc》

下载本文的Word格式文档,以方便收藏与打印。