68-PreparedStatement数据库操作接口

本文详细介绍了Java JDBC中的PreparedStatement接口,对比Statement接口解决了SQL语句拼凑的问题,通过使用占位符简化了参数设置,并提供了多种数据库查询操作示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PreparedStatement数据库操作接口

  既然java.sql中有Statement接口实现数据库操作,那为什么又要提供有一个PreparedStatement实现数据库操作?

Statement问题分析

  以更新操作为例,在Statement中要想执行SQL语句,那么一定要通过字符串实现SQL结构定义,这种定义如果要结合到用户输入的情况下就可能产生问题产生。

分析Statement接口操作问题

String title = "testNews";
String content = "文本内容";
String sql = "INSERT INTO news(nid,title,content) VALUES(" news_seq.nextval " + title + content)";		//输入复杂,维护困难

  利用Statement执行的SQL语句有如下三个问题:

  1. 不能很好的描述日期的形式;
  2. 需要进行SQL语句的拼凑处理,导致SQL语句编写维护困难;
  3. 对于一些敏感字符数据无法进行合理拼凑。

  所以可以发现虽然Statement可以操作数据库,但是操作过程中并不是十分方便,而最大的弊端在于SQL语句的拼凑

PreparedStatement接口简介

  为了解决Statement接口存在的SQL语句拼凑问题,所以java.sql中提供一个Statement子接口:PreparedStatement,这个接口最大的好处是可以编写正常的SQL(数据不再和SQL语法混合在一起),同时利用占位符的形式,在SQL正常执行完毕后可以进行数据的设置。PreparedStatement接口定义:

  • public interface PreparedStatement implements Statement

  如果想要获取PreparedStatement接口实例,依然需要通过Connection接口来实现。

  • 创建PreparedStatement接口对象:public PreparedStatement prepareStatement(String sql) throws SQLException

  由于SQL语句已经在创建PreparedStatement接口对象的时候提供了,所以在执行数据库操作的时候也要更换方法:

  • 数据库更新:public int executeUpdate() throws SQLException
  • 数据库查询:public ResultSet executeQuery() throws SQLException

6hdmcD.png

利用PreparedStatement解决Statement存在的问题

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Date

public class Demo{
	private static final String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DATABASE_URL = "jdbc:oracle:thin:@localhost:1521:mldn"
	private static final String DATABASE_USER = "test";
	private static final String DATABASE_PASSWORD = "test";
	public static void main(String[] args) throws Exception{
		String title = "testNews";
		String content = "文本内容";
		String sql = " INSERT INTO news(nid,title,content) " 
				+ " VALUES(news_seq.nextval,?,?) ";			//使用“?”作为占位符
		
		Connection conn = null;
		Class.forName(DATABASE_DRIVER);
		conn = DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
		PreparedStatement pstmt = conn.prepareStatement(sql);
		//在执行具体数据库操作之前需要为占位符设置内容,按照顺序设置
		pstmt.setString(1,title);
		pstmt.setString(2,content);
		// pstmt.setInt(2,test);
		// pstmt.setDate(5, new java.sql.Date(date.getTime()));   //!!!重要
		int count = pstmt.executeUpdate();		//返回影响的行数
		conn.close();
	}
}

  在JDBC中不管使用的是PreparedStatement设置的日期时间,还是使用的ResultSet获取的日期时间实际上都是java.util.Date的子类,也就是说现在是如下的对应关系:
6hwRRf.png

使用PreparedStatement实现数据查询操作

  清楚了PreparedStatement实现更新处理之后,那么下面可以使用其实现数据查询处理操作,由于开发中PreparedStatement的使用是最广泛的,下面列举几个代表性的查询:
1 查询全部数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class Demo{
	private static final String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DATABASE_URL = "jdbc:oracle:thin:@localhost:1521:mldn"
	private static final String DATABASE_USER = "test";
	private static final String DATABASE_PASSWORD = "test";
	public static void main(String[] args) throws Exception{
		// 程序开发中SELECT子句后面必须跟上具体字段名称
		String sql = "SELECT nid,title FROM news";
		Connection conn = null;
		Class.forName(DATABASE_DRIVER);
		conn = DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
		PreparedStatement pstmt = conn.PreparedStatement();
		ResultSet rs = stmt.executeQurey(sql);		//执行查询
		while(rs.next()){			//数据未完全输出
			int nid = rd.getInt(1);
			String title = rs.getString(2);		//列数2
			System.out.println("nid:" + nid + "-" + "Title:" + title);
		}
		conn.close();
	}
}

2 根据NID查询数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class Demo{
	private static final String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DATABASE_URL = "jdbc:oracle:thin:@localhost:1521:mldn"
	private static final String DATABASE_USER = "test";
	private static final String DATABASE_PASSWORD = "test";
	public static void main(String[] args) throws Exception{
		// 程序开发中SELECT子句后面必须跟上具体字段名称
		String sql = "SELECT nid,title FROM news WHERE nid=?";
		Connection conn = null;
		Class.forName(DATABASE_DRIVER);
		conn = DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
		PreparedStatement pstmt = conn.PreparedStatement();
		pstmt.setInt(1,5);		//设置nid数据
		ResultSet rs = stmt.executeQurey(sql);		//执行查询
		while(rs.next()){			//数据未完全输出
			int nid = rd.getInt(1);
			String title = rs.getString(2);		//列数2
			System.out.println("nid:" + nid + "-" + "Title:" + title);
		}
		conn.close();
	}
}

  进行全部数据查询的时候如果返回的内容过多则一定会造成内存的大量占用,那么此时可以使用分页的形式实现数据的查询处理(模糊)。
3 根据NID查询数据(分页)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class Demo{
	private static final String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DATABASE_URL = "jdbc:oracle:thin:@localhost:1521:mldn"
	private static final String DATABASE_USER = "test";
	private static final String DATABASE_PASSWORD = "test";
	public static void main(String[] args) throws Exception{
		int currentPage = 1;		//当前页
		int lineSize = 10;			//每页显示数据行
		String columu = "title"		//模糊查询列
		String keyWord = "test";	//查询关键字
		// 程序开发中SELECT子句后面必须跟上具体字段名称
		String sql =  " SELECT * FROM ( "
					+ " nid,title FROM news WHERE "+ columu + "LIKE ? AND ROUNUM<=?) temp "
					+ " WHERE temp.rn>? ";
		Connection conn = null;
		Class.forName(DATABASE_DRIVER);
		conn = DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
		PreparedStatement pstmt = conn.PreparedStatement();
		pstmt.setString(1, "%" + keyWord + "%");
		pstmt.setInt(2, currentPage * lineSize);
		pstmt.setInt(3, (currentPage -1) * lineSize);
		ResultSet rs = stmt.executeQurey(sql);		//执行查询
		while(rs.next()){			//数据未完全输出
			int nid = rd.getInt(1);
			String title = rs.getString(2);		//列数2
			System.out.println("nid:" + nid + "-" + "Title:" + title);
		}
		conn.close();
	}
}

4 统计数据查询

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class Demo{
	private static final String DATABASE_DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String DATABASE_URL = "jdbc:oracle:thin:@localhost:1521:mldn"
	private static final String DATABASE_USER = "test";
	private static final String DATABASE_PASSWORD = "test";
	public static void main(String[] args) throws Exception{
		String columu = "title"		//模糊查询列
		String keyWord = "test";	//查询关键字
		// 程序开发中SELECT子句后面必须跟上具体字段名称
		String sql =  " SELECT COUNT(*) FROM news WHERE "+ columu + "LIKE ?";
		Connection conn = null;
		Class.forName(DATABASE_DRIVER);
		conn = DriverManager.getConnection(DATABASE_URL,DATABASE_USER,DATABASE_PASSWORD);
		PreparedStatement pstmt = conn.PreparedStatement();
		pstmt.setString(1, "%" + keyWord + "%");
		ResultSet rs = stmt.executeQurey(sql);		//执行查询
		if(rs.next()){			
			long count = rs.getLong(1);
			System.out.println(count);
		}
		conn.close();
	}
}

  使用COUNT函数做统计查询的时候一定会返回查询结果,没有数据返回0

本文为Java基础学习系列最后一篇文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值