欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-29 07:57:34
1.JDBC介绍 jdbc(java database connectivity)为java开发者使用数据库提供了统一的编程接口,它由一组java类和接口组成。 JDBC需要用到的类和接口有: DriverManager、Connection、Statement、ResultSet 2. mysql ......

1.jdbc介绍

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

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

drivermanager、connection、statement、resultset         

 

2. mysql-connector-java下载

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

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

然后进入下载mysql-connector-java.jar包,用于连接mysql

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

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

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

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

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

 

3.jdbc使用过程

3.1 通过drivermanager. registerdriver(driver driver)来注册驱动程序

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

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

因为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为例:

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

 

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);        //释放资源
        }
    }

打印如下所示:

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

 

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);        //释放资源
        }
    }

运行打印:

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

查看数据库:

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

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);        //释放资源
        }
        
    }

查看数据库:

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

 

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;
                  }
 }