初学JDBC的一些总结(二)
一、简单介绍PreparedStatement 和Statement的区别:
PreparedStatement是用来执行SQL查询语句的API之一,Java提供了 Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句。
- Statement 用于通用查询
- PreparedStatement 用于执行参数化查询
- CallableStatement则是用于存储过程。
通过调用connection.preparedStatement(sql)方法可以获得PreparedStatment对象。数据库系统会对sql语句进行预编译处理(如果JDBC驱动支持的话),预处理语句将被预先编译好,这条预编译的sql查询语句能在将来的查询中重用,这样一来,它比Statement对象生成的查询速度更快。
PreparedStatement提供了诸多好处,企业级应用开发中强烈推荐使用PreparedStatement来做SQL查询,下面列出PreparedStatement的几点优势。
1、PreparedStatement可以写动态参数化的查询
2、PreparedStatement比 Statement 更快:使用 PreparedStatement 最重要的一点好处是它拥有更佳的性能优势,SQL语句会预编译在数据库系统中。执行计划同样会被缓存起来,它允许数据库做参数化查询。使用预处理语句比普通的查询更快,因为它做的工作更少(数据库对SQL语句的分析,编译,优化已经在第一次查询前完成了)。为了减少数据库的负载,生产环境中德JDBC代码你应该总是使用PreparedStatement 。值得注意的一点是:为了获得性能上的优势,应该使用参数化sql查询而不是字符串追加的方式。
3、PreparedStatement可以防止SQL注入式攻击:在使用参数化查询的情况下,数据库系统(eg:MySQL)不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。
二、关于PreparedStatement接口,需要重点记住的是:
- PreparedStatement查询默认返回FORWARD_ONLY的ResultSet,你只能往一个方向移动结果集的游标。当然你还可以设定为其他类型的值如:”CONCUR_READ_ONLY”。
- 不支持预编译SQL查询的JDBC驱动,在调用connection.prepareStatement(sql)的时候,它不会把SQL查询语句发送给数据库做预处理,而是等到执行查询动作的时候(调用executeQuery()方法时)才把查询语句发送个数据库,这种情况和使用Statement是一样的。
- 占位符的索引位置从1开始而不是0,如果填入0会导致*java.sql.SQLException invalid column index*异常。所以如果PreparedStatement有两个占位符,那么第一个参数的索引时1,第二个参数的索引是2.
三、使用 PreparedStatement 接口实现增,删,改操作
1、添加图书信息
package com.java1234.jdbc.chap04.sec02; import java.sql.Connection;
import java.sql.PreparedStatement; import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil; public class Demo1 { private static DbUtil dbUtil=new DbUtil(); /**
* 添加图书
* @param book
* @return
* @throws Exception
*/
private static int addBook(Book book)throws Exception{
Connection con=dbUtil.getCon(); // 获取连接
String sql="insert into t_book values(null,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, book.getBookName()); // 给第一个坑设置值
pstmt.setFloat(2, book.getPrice()); // 给第二个坑设置值
pstmt.setString(3, book.getAuthor()); // 给第三个坑设置值
pstmt.setInt(4, book.getBookTypeId()); // 给第四个坑设置值
int result=pstmt.executeUpdate();
dbUtil.close(pstmt, con);
return result;
} public static void main(String[] args) throws Exception{
Book book=new Book("Java叉叉2", 1, "叉叉", 1);
int result=addBook(book);
if(result==1){
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}
}
}
2、更新图书信息
package com.java1234.jdbc.chap04.sec03; import java.sql.Connection;
import java.sql.PreparedStatement; import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil; public class Demo1 { private static DbUtil dbUtil=new DbUtil(); /**
* 更新图书
* @param book
* @return
* @throws Exception
*/
private static int updateBook(Book book)throws Exception{
Connection con=dbUtil.getCon();
String sql="update t_book set bookName=?,price=?,author=?,bookTypeId=? where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, book.getBookName());
pstmt.setFloat(2, book.getPrice());
pstmt.setString(3, book.getAuthor());
pstmt.setInt(4, book.getBookTypeId());
pstmt.setInt(5, book.getId());
int result=pstmt.executeUpdate();
dbUtil.close(pstmt, con);
return result;
} public static void main(String[] args) throws Exception{
Book book=new Book(12,"K2", 2, "K", 2);
int result=updateBook(book);
if(result==1){
System.out.println("更新成功!");
}else{
System.out.println("更新失败!");
}
}
}
3、删除图书信息
package com.java1234.jdbc.chap04.sec04; import java.sql.Connection;
import java.sql.PreparedStatement; import com.java1234.jdbc.util.DbUtil; public class Demo1 { private static DbUtil dbUtil=new DbUtil(); /**
* 删除图书
* @param id
* @return
* @throws Exception
*/
private static int deleteBook(int id)throws Exception{
Connection con=dbUtil.getCon();
String sql="delete from t_book where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, id);
int result=pstmt.executeUpdate();
dbUtil.close(pstmt, con);
return result;
} public static void main(String[] args)throws Exception {
int result=deleteBook(12);
if(result==1){
System.out.println("删除成功!");
}else{
System.out.println("删除失败!");
}
}
}
总结:使用PreparedStatement对象来执行SQL语句的查询,我们在写SQL语句的时候需要注意使用占位符表示待查寻信息字段信息必须要区分英文和中文占位符的区别。
PreparedStatement对象的一些主要方法:
executeQuery():在此PreparedStatement对象中执行 SQL 查询,并返回该查询生成的ResultSet对象。executeUpdate(): 在此PreparedStatement对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如INSERT、UPDATE或DELETE语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。getMetaData():获取包含有关ResultSet对象列信息的ResultSetMetaData对象,ResultSet对象将在执行此PreparedStatement对象时返回。setAsciiStream(int parameterIndex, InputStream x,long length):将指定参数设置为给定输入流。(主要用于处理CLOB)setBinaryStream(int parameterIndex, InputStream x, long length):将指定参数设置为给定输入流,该输入流将具有指定字节数。(主要用于处理BLOB)setXxx(int parameterIndex, Xxx x):将指定参数设置为给定 Javaxxx(java基本数据类型)值。
四、使用结果集ResultSet返回一个二维表的信息:
当我们查询数据库时,返回的是一个二维的结果集,我们这时候需要使用 ResultSet 来遍历结果集,获取每一行的数据。
boolean next(): 将光标从当前位置向前移一行。开始时候的光标在第一行的前边,并不指向第一行。
String getString(int columnIndex) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。
String getString(String columnLabel) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值
package com.java1234.jdbc.chap05.sec02; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List; import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil; public class Demo1 { private static DbUtil dbUtil = new DbUtil(); /**
* 遍历查询结果,这里是按照列的编号进行输出的。
* @throws Exception
*/
private static void listBook() throws Exception {
Connection con = dbUtil.getCon(); // 获取连接
String sql = "select * from t_book";
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery(); // 返回结果集ResultSet
while (rs.next()) {
int id = rs.getInt(1); // 获取第一个列的值 编号id
String bookName = rs.getString(2); // 获取第二个列的值 图书名称 bookName
float price = rs.getFloat(3); // 获取第三列的值 图书价格 price
String author = rs.getString(4); // 获取第四列的值 图书作者 author
int bookTypeId = rs.getInt(5); // 获取第五列的值 图书类别id
System.out.println("图书编号:" + id + " 图书名称:" + bookName + " 图书价格:"
+ price + " 图书作者:" + author + " 图书类别id:" + bookTypeId);
System.out
.println("======================================================================="); }
} /**
* 遍历查询结果,这里是按照列的数据类型进行输出的
* @throws Exception
*/
private static void listBook2() throws Exception {
Connection con = dbUtil.getCon(); // 获取连接
String sql = "select * from t_book";
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery(); // 返回结果集ResultSet
while (rs.next()) {
int id = rs.getInt("id"); // 获取第一个列的值 编号id
String bookName = rs.getString("bookName"); // 获取第二个列的值 图书名称 bookName
float price = rs.getFloat("price"); // 获取第三列的值 图书价格 price
String author = rs.getString("author"); // 获取第四列的值 图书作者 author
int bookTypeId = rs.getInt("bookTypeId"); // 获取第五列的值 图书类别id
System.out.println("图书编号:" + id + " 图书名称:" + bookName + " 图书价格:"
+ price + " 图书作者:" + author + " 图书类别id:" + bookTypeId);
System.out
.println("======================================================================="); }
}
//这里为了体现面向对象的思想,把每次查询到的信息都封装成一个Book对象,并装进ArrayList链表中
private static List<Book> listBook3()throws Exception{
List<Book> bookList=new ArrayList<Book>();
Connection con = dbUtil.getCon(); // 获取连接
String sql = "select * from t_book";
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery(); // 返回结果集ResultSet
while (rs.next()) {
int id = rs.getInt("id"); // 获取第一个列的值 编号id
String bookName = rs.getString("bookName"); // 获取第二个列的值 图书名称 bookName
float price = rs.getFloat("price"); // 获取第三列的值 图书价格 price
String author = rs.getString("author"); // 获取第四列的值 图书作者 author
int bookTypeId = rs.getInt("bookTypeId"); // 获取第五列的值 图书类别id
Book book=new Book(id, bookName, price, author, bookTypeId);
bookList.add(book);
}
return bookList;
} public static void main(String[] args) throws Exception {
// listBook();
// listBook2();
List<Book> bookList=listBook3();
for (Book book : bookList) {
System.out.println(book);
}
}
}
五、利用JDBC进行大数据的处理:
大数据对象处理主要有 CLOB(character large object)和 BLOB(binary large object)两种类型的字段;在 CLOB中可以存储大字符数据对象,比如长篇小说;在 BLOB 中可以存放二进制大数据对象,比如图片,电影,音乐。
1、处理 CLOB 数据
package com.java1234.jdbc.chap06.sec01; import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil; public class Demo1 { private static DbUtil dbUtil=new DbUtil(); /**
* 添加图书
* @param book
* @return
* @throws Exception
*/
private static int addBook(Book book)throws Exception{
Connection con=dbUtil.getCon(); // 获取连接
String sql="insert into t_book values(null,?,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, book.getBookName()); // 给第一个坑设置值
pstmt.setFloat(2, book.getPrice()); // 给第二个坑设置值
pstmt.setString(3, book.getAuthor()); // 给第三个坑设置值
pstmt.setInt(4, book.getBookTypeId()); // 给第四个坑设置值
File context=book.getContext(); // 获取文件
InputStream inputStream=new FileInputStream(context);
pstmt.setAsciiStream(5, inputStream,context.length()); // 给第五个坑设置值
int result=pstmt.executeUpdate();
dbUtil.close(pstmt, con);
return result;
}
/**
* 按照编号获取图书信息
* @param book
* @return
* @throws Exception
*/
public static void getBook(int id)throws Exception{
Connection con=dbUtil.getCon();
String sql="select * from t_book where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, id);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
//getString(参数名称):参数名称都是数据库中设置的每一列的表格名称
String bookName=rs.getString("bookName");
float price=rs.getFloat("price");
String author=rs.getString("author");
int bookTypeId=rs.getInt("bookTypeId");
Clob c=rs.getClob("context");
String context=c.getSubString(1, (int)c.length());
System.out.println("图书名称:"+bookName);
System.out.println("图书价格:"+price);
System.out.println("图书作者:"+author);
System.out.println("图书类型ID:"+bookTypeId);
System.out.println("图书内容:"+context);
}
dbUtil.close(pstmt, con);
} public static void main(String[] args)throws Exception {
/*File context=new File("c:/helloWorld.txt");
Book book=new Book("helloWorld", 100, "小锋", 1,context);
int result=addBook(book);
if(result==1){
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}*/
getBook(16);
}
}
2、处理BLOB数据
package com.java1234.jdbc.chap06.sec02; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil; public class Demo1 { private static DbUtil dbUtil=new DbUtil(); /**
* 添加图书(还包括给每一本书添加一个插图)
* @param book
* @return
* @throws Exception
*/
private static int addBook(Book book)throws Exception{
Connection con=dbUtil.getCon(); // 获取连接
String sql="insert into t_book values(null,?,?,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1, book.getBookName()); // 给第一个坑设置值
pstmt.setFloat(2, book.getPrice()); // 给第二个坑设置值
pstmt.setString(3, book.getAuthor()); // 给第三个坑设置值
pstmt.setInt(4, book.getBookTypeId()); // 给第四个坑设置值
File context=book.getContext(); // 获取文件
InputStream inputStream=new FileInputStream(context);
pstmt.setAsciiStream(5, inputStream,context.length()); // 给第五个坑设置值 File pic=book.getPic(); // 获取图片文件
InputStream inputStream2=new FileInputStream(pic);
pstmt.setBinaryStream(6, inputStream2, pic.length()); // 给第六个坑设置值
int result=pstmt.executeUpdate();
dbUtil.close(pstmt, con);
return result;
} /**
* 按照编号获取图书信息(还包括每本书的插图也放到一个指定的文件中)
* @param book
* @return
* @throws Exception
*/
public static void getBook(int id)throws Exception{
Connection con=dbUtil.getCon();
String sql="select * from t_book where id=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setInt(1, id);
ResultSet rs=pstmt.executeQuery();
if(rs.next()){
String bookName=rs.getString("bookName");
float price=rs.getFloat("price");
String author=rs.getString("author");
int bookTypeId=rs.getInt("bookTypeId"); //获取文本文件
Clob c=rs.getClob("context");
String context=c.getSubString(1, (int)c.length()); //获取图片
Blob b=rs.getBlob("pic");
//图片不能直接输出到控制台,所以只能把图片放到一个指定的位置
FileOutputStream out=new FileOutputStream(new File("d:/pic2.jpg"));
out.write(b.getBytes(1, (int)b.length()));
out.close();
System.out.println("图书名称:"+bookName);
System.out.println("图书价格:"+price);
System.out.println("图书作者:"+author);
System.out.println("图书类型ID:"+bookTypeId);
System.out.println("图书内容:"+context);
}
dbUtil.close(pstmt, con);
} public static void main(String[] args)throws Exception {
//这是为了测试图书信息添加
/*File context=new File("c:/helloWorld.txt");
File pic=new File("c:/pic1.jpg");
Book book=new Book("helloWorld", 100, "小锋", 1,context,pic);
int result=addBook(book);
if(result==1){
System.out.println("添加成功!");
}else{
System.out.println("添加失败!");
}*/
//这是为了测试按照图书标号查找图书
getBook(18);
}
}
备注:这里所有的代码都是基于一个Book图书的模型进行的。
What You Want,Time Will Give You!!!
初学JDBC的一些总结(二)的更多相关文章
- 关于JDBC学习过程中的注意事项(分享自己犯过的错误,写给初学JDBC的小伙伴的八条建议)
关于JDBC学习过程中的注意事项(分享自己犯过的错误,写给初学JDBC的小伙伴的八条建议) 前言:最近在学习JDBC,总结了几个小问题,特地分享给大家,让大家不要犯这样的错误,也希望大家养成学会总结的 ...
- JDBC的使用(二):PreparedStatement接口;ResultSet接口(获取结果集);例题:SQL注入
ResultSet接口:类似于一个临时表,用来暂时存放数据库查询操作所获得的结果集. getInt(), getFloat(), getDate(), getBoolean(), getString( ...
- JavaWeb用Jdbc操作MySql数据库(二)
一.仍然使用前面的环境和示例数据库. 二.建立发出注册请求的页面index3.jsp. <%@ page language="java" import="java. ...
- 初学JDBC,最简单示例
一.下载相应数据库驱动jar包,添加到项目中 二.注册驱动,数据库驱动只加入到classpath中是还不行的,还要在使用的时候注册一下,就像安装驱动软件,只拷贝到硬盘还不行,需要安装一下 Driver ...
- JDBCTemplate简化JDBC的操作(二)
一.Spring对不同的持久化支持: Spring为各种支持的持久化技术,都提供了简单操作的模板和回调 ORM持久化技术 模板类 JDBC org.springframework.jdbc.core. ...
- 初学JDBC的一些总结(一)
1.关于JDBC的的个人理解: JDBC(Java Data Base Connectivity,java 数据库连接)是用于执行 SQL 语句的 JavaAPI,可以为多种关系型数据库提供统一的访问 ...
- Jmeter之JDBC请求参数化(二)
二.上面已经讲了一些基本的配置,和简单的jdbc请求,下面来看下具体的如何将查询语句参数化. 参数化这里有几种方法,foreach,计数器,csv等,这里介绍几种方法.
- Java JDBC学习实战(二): 管理结果集
在我的上一篇博客<Java JDBC学习实战(一): JDBC的基本操作>中,简要介绍了jdbc开发的基本流程,并详细介绍了Statement和PreparedStatement的使用:利 ...
- 初学后台框架总结篇二——快速了解CI框架
一.下载CI框架并安装,这里放置一张自己的项目目录结构图 目录框架搭建好之后开始将自己的项目与框架融合 二.更改相关配置 1.用任何文本编辑器打开 application/config/config. ...
随机推荐
- jQuery分步步骤
插件描述:jQuery上一步.下一步,分步步骤,兼容性如下: 使用方法 1.引入样式和脚本 <link rel="stylesheet" type="text/cs ...
- es6 模板字符串
模板字符串 提供构造字符串的语法糖,在 Prel/python 等语言中也都有类似特性. 1.反引号模板,可以换行 2.反引号模板,可以嵌套 用+``来嵌套 好处:语法更加简洁 var name=&q ...
- python之GIL官方文档 global interpreter lock 全局解释器锁
0.目录 2. 术语 global interpreter lock 全局解释器锁3. C-API 还有更多没有仔细看4. 定期切换线程5. wiki.python6. python.doc FAQ ...
- Ubuntu下使用Evernote
Ubuntu下安装使用Evernote http://blog.csdn.net/yangzhuoluo/article/details/8118996 http://blog.csdn.net/ya ...
- Directory 类
Directory 类 该类公开,主要用于创建.移动和枚举通过目录和子目录的静态方法.此类不能被继承. 命名空间: System.IO; 程序集: mscorlib(在 msc ...
- ansible 自动化管理
1 什么样的情形需要批量部署 1.操作系统的安装 常见的有collber,red hat satelite(redhat)系统专用. 2.操作系统的配置 常见的有cfengine,puppet,che ...
- Python学习(十二) —— 面向对象
一.初识面向对象 面向过程的核心是过程,流水线思维,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点:极大地降低了写程序的复杂度,只需要顺着要执行的 ...
- Python题目练习(一)
1.使用while循环输入 1 2 3 4 5 6 8 9 10 i = 1 while i <=10 : if i != 7: print(i) else: print(' ') i += ...
- 创建自己的composer包
需求:在项目中输入 p($arr); 将会格式化输出 一.在GitHub上创建仓库 1.1这个仓库必须包含composer.json文件,内容如下. { "name": " ...
- 认识Fiddler
一.Fiddler界面介绍.(注:下图中的功能区面板显示的是“Inspectors”的选项卡界面) 二.工具栏介绍. 1.气泡:备注.添加之后在会话栏的Comment列中显示备注内容. 2.Repla ...