使用PrepareStatement
包结构:
第一步:编写获取连接工具类
package com.atguigu.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* JDBC 操作的工具类
*/
public class JdbcUtils {
public static void close(ResultSet resultSet){
try {
if(resultSet != null){
resultSet.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//关闭数据库资源
public static void close(Connection connection){
try {
if(connection != null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement statement){
try {
if(statement != null){
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//根据配置文件获取数据库连接
public static Connection getConnection() throws ClassNotFoundException, SQLException, IOException{
Connection connection = null;
//0. 读取 Properties 文件
Properties properties = new Properties();
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties.load(in);
//1. 准备连接数据库的四个基本信息:
String driverClassName = properties.getProperty("jdbc.driverClass");
String url = properties.getProperty("jdbc.jdbcUrl");
String user = properties.getProperty("jdbc.user");
String password = properties.getProperty("jdbc.password");
//2. 加载驱动
Class.forName(driverClassName);
//3. 调用 DriverManager.getConnection(url, user, password) 获取连接
connection = DriverManager.getConnection(url, user, password);
return connection;
}
}
第二步:执行插入操作
public class JdbcTest1 {
//向数据表插入一条记录
@Test
public void testInsert() throws ClassNotFoundException, SQLException, IOException{
//1. 编写一条 SQL 语句:
String sql = "INSERT INTO users2 (username, password) VALUES('tom','2345')";
//2. 获取连接
Connection connection = JdbcUtils.getConnection();
//3. 执行 SQL 需要借助于 Statement 接口
//3.1 调用 Connection#createStatement() 创建 Statement 对象
Statement statement = connection.createStatement();
//3.2 执行 SQL
statement.execute(sql);
//4. 关闭数据库资源
statement.close();
connection.close();
}
}
=========================================
/**
* 无论是否出现异常, 都必须保证关闭数据库资源!
* 使用 try catch finallay. 在 finally 中关闭数据库资源
*/
@Test
public void testInsert2(){
Connection connection = null;
Statement statement = null;
try {
//1. 编写一条 SQL 语句:
String sql = "INSERT INTO users2 (username, password) VALUES('tom','2345')";
//2. 获取连接
connection = JdbcUtils.getConnection();
//3. 执行 SQL 需要借助于 Statement 接口
//3.1 调用 Connection#createStatement() 创建 Statement 对象
statement = connection.createStatement();
//3.2 执行 SQL
statement.execute(sql);
} catch (Exception e) {
e.printStackTrace();
} finally{
//4. 关闭数据库资源
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
===========================================
/*
* 若仅仅是执行一条已经准备好的 SQL, 使用 Statement OK!
* 开发时, 不太可能使用完全实现准备好的 SQL! SQL 中的部分开能需要动态传入.
*/
//调用 JdbcUtils 来关闭数据库资源
@Test
public void testStatement(){
Connection connection = null;
Statement statement = null;
try {
//1. 编写一条 SQL 语句:
String sql = "INSERT INTO users2 (username, password) VALUES('tom','2345')";
//2. 获取连接
connection = JdbcUtils.getConnection();
//3. 执行 SQL 需要借助于 Statement 接口
//3.1 调用 Connection#createStatement() 创建 Statement 对象
statement = connection.createStatement();
//3.2 执行 SQL
statement.execute(sql);
} catch (Exception e) {
e.printStackTrace();
} finally{
//4. 关闭数据库资源
JdbcUtils.close(statement);
JdbcUtils.close(connection);
}
}
==========================================================
//关于 Statement 做了解即可.
//用户名和密码从控制台进行动态输入
//拼接 SQL 字符串不靠谱!
//1. 麻烦. 2. 还会有 SQL 注入的问题.
@Test
public void testStatement2(){
Connection connection = null;
Statement statement = null;
Scanner scanner = new Scanner(System.in);
System.out.print("username:");
String username = scanner.nextLine();
System.out.println("password:");
String password = scanner.nextLine();
try {
//1. 编写一条 SQL 语句:
String sql = "INSERT INTO users (username, password) VALUES('"
+ username + "','" + password + "')";
//2. 获取连接
connection = JdbcUtils.getConnection();
//3. 执行 SQL 需要借助于 Statement 接口
//3.1 调用 Connection#createStatement() 创建 Statement 对象
statement = connection.createStatement();
//3.2 执行 SQL
statement.execute(sql);
} catch (Exception e) {
e.printStackTrace();
} finally{
//4. 关闭数据库资源
JdbcUtils.close(statement);
JdbcUtils.close(connection);
}
}
=========================================================
/**
* PreparedStatement 可以解决 Statement 的问题
* 1. 不再需要拼接 SQL 字符串
* 2. 可以解决 SQL 注入的问题.
*/
@Test
public void testPreparedStatement(){
Connection connection = null;
PreparedStatement preparedStatement = null;
Scanner scanner = new Scanner(System.in);
System.out.print("username:");
String username = scanner.nextLine();
System.out.println("password:");
String password = scanner.nextLine();
try {
//1. 编写一条 SQL 语句, 使用 ? 作为占位符. 所以就可以不拼 SQL 串了.
String sql = "INSERT INTO users (username, password) VALUES(?,?)";
//2. 获取连接
connection = JdbcUtils.getConnection();
//3. 调用 Connection#prepareStatement(sql) 创建 PreparedStatement 对象
preparedStatement = connection.prepareStatement(sql);
//4. 调用 PreparedStatement 的 setXxx 方法来填充占位符
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
//3.2 执行 SQL. 调用 execute() 方法. 而不能再调用 Statement 的 execute(sql) 方法
preparedStatement.execute();
} catch (Exception e) {
e.printStackTrace();
} finally{
//4. 关闭数据库资源
JdbcUtils.close(preparedStatement);
JdbcUtils.close(connection);
}
}
==========================================================
jdbc.properties路径:/jdbc-1/src/jdbc.properties
内容:
#连接MySQL
jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://127.0.0.1:3306/jdbc1
#连接Oracle
#jdbc.user=scott
#jdbc.password=tiger
#jdbc.driverClass=oracle.jdbc.driver.OracleDriver
#jdbc.jdbcUrl=jdbc:oracle:thin:@127.0.0.1:1521:ORCL001
使用PrepareStatement的更多相关文章
- preparestatement可以避免注入
之所以PreparedStatement能防止注入,是因为它把单引号转义了,变成了\',这样一来,就无法截断SQL语句,进而无法拼接SQL语句,基本上没有办法注入了. 不使用这个,我们一般做查询或更新 ...
- 可输出sql的PrepareStatement封装
import java.io.InputStream; import java.io.Reader; import java.net.URL; import java.sql.Connection; ...
- 预处理prepareStatement是怎么防止sql注入漏洞的?
序,目前在对数据库进行操作之前,使用prepareStatement预编译,然后再根据通配符进行数据填值,是比较常见的做法,好处是提高执行效率,而且保证排除SQL注入漏洞. 一.prepareStat ...
- prepareStatement与Statement的区别
prepareStatement与Statement的区别 1.区别: 转 http://blog.csdn.net/zsm653983/article/details/7296609 stmt=co ...
- JDBC中prepareStatement 和Statement 的区别
package util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedSta ...
- 加载执行预编译的Sql :prepareStatement
1.获得连接:Connection con = null; con = DBUtil.getConnection(); 2.写sql语句:String sql=""; 3.用连接加 ...
- prepareStatement和Statement的区别
1:创建时的区别: Statement stm=con.createStatement(); PreparedStatement pstm=con.prepareStatement(sql ...
- prepareStatement的用法和解释
1. PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程2. 使用 Statement 对象.在对数据库只执行一次性存取的时侯,用 Statement ...
- MySQL PrepareStatement基本的两种模式&客户端空间占用的源码分析
关于预编译(PrepareStatement),对于所有的JDBC驱动程序来讲,有一个共同的功能,就是“防止SQL注入”,类似Oracle还有一种“软解析”的概念,它非常适合应用于OLTP类型的系统中 ...
- JDBC连接数据库 prepareStatement
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...
随机推荐
- 史上最全面的SignalR系列教程-4、SignalR 自托管全解(使用Self-Host)-附各终端详细实例
1.概述 通过前面几篇文章 史上最全面的SignalR系列教程-1.认识SignalR 史上最全面的SignalR系列教程-2.SignalR 实现推送功能-永久连接类实现方式 史上最全面的Signa ...
- Python模块之netmiko
一.简介 此模块用于简化paramiko与网络设备之间的ssh连接,可在windows与Unix平台使用 二.目前支持的设备 (2019.03.07) Regularly tested Arista ...
- spring-boot-plus项目打包(七)
spring-boot-plus项目打包 项目打包 spring-boot-plus项目使用maven assembly插件进行打包 根据不同环境进行打包部署 包含启动.重启命令,配置文件提取到外部c ...
- 自定义genericUDF demo
package cn.com.dtmobile.hiveUdf; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import ...
- MinorGC和FullGC的触发条件
前言 无论是日常工作,还是企业面试,我们都会经常接触到GC.我们都知道GC是java中的垃圾回收策略.GC帮我们省去了很多事.在GC中,我经常听到的就属于MinorGC和FullGC了.那么在什么情况 ...
- 小白学习day2------比较运算
1 算术运算 加+ 2+3=5 减 - 3-2=1 乘 * 2*3=6 除 / 6/2=3 取膜 % 余数 幂 ** 2**3=8 整除 // 9//4=2 2 比较运算 == 判断是否等于 != , ...
- 监听input实时输入
// 用Jquery实现: $('#input-element').on('input',()=>{ console.log("你按了一下111");}) // 用Jquer ...
- 「每日五分钟,玩转JVM」:线程共享区
前言 上一篇中,我们了解了JVM中的线程独占区,这节课我们就来了解一下JVM中的线程共享区,JVM中的线程共享区是跟随JVM启动时一起创建的,包括堆(Heap)和方法区()两部分,而线程独占区的程序计 ...
- unity之游戏特效
一.运动轨迹 运动轨迹常常用于表现武器的挥舞效果,在提高速度感的同时又能让玩家看清楚招式动作,所以是常见的一种格斗特效. Unity中可以直接使用TrailRender来实现该效果. 二.运动模糊 运 ...
- Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves)
Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves) 深度优先搜索的解题详细介绍,点击 ...