想了解JDBC的一些基础知识的同学可以回看:解析JDBC指令 【增删查改的使用】
表示预编译的 SQL 语句的对象
使用PreparedStatement替代Statement的原因
- Statement有sql注入问题
- PreparedStatement可以通过规范sql解决sql注入问题
- 设置占位符参数更灵活
SQL注入问题
因为sql的获取是通过字符串拼接的,当追加
OR 1 = 1
,整个sql的逻辑会返回true
,则会失去判断作用
//sql注入问题demo
ResultSet executeQuery = conn.createStatement().executeQuery("SELECT userno FROM user WHERE username= 'scott', password ='tiger' OR 1 = 1");
if (executeQuery.next()) {
System.out.println("登陆成功!");
}
常用方法
说明 | |
---|---|
executeUpdate() | 没有参数,更新操作后,返回我们数据库响应的行数 |
executeQuery() | 没有参数,返回我们数据库查询结果集 |
setInt() | 将指定参数设置为给定 Java int 值。内部会自动转成数据库数据类型 |
setString() | 将指定参数设置为给定 Java String 值 |
setObject(int parameterIndex, Object x) | 使用给定对象设置指定参数的值。(内部会obj转成对应的数据类型 number , varchar2 ) |
close() | 释放资源 |
Demo
增删查改
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import cn.szsxt.utils.JdbcUtils;
public class Demo {
@Test
public void demo01() {
// 添加
// 获取 conn 连接对象
Connection conn = JdbcUtils.getConn();
// 准备sql ? 占位符
String sql = "insert into t_user(name,pwd) values (?,?)";
// 获取 ps对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
// 设置sql 的参数
ps.setString(1, "马云");
// setOjb 内部转成 指定的 数据库的数据类型
ps.setObject(2, "alibaba");
// 执行sql update方法
// 更新后数据库响应的行数
int update = ps.executeUpdate();// ps 的方法是 executeUpdate()
// st 的方法是 executeUpdate(sql) 如果调用 st的更新方法会出错
// 处理结果
if (update > 0) {
System.out.println("添加成功 ");
} else {
System.out.println("添加失败...");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 释放资源
finally {
JdbcUtils.close(ps, conn);
}
}
@Test
public void demo02() {
// 修改操作
// 获取 conn 连接对象
Connection conn = JdbcUtils.getConn();
// 准备sql
String sql = "update t_user set name = ? ,pwd = ? where id = ?";
// 获取 ps对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
// 设置sql的参数 从左 往 有设置 数据
ps.setString(1, "scott");
ps.setString(2, "tiger");
ps.setInt(3, 2);
// 执行sql update方法
int update = ps.executeUpdate();
// 处理结果
if (update > 0) {
System.out.println("修改成功 ...");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 释放资源
finally {
JdbcUtils.close(ps, conn);
}
}
@Test
public void demo03() {
// 删除操作
// 获取 conn 连接对象
Connection conn = JdbcUtils.getConn();
// 准备sql
String sql = "delete from t_user where id = ?";
// 获取 ps对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
// 设置sql的参数 从左 往 有设置 数据
ps.setInt(1, 1);
// 执行sql update方法
int update = ps.executeUpdate();
// 处理结果
if (update > 0) {
System.out.println("删除成功 ...");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 释放资源
finally {
JdbcUtils.close(ps, conn);
}
}
@Test
public void demo04() {
// 查询操作
Connection conn = JdbcUtils.getConn();
String sql = "select * from t_user";
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
// ps 设置参数 如果没有就不设置
// ruseltSet 查询返回的结果集 可以从结果集中 获取 查询表的数据
rs = ps.executeQuery();
// next() 判断 查询结果中是否 有数据
// while 循环遍历
while (rs.next()) {
// rs中 有getXXx 方法获取 列的中数据
// 可以通过 索引或者列名获取 (类名忽略大小写 )
String name = rs.getString("name");
String pwd = rs.getString("pwd");
System.out.println(name + "\t" +pwd);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
JdbcUtils.close(rs, ps, conn);
}
}
}
data数据的数据库交互
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import cn.szsxt.utils.JdbcUtils;
public class Demo {
@Test
public void demo01() {
// 添加 date 数据类型到数据库
// 获取 conn 连接对象
Connection conn = JdbcUtils.getConn();
// 准备sql
String sql = "insert into t_user(name,bir) values (?,?)";
// 获取 ps对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
// 设置sql的参数 参数的设置 要和数据库中的数据类型一致
// int --> number string --> varchar2
// java.sql.date(是sql包下面的 date ) - > 数据库中 date
ps.setString(1, "张无忌");
// sql.Date 构造 需要给 long 值
Date date = new Date(709789070987L);
ps.setDate(2, date);
// 执行sql update方法
int update = ps.executeUpdate();
// 处理结果
if (update > 0) {
System.out.println("添加成功...");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 释放资源
finally {
JdbcUtils.close(ps, conn);
}
}
@Test
public void demo02() {
// 查询操作 查询 获取 数据库中的date类型数据
Connection conn = JdbcUtils.getConn();
String sql = "select name,bir from t_user where id = ?";
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
// ps 设置参数 如果没有就不设置
ps.setInt(1, 3);
// ruseltSet 查询返回的结果集 可以从结果集中 获取 查询表的数据
rs = ps.executeQuery();
// next() 判断 查询结果中是否 有数据
// while 循环遍历
while (rs.next()) {
// rs中 有getXXx 方法获取 列的中数据
// 可以通过 索引或者列名获取 (类名忽略大小写 )
String name = rs.getString("name");
// 获取数据的时候
// 获取的方法 是 getXXX() 要和 数据库的数据 类型要一致
Date date = rs.getDate("bir");
System.out.println(name + "\t" +date);
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
JdbcUtils.close(rs, ps, conn);
}
}
}
图片的数据交互
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import cn.szsxt.utils.JdbcUtils;
public class Demo {
@Test
public void demo01() {
// 添加 date 数据类型到数据库
// 获取 conn 连接对象
Connection conn = JdbcUtils.getConn();
// 准备sql
String sql = "insert into t_user(name,img) values (?,?)";
// 获取 ps对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
// 设置sql的参数参数的设置要和数据库中的数据类型一致
// 图片存储是二进制文件blob 数据类型
ps.setString(1, "张无忌");
// 可以读取图片 到输入流 把 这个流存到 数据中
// 读取图片
File f = new File("src/zm.jpg");
// 选择流
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ps.setBlob(2, fis);
// 执行sql update方法
int update = ps.executeUpdate();
// 处理结果
if (update > 0) {
System.out.println("添加成功...");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 释放资源
finally {
JdbcUtils.close(ps, conn);
}
}
@Test
public void demo02() {
// 查询操作 查询 获取 数据库中的 图片
Connection conn = JdbcUtils.getConn();
String sql = "select name,img from t_user where id = ?";
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
// ps 设置参数 如果没有就不设置
ps.setInt(1, 1);
// ruseltSet 查询返回的结果集 可以从结果集中 获取 查询表的数据
rs = ps.executeQuery();
// next() 判断 查询结果中是否 有数据
// while 循环遍历
while (rs.next()) {
// rs中 有getXXx 方法获取 列的中数据
// 可以通过 索引或者列名获取 (类名忽略大小写 )
String name = rs.getString("name");
System.out.println(name);
// 获取数据的时候
// 获取的方法 是 getXXX() 要和 数据库的数据 类型要一致
Blob blob = rs.getBlob("img");
// blob 是二进制数据类型 可以 转成 输入 流
InputStream is = blob.getBinaryStream();
String path = "src/a.jpg";
writeImage(is, path);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(rs, ps, conn);
}
}
/**
* 图片数据库中的图片 保存到本地
*
* @param is 输入流
* @param path 保存到本地的 图片 路径
*/
private void writeImage(InputStream is, String path) {
// 建立联系
File f = new File(path);
// 选择流
BufferedOutputStream fos = null;
try {
fos = new BufferedOutputStream(new FileOutputStream(f));
// 读写操作
byte[] buffer = new byte[1024];
int len = 0;
// -1 判断是否读 到 文件的末尾
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.flush();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(" 保存完毕");
}
}
文本的数据交互
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import cn.szsxt.utils.JdbcUtils;
public class Demo {
@Test
public void demo01() {
// 获取conn
Connection conn = JdbcUtils.getConn();
String sql = "insert into t_user(name,myinfo) values (?,?)";
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
ps.setString(1, "赵敏");
// CLob 设置大文本数据
FileReader fr = new FileReader(new File("src/a.txt"));
ps.setClob(2, fr);
// 更新操作
int update = ps.executeUpdate();
if (update > 0) {
System.out.println("插入成功");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JdbcUtils.close(ps, conn);
}
}
@Test
public void demo02() {
// 获取conn
Connection conn = JdbcUtils.getConn();
String sql = "select name,myinfo from t_user where id = ? ";
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
ps.setInt(1, 4);
// 查询
rs = ps.executeQuery();
if (rs.next()) {
String name = rs.getString("name");
System.out.println(name);
//是大文本数据 可以获取字符输入流
Clob clob = rs.getClob("myinfo");
String str = writeString(clob);
System.out.println(str);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JdbcUtils.close(rs, ps, conn);
}
}
/**
* 读取 大文本中的字符
* @param clob 大文本 数据类型
* @return
*/
private String writeString(Clob clob) {
// 获取字符串输入流
try {
StringBuilder sb = new StringBuilder();
Reader reader = clob.getCharacterStream();
// reader 转成 字符缓冲 br
BufferedReader br = new BufferedReader(reader);
// readLine() 读取一行
String msg = null;
// 读取到的字符串 赋值给 msg 如果msg 不为null 继续 循环读取
while ((msg = br.readLine()) != null) {
// msg 是有多行数据 要把多行数据 拼成一个字符串 可以 StringBuilder
sb.append(msg + "\r\n");
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}