首先纠正前一篇博客中的一个小问题,关于Get和Post两种请求,昨天翻了下室友的Android开发教程,看了下发送请求那一块,里面说到Get请求是想从服务端获取信息,Post只是想上传信息到服务端,但是有一点不明白,明明Post也有response对象,应该也能返回信息到客户端才对,区别还是不太懂。
下面进入正题,这一篇博客主要是记录回顾JDBC的一些操作,以及遇到的一些问题
1.准备工作
首先MySQL安装好不用多说,然后编译器我的是eclipse oxygen,相对上一次需要多准备的也就只有一个jar包,下载链接:https://dev.mysql.com/downloads/connector/j/
Select Operating System选择Platform Independent(平台无关),下载好压缩包之后解压,复制mysql-connector-java-8.0.13.jar到 WebContent > WEB-INF > lib 文件夹下,并Add to build Path。接下来就可以直接用了。
2.JDBC连接MySQL数据库
我们首先来看一下官方给出的样例代码
importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;//Notice, do not import com.mysql.cj.jdbc.*//or you will have problems!
public classLoadDriver {public static voidmain(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
}
}
}
importjava.sql.Connection;importjava.sql.DriverManager;importjava.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()函数,下面是例子
importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;importjava.sql.Statement;importjava.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的知识,这段时间在学习过滤器和监听器的操作,大概十天之后写关于这两个的操作吧