您的位置:首页 > 编程语言 > Java开发

javaweb_day11 JDBC 总结

2013-05-13 20:59 931 查看
JDBC开发(java data base connectivity)

由sun公司定义了一套JAVA操作数据的规范,称之为JDBC.

由java.sql javax.sql 2个jar包组成.

数据库厂商提供 用来操作数据库用的驱动,本质是很多的接口.

由于所有的数据库都遵循JDBC规范,我们在学习和使用数据库时只要学习JDBC中 的接口就可以了.

开发JDBC应用需要

步骤:

编写代码注意:导入接口,不导实现,降低耦合.

创建数据库,创建表,插入数据

导入mysql数据库驱动

1注册数据库驱动:

DriverManager.registerDriver(new Driver()); 观察mysql源码发现次方法在数据库里面注册了2次 耦合性低

推荐使用Class.forName(“com.mysql.jdbc.Driver”);

2获取数据库连接:

Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/Day11","root","root");

如果默认是访问本机的,localhost:3306可以省略

常用数据库url地址的写法;

oracle写法; jdbc:oracle:thin:@localhost:1521:sid

sqlServer写法:jdbc:microsoft:sqlServer://localhost:1443;DatabaseName=sid

mysql: jdbc:mysql://localhost:3306/si

~url可以接的参数,user.password 以及useUnicode=true&characterEncoding=gbk

3 获取传输器对象: conn,creatStatement

createStatement():创建向数据库发送sql的statement对象。

prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。

4利用传输器对象传入并执行sql语句,获取结果及对象 :

stat.executeQuery();

executeQuery()只支持查询,用于向数据发送查询语句。

executeUpadate() 支持增删改,用于向数据库发送insert、update或delete语句

execute() 支持增删改查,用于向数据库发送任意sql语句

ResultSet.next() 游标

用户的注册和登录案例:

注意:接口上要写注视,实例上可不写

sql注入.

prepaeredStatement 优势

还可以进行sql语句结构相同但是参数不同的插入

5遍历结果集 获取数据打印

ResultSet以表的样式在内存中保存,其中还维护一个游标,最开始的适合游标在第一行之前(表头),

每调用一次next()方法就试图下移一行,如果下移成功就返回true.

ResultSet还提供了很多个get方法,用来获取查询结果中的不同类型的数据.

除了next()方法还有以下方法可以用来遍历结果集:

Previous():移动到前一行

absolute(int row):移动到指定行

beforeFirst():移动resultSet的最前面。

afterLast() :移动到resultSet的最后面。

6使用完立即释放资源: 先创建的后释放.

rs.close(); 占用内存,所以使用完后也要释放

stat.close();占用内存,所以使用完后也要释放

conn.close(); connection是一个有限的资源,用完就要立即释放表

if(rs != null){

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

} finally{

rs = null;

}

}

if(stat != null){

try {

stat.close();

} catch (SQLException e) {

e.printStackTrace();

} finally{

stat = null;

}

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

} finally{

conn = null;

}

}

sql注入:

由于JDBC程序在执行的过程中sql语句在拼装时使用了由页面传入参数,

如果用户恶意传入一些sql中的特殊关键字,会导致sql语句意义发生变化,这种攻击方式就叫做sql注入.

prepaeredStatement来防止sql注入:

是Statement的孩子,不同的是prepaeredStatement使用预编译机制,在创建prepaeredStatement对象是就需要将sql语句传入,传入过程中参数使用?代理,

这个过程会导致传入的sql被进行预编译,然后调用prepaeredStatement的setXXXX方法将参数设置上去,由于sql语句已经经过了预编译,再传入特殊值也不会起作用.

prepaeredStatement使用了预编译机制,sql语句在执行的过程中比Statement效率要高.

四 JDBC大数据:

插入大文本:

在mysql数据库也可以支持在数据库中保存大文本和大二进制数据

Text

TINYTEXT(255)、TEXT(64k)、MEDIUMTEXT(16M)和LONGTEXT(4G)

Blob(Oracle里面是CLOB)

TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB

插入大文本步骤:

ps = conn.prepareStatement("insert into Demo2Text values(null,?,?)");

ps.setString(1, "钢铁是怎样练成");

File file = new File("1.txt");

ps.setCharacterStream(2, new FileReader(file), (int) file.length());

ps.setCharacterStream(,,int) 是JDL1.2开始有的;ps.setCharacterStream(,,long)s JDK1.7才有的

引发的三个异常的问题:

//1.Exception in thread "main" java.lang.AbstractMethodError: com.mysql.jdbc.PreparedStatement.setCharacterStream(ILjava/io/Reader;J)V

//ps.setCharacterStream(2, new FileReader(file), file.length());第三个参数是long型的是从1.6才开始支持的,驱动里还没有开始支持。

//解决方案:ps.setCharacterStream(2, new FileReader(file), (int)file.length());

//2.Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

//文件大小过大,导致PreparedStatement中数据多大占用内存,内存溢出

//-Xms256M-Xmx256M

//3.com.mysql.jdbc.PacketTooBigException: Packet for query is too large (10886466 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.

//数据库连接传输用的包不够大,传输大文本时报此错误

//在my.ini中配置max_allowed_packet指定包的大小,在my.ini中配置max_allowed_package=64m, 然后重新启动mysql

查询大文本步骤:

Reader rd=rs.getCharacterStream("content");

插入大二进制数据步骤:

ps = conn.prepareStatement("insert into Demo3Blob values(null,?,?)");

ps.setString(1, "梦想的力量");

File file = new File("1.mp3");

ps.setBinaryStream(2, new FileInputStream(file), (int) file.length());

查询大二进制数据步骤:

InputStream in = rs.getBinaryStream("content");

编码的相关总结:

编码:把字符转成二进制 "中".getBytes("gbk")

解码:把二进制转成字符 String str=new String(bs,"gbk")

转码:将一张码表表示的一个字符转换为另一张码表表示的此字符的二进制gbkbs

String s=new String (gbkbs,"gbk");

Byte[] utfbs=s.getByte("utf8");

乱码:

(1)编码和解码使用的不是同一张码表

(2)如果编码的过程,查找的码表中没有要查找的字符也会出现乱码的问题.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: