初学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. ...
随机推荐
- Spark的Streaming和Spark的SQL简单入门学习
1.Spark Streaming是什么? a.Spark Streaming是什么? Spark Streaming类似于Apache Storm,用于流式数据的处理.根据其官方文档介绍,Spark ...
- lua 日期的一些函数
--根据日期获取星期几 function getWeekNum(strDate) local ymd = Split(strDate,"-") t = ]),month=]),da ...
- [转] JavaScript 单例模式
定义 确保一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式使用的场景 比如线程池.全局缓存等.我们所熟知的浏览器的window对象就是一个单例,在JavaScript开发中,对于这种只需要 ...
- 秒懂C#通过Emit动态生成代码
首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new AssemblyName("Kitty&qu ...
- nginx 301重定向一种实现方法
假设要使用的域名是b.com,以前的老域名是a.com,则以下设置让nginx把a.com的请求访问转发到b.com,并返回301给浏览器. server { listen 80; server_na ...
- Asp.Net MVC及Web API框架配置会碰到的几个问题及解决方案 (精髓)
前言 刚开始创建MVC与Web API的混合项目时,碰到好多问题,今天拿出来跟大家一起分享下.有朋友私信我问项目的分层及文件夹结构在我的第一篇博客中没说清楚,那么接下来我就准备从这些文件怎么分文件夹说 ...
- DirectoryEntry配置IIS7出现ADSI Error:未知错误(0x80005000)
一.错误情况 环境:win7+iis7.0 DirectoryEntry配置IIS7出现如下错误 或者是 下面一段代码在IIS6.0下运转正常,但IIS7.0下运转会出错: System.Direct ...
- BZOJ3926 [Zjoi2015]诸神眷顾的幻想乡 字符串 SAM
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3926.html 题目传送门 - BZOJ3926 题意 给定一个有 $n$ 个节点,最多只有 $20$ ...
- hive中使用union出现异常数据
select * from tbl where id=2 union select * from tbl where id =1 如果hive使用union这么查询的时候,我们会发现数据变乱了. 解决 ...
- OpenJ_Bailian 4017 爬楼梯
时间限制: 1000 ms 空间限制: 262144 KB 题目描述 树老师爬楼梯,他可以每次走1级或者2级,输入楼梯的级数,求不同的走法数.例如:楼梯一共有3级,他可以每次都走一级,或者第一次走一 ...