Java后台Servlet学习(二)


 

  首先纠正前一篇博客中的一个小问题,关于Get和Post两种请求,昨天翻了下室友的Android开发教程,看了下发送请求那一块,里面说到Get请求是想从服务端获取信息,Post只是想上传信息到服务端,但是有一点不明白,明明Post也有response对象,应该也能返回信息到客户端才对,区别还是不太懂。

  下面进入正题,这一篇博客主要是记录回顾JDBC的一些操作,以及遇到的一些问题

1.准备工作

  首先MySQL安装好不用多说,然后编译器我的是eclipse oxygen,相对上一次需要多准备的也就只有一个jar包,下载链接:https://dev.mysql.com/downloads/connector/j/ 

  

2.JDBC连接MySQL数据库

  我们首先来看一下官方给出的样例代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

// Notice, do not import com.mysql.cj.jdbc.*
// or you will have problems!

public class LoadDriver {
    public static void main(String[] args) {
        try {
            // The newInstance() call is a work around for some
            // broken Java implementations

            Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
        } catch (Exception ex) {
            // handle the error
        }
    }
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

Connection conn = null;
...
try {
    conn =
       DriverManager.getConnection("jdbc:mysql://localhost/test?" +
                                   "user=minty&password=greatsqldb");

    // Do something with the Connection

   ...
} catch (SQLException ex) {
    // handle any errors
    System.out.println("SQLException: " + ex.getMessage());
    System.out.println("SQLState: " + ex.getSQLState());
    System.out.println("VendorError: " + ex.getErrorCode());
}

  以上两段是官方给出的连接数据库的代码,第一部分是利用forName函数获取MySQL驱动,后面的newInstance可以不用写,forName中的参数是根据你MySQL的版本来的,这也就是我学习中遇到的第一个坑,最开始跟着网上的教程做一直连接不上数据库,因为之前的MySQL版本forName中的参数都是com.mysql.jdbc.Driver,而我下的最新版本是com.mysql.cj.jdbc.Driver,获取驱动之后就可以准备连接了Connection con = DriverManager.getConnection(String url),这一步只需要知道url的值就可以了,下面就讲一讲url的格式

  url:  "jdbc:mysql://" + 数据库所在的ip(本机就可以用localhost)+ "/" + 想要访问的数据库名 + "?" + "user=" + 数据库账号 + "&password=" + 账号对应的密码

  其实一般的访问的url链接也是跟这个差不太多的,这部分放到后面再继续说,不管怎么说连接数据库的部分算是结束了吧,毕竟根据官方的文档来写应该是没什么问题的,然而让我万万没想到的,就是有问题!

  这个的原因是时差,报错的信息中也有写到time zone对吧,所以网上查一查也就知道了,在url后面接上&serverTimezone=GMT就真正的连接成功啦,特别提醒url中不能有空格,所以像我这种写代码习惯数字和操作符用空格隔开的朋友需要注意。

3.利用JDBC对数据库进行操作

  首先来介绍一下JDBC对数据库进行操作的方式,目前就我了解到的就两种类,一个是Statement类,一个是PreparedStatement类

  先来介绍第一个Statement

  1)Statement对象的创建方式

    我们之前通过DriverManager.getConnection()函数已经获得了Connection对象con,而Statement对象则是通过con.createStatement()函数获得的,下面是官方的解释

  返回类型为Statement,作用生成一个Statement对象来发送SQL声明给数据库

  2)利用Statement对象进行数据库查询

    数据库查询用到的函数是executeQuery(String SQL),其实也很好理解,execute是执行的意思,query是查询的意思,这里函数返回的是一个ResultSet对象

    ResultSet的常用的操作就是next()函数和各种get函数,前一个是移动到下一行,如果后面没有了就返回false,有就返回true,get函数就比如getString、getInt等,传参的方式有int string两种,比如我user表中的是id(int)、username(String)、password(String),在执行ResultSet rs = execute("SELECT * FROM user")之后,我想获得第一行中的username就先rs.next();然后可以用String str = rs.getString(2);或者rs.getString("username");同样的想获得id可以使用int id = rs.getInt(1)或者rs.getInt("id");下面给出官方的说明

  

  

  3)利用Statement对象对数据库进行增、删、改操作

    在JDBC中update、delete、insert都被归纳成update,所以都通过executeUpdate(String sql)函数进行操作,返回值是操作的行数,这个就没什么好说的了,下面是官方的说明文档

  4)在不知道是查询还是更改的情况下

    在不知道是要查询还是更改的情况下,我们可以用execute(String sql)直接执行,但是这个函数的返回值是bool型,也就是在sql为查询语句的时候就返回true,在为更改语句的时候返回false,如果是查询语句,想要获得结果可以在Statement对象调用execute()函数之后再调用getResultSet()函数;如果是update语句,想要得到update的列数,可以可以在Statement对象调用execute()函数之后再调用getUpdateCountt()函数,下面是例子

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

// assume that conn is an already created JDBC connection (see previous examples)

Statement stmt = null;
ResultSet rs = null;

try {
    stmt = conn.createStatement();
    rs = stmt.executeQuery("SELECT foo FROM bar");

    // or alternatively, if you don't know ahead of time that
    // the query will be a SELECT...

    if (stmt.execute("SELECT foo FROM bar")) {
        rs = stmt.getResultSet();
    }

    // Now do something with the ResultSet ....
}
catch (SQLException ex){
    // handle any errors
    System.out.println("SQLException: " + ex.getMessage());
    System.out.println("SQLState: " + ex.getSQLState());
    System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
    // it is a good idea to release
    // resources in a finally{} block
    // in reverse-order of their creation
    // if they are no-longer needed

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException sqlEx) { } // ignore

        rs = null;
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException sqlEx) { } // ignore

        stmt = null;
    }
}

    到这里有关Statement的操作就讲解完毕,Statement的操作一般针对用不变的操作,输入的语句是固定的,不要说用String拼接,那样不安全比如固定好的语句为

        String sql = "SELECT password FROM user WHERE username=" +user_name;

    针对这种情况输入的是'OR'1'='1'时,执行的语句就发生了变化,所以针对Statement对象不要使用字符串拼接!

    那么要实现可以复用、更改的执行语句要用什么呢,下面就介绍第二种PreparedStatement

   1)创建PreparedStatement

     创建PreparedStatement对象的方式为con.prepareStatement(String sql)

String sql = "SELECT password FROM user WHERE username=?";
PreparedStatement  ps = con.prepareStatement(sql);

      ?就是未定的部分(注意=的左右不要有空格,不要有空格,不要有空格),可以利用ps.setString(int num,String str)函数拼接上去,但是利用这个函数拼接就不会出现问题,因为这个函数会把敏感符号全部转译,单引号这种符号也就只是一个单引号了,不会改变原来SQL语句的意思,还有一些setInt等操作、作用也是一样的 

      这里的第一个参数就表示是第几个?,第二个参数是要修改的值

   2)利用PreparedStatement对象对数据库进行查询操作

      由于在创建PreparedStatement对象的时候传入的sql语句,所以查询的时候就不需要额外传入参数了,直接调用executeQuery()函数即可,返回值仍然是ResultSet型

   3)利用PreparedStatement对象对数据库进行增、删、改

       同查询值要直接调用executeUpdate()函数即可,返回值还是更改的行数

 

    以上就是我掌握的JDBC的知识,这段时间在学习过滤器和监听器的操作,大概十天之后写关于这两个的操作吧

 

 

  

 

    

 

     

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM