好快,已经是12月份了,11月5日开的班。就快学习一个月了,总学习时间是四个月。过年休息9天,这样到明年3月14日课程就结束了。好好学习,回去找个好工作!
今日是JDBC的第一天,JDBC的基础应用。以后在WEB开发中的使用方式。课程中,方老师上午在讲解JDBC基础的同时做了一个JDBC练习程序,对JDBC的基础应用。下午,方老师做了一个使用数据库的WEB应用,用户注册、登录、用户信息修改。
先让我们来了解一下JDBC(Java Data Base Connectivity)基础吧!
我们都知道数据库都提供一些接口,用户使用这些接口操作数据库。这就是数据库驱动!常见的数据库有MySQL、Oracle、SQLServer、DB2等,这些数据库提供的接口都不一样,难道开发人员使用不同的数据库就要学习不同的驱动接口吗?JDBC正是为统一数据库访问接口而实现的,SUN公司提出了这一接口。数据库公司都去实现这一接口。大大方便了,编程人员对数据库的操作:
在工程中使用JDBC,必须导入相应的JAR包。比如使用MySQL数据库,必须导入MySQL实现的JDBC jar包。可以到http://dev.mysql.com/downloads/下载。
使用JDCB进行数据访问的基本流程,见代码:
隐藏行号 复制代码 ? 这是一段程序代码。
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.ResultSet;
-
import java.sql.SQLException;
-
import java.sql.Statement;
-
-
public class JDBCTemp {
-
-
public static void main(String[] main) throws Exception {
-
// 1.装
-
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
-
/*
-
* 因om.mysql.jdbc.Driver在
-
* 上om.mysql.jdbc.Driver,
-
* 所
-
*/
-
Class.forName("com.mysql.jdbc.Driver");
-
// 2.连
-
Connection conn = DriverManager.getConnection(
-
"jdbc:mysql://localhost:3306/databasename", "username",
-
"password");
-
// 3.创QL语tatement对
-
Statement sta = conn.createStatement();
-
// 4.执QL语
-
boolean ok = sta.execute("select * from user;");
-
-
// 5.遍
-
ResultSet rs = null;
-
if(ok){
-
rs = sta.getResultSet();
-
while(rs.next()){
-
rs.getInt(1);
-
//...
-
}
-
}
-
-
// 6.释esultSet、tatement、onnection这
-
// 必
-
// 下
-
if(rs != null){
-
try {
-
rs.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
rs = null;
-
}
-
-
if(sta != null){
-
try {
-
sta.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
sta = null;
-
}
-
-
if(conn != null){
-
try {
-
conn.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
conn = null;
-
}
-
}
-
}
-
上面的代码只为演示,继续向下学习就会发现其中的一些问题。
其中
DriverManager.getConnection("jdbc:mysql://localhost:3306/databasename", "username","password");
|
GetConnection的第一个参数“jdbc:mysql://localhost:3306/databasename
”,它的各段含义如下:
Jdbc:协议
Mysql:子协议
localhost:主机
3306:端口
databasename:数据库名
常见的URL如下:
Oracle :jdbc:oracle:thin:@localhost:1521:sid
SQLServer:jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid
MYSQL:jdbc:mysql://localhost:3306/sid
如果把上面的代码用于用户登录或查询数据时,会造成一个严重的安全漏洞——SQL注入!
例,根据提交的用户名查找用户:
"select id,name,password from user where name='"+name+"'";
|
如果用户提交的用户名是:“’ or 1=1 or 1=‘”,会发生什么问题?因为在where过滤时使用了or逻辑,其有的1=1返回真,结果可以正常通过验证。这是一个十分严重的安全漏洞!
为此Java为我们提供了PreparedStatement接口,表示预编译的 SQL 语句的对象。SQL 语句被预编译并存储在 PreparedStatement 对象中,然后可以使用此对象多次高效地执行该语句。PreparedStatement的使用:
PreparedStatement ps = conn.prepareStatement("select id,name,password form user where name=? and passowrd=?");
ps.setString(1, name);
ps.setString(2, password);
|
这样就可以解决SQL注入的漏洞,同时也可以高效的执行SQL语句。上面的使用方法一眼就看出来了,一个“?”对应下边的ps.setXXX方法,按照“?”先后,对应ps.setXXX第一个参数的索引!
我们使用Statement. execute执行了查询语句,Statement还有其他以execute开头的方法,具体针对查询和增加、删除、修改的方法,在此就不一一说明了。JDK手册里边有详细说明。
查询成功后,在Statement对象中,可以获得记录集对象ResultSet,查询的结果全都保存在ResultSet中吗?仔细想想,好像是。如果有1亿条记录符合查询条件,同时有1000个用户调用同一查询,那服务器不烧了吗!所以查询的结果并未保存在ResultSet中,而是保存在数据库中,ResultSet指向数据库的引用。这样很方便也很快捷!那数据库会不会被充爆了?当然不会,数据本身就保存在数据库中,数据库的查询结果顶多就保存的指向数据的“指针”。
ResultSet对象内部有一个游标,游标初始位置是第一条记录前。必须调用它的next()方法,才会到第一条记录,依次向下。如果不存在记录,或者已经到记录尾,则返回false。存在记录返回true。然后我们可以通过调用它的getObject、getInt、getString…方法调用相应的值,如果只使用getObject获取记录值,必须使用强转将它转换为我们需要的类型。
下面是常用数据类型转换表(老方整理的,嘿嘿):
SQL类型
|
Jdbc对应方法
|
返回类型
|
BIT
|
getBoolean()
|
Boolean
|
TINYINT
|
getByte()
|
Byte
|
SMALLINT
|
getShort()
|
Short
|
int
|
getInt()
|
Int
|
BIGINT
|
getLong()
|
Long
|
CHAR,VARCHAR,LONGVARCHAR
|
getString()
|
String
|
Text Blob
|
getColb() getBlob()
|
Clob blob
|
DATE
|
getDate()
|
Java.sql.Date
|
TIME
|
getTime()
|
Java.sql.Time
|
TIMESTAMP
|
getTimestamp()
|
Java.sql.Timestamp
|
关于使用JDBC进行CURD的操作比较简单,因为昨天已经学习了在控制台有使用这些操作,在此就不多进行复习了。但一定要记住每次使用完数据库连接时,一定要释放。一是因为数据库有同时连接数量限制,二是因为数据连接会占用服务器资源。安全释放这些连接,参看上边的释放代码。常规的项目开发中,会将对数据库的操作封装到一个类中,这样方便使用。
在常规项目开发中,我们需要编写操作数据的DAO类。因为对数据库的一些操作需要处理异常,为了查错直观一些。我们在环绕这些异常时,将它们包装一下再抛出。如何包装异常?JAVA的包装类很多,我们的包装也是通过这个方法实现的。编写一个继承处Exception类的子类,然后将接收的异常存到父亲类中,我们也可以在自定义类中添加些自己的提示信息。这样当程序运行时抛出的异常,可以直观的定位到错误类。这是一个十分好的方法,用在其他地方。也有相当的功效!
最后一个问题,数据库中的中文乱码问题。其实并不是数据库的原因 ,因为我们在创建数据库时可以指定它的编码为utf8、gb2312或gbk等支持中文的编码。WEB应用读写数据库时造成的乱码,主要是由于WEB应用使用的编码与数据库使用的编码不统一。统一一下,就可以解决了!
老方有给大家留作业,今天的作业内容较多。主要是为了练习数据库的操作和数据库与WEB的组合应用。之前都是使用XML或配置文件做为伪数据库与WEB组合练习的,从今天起用上数据库了。虽然并不是十分兴奋,但离框架和项目练习越来越近了,这让我感觉很好!
以前并未使用JAVA开发过项目,虽然学习JAVA对我已经没什么难度。但上课这些天来,有时用到IO和集合,还是让我卡了一下。因为我并未系统的学习过它们,我应该系统的学习一下它们了。越是学习应该越是快乐,越学习应该越是简单。没有学习基础那么枯燥,就围绕那基础搞来搞去,用起来了才舒服。因为基础学习好了,所以感觉应用就简单的。其实应用并不简单,即使不说基础,应用中的模式与框架是相当重要的,有使用过程语言开发的同志,我想对此有很大的感想!
我要学好项目的架构,文档的编写与项目管理,这在以后工作中是相当重要的。