初學JDBC(四)-使用Preparedstatement介面實現增刪改操作
上一篇部落格中我講了使用Statement對資料庫中的表內容進行增刪改操作,先講了原始的增刪改即每次增加刪除修改都需要載入資料庫驅動,連線資料庫,執行SQL語句,關閉資料庫,這樣的話,程式碼的重複量有些大,程式碼冗餘比較明顯,後來進行修改,運用了Java繼承封裝和多型的思想,對原來的增刪改程式碼進行了優化,這一篇部落格我來說說用PreparedStatement介面實現對資料庫表內容的增刪改操作,在現實的開發中也常用PreparedStatement介面而不是Statement介面進行增刪改操作:使用PreparedStatement對於程式碼的可維護性和可讀性提高了;使用PreparedStatement盡最大可能提高效能;最重要的一點是極大地提高了安全性。(PS今天上完課頭有些暈暈乎乎,狀態不是很好,可是閒來無事,就又來刷部落格了,如有錯誤請原諒並指出來
PreparedStatement是Statement介面的子介面,屬於預處理操作,與直接使用Statement不同,PreparedStatement在操作時,是預先在資料表中準備好了一條SQL語句,但是此SQL語句的具體內容暫時不設定,而是之後在進行設定。
PreparedStatement介面的技術原理:
PreparedStatement例項包含已編譯的SQL語句,SQL語句可能包含1個,2個或多個輸入的值,這些值未被明確指定在SQL語句中用?作為佔位符代替,之後執行SQL語句之前要用setXXX()方法對值進行寫入。
PreparedStatement物件比Statement物件的執行速度要快,因為PreparedStatement物件已經預編譯過了,因此需要多次執行的SQL語句也可以用PreparedStatement物件進行執行來加快執行速度。
作為Statement的子類,PreparedStatement介面繼承了Statement的所有功能。另外它還整合一整套getXXX()和setXXX()方法,用於對值得獲取和輸入設定。同時,它還修改了三個方法execute、executeQuery、executeUpdate使它們不需要引數。這些方法的Statement形式,不應該再用於PreparedStatement物件。
PreparedStatement中的方法摘要:
1:executeQuery():在此PreparedStatement物件中執行SQL語句,並返回該查詢生成的ResultSet物件。
2:executeUpdate():在此PreparedStatement物件中執行SQL語句,該語句必須是一個SQL資料操作語言(Date Manipulation Language,DML)語句,比如insert、update、delete語句;或者是無返內容的SQL語句,比如DDL語句。
3:execute():在此PreparedStatement物件中執行SQL語句,該語句可以是任何種類的SQL語句。
4:getMetaData():獲取包含有關ResultSet物件列資訊的ResultSetMetaData物件,ResultSet物件將在此執行PreparedStatement物件時返回。
5:getParameterMetaData():獲取此PreparedStatement物件的引數的編號、型別和屬性。
6:setAsciiStream(int parameterIndex, InputStream x, int longth):將指定引數設定為給定輸入流,該輸入流將具有給定位元組數。
上面是一些常用額方法,如果想了解更多的方法請查閱JDK API文件,自行學習。
例子:下面用PreparedStatement對t_employee表進行操作,直接運用Java的封裝繼承和多型思想進行實現,減少程式碼冗餘。建立表:
create table t_employee(
id int primary key auto_increment,
userName varchar(20),
salary decimal(6,2),
job varchar(20),
jobTypeId int
)
package com.panli.dbutil;
/**
* 連線資料庫
*/
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DbUtil {
//資料庫驅動名字
private static String jdbcName = "com.mysql.jdbc.Driver";
//資料庫協議地址
private static String dbUrl = "jdbc:mysql://localhost:3306/db_user";
//資料庫使用者名稱
private static String dbUser = "root";
//資料庫密碼
private static String dbPassword = "123456";
/**
* 獲取連線
* @return
* @throws Exception
*/
public static Connection getCon() throws Exception{
Class.forName(jdbcName);
Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
return conn;
}
/**
* 關閉連線
* @param stmt
* @param conn
* @throws Exception
*/
public static void close(Statement stmt,Connection conn) throws Exception{
if(stmt!=null){
stmt.close();
if(conn!=null){
conn.close();
}
}
}
/**
* 關閉連線
* @param cstmt
* @param conn
* @throws Exception
*/
public static void close(CallableStatement cstmt, Connection conn) throws Exception{
if(cstmt!=null){
cstmt.close();
if(conn!=null){
conn.close();
}
}
}
/**
* 關閉連線
* @param pstmt
* @param conn
* @throws SQLException
*/
public static void close(PreparedStatement pstmt, Connection conn) throws SQLException{
if(pstmt!=null){
pstmt.close();
if(conn!=null){
conn.close();
}
}
}
/**
* 過載關閉方法
* @param pstmt
* @param conn
* @throws Exception
*/
public void close(ResultSet rs,PreparedStatement pstmt, Connection conn) throws Exception{
if(rs!=null){
rs.close();
if(pstmt!=null){
pstmt.close();
if(conn!=null){
conn.close();
}
}
}
}
}
package com.panli.model;
import java.io.File;
/**
* model包下的employee類,對每個欄位進行建模
* @author Peter
*
*/
public class Employee {
private int id;
private String userName;
private double salary;
private String job;
private int jobTypeId;
private File context;
private File pic;
/**
* 帶有6個引數的構造方法
* @param userName
* @param salary
* @param job
* @param jobTypeId
* @param context
* @param pic
*/
public Employee(String userName, double salary, String job, int jobTypeId,
File context, File pic) {
super();
this.userName = userName;
this.salary = salary;
this.job = job;
this.jobTypeId = jobTypeId;
this.context = context;
this.pic = pic;
}
/**
* 具有5個引數的構造方法
* @param userName
* @param salary
* @param job
* @param jobTypeId
* @param context
*/
public Employee(String userName, double salary, String job, int jobTypeId,
File context) {
super();
this.userName = userName;
this.salary = salary;
this.job = job;
this.jobTypeId = jobTypeId;
this.context = context;
}
/**
* 預設的構造方法
*/
public Employee() {
super();
// TODO Auto-generated constructor stub
}
/**
* 帶一個引數的構造方法
* @param id
*/
public Employee(int id) {
super();
this.id = id;
}
/**
* 帶4個引數的構造方法
* @param userName
* @param salary
* @param job
* @param jobTypeId
*/
public Employee(String userName, double salary, String job, int jobTypeId) {
super();
this.userName = userName;
this.salary = salary;
this.job = job;
this.jobTypeId = jobTypeId;
}
/**
* 帶引數的構造方法
* @param id
* @param userName
* @param salary
* @param job
* @param jobTypeId
*/
public Employee(int id, String userName, double salary, String job,
int jobTypeId) {
super();
this.id = id;
this.userName = userName;
this.salary = salary;
this.job = job;
this.jobTypeId = jobTypeId;
}
/**
* 重寫toString()方法
*/
@Override
public String toString() {
return "Employee:[id=" + id + ", userName=" + userName + ", salary="
+ salary + ", job=" + job + ", jobTypeId=" + jobTypeId + "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public int getJobTypeId() {
return jobTypeId;
}
public void setJobTypeId(int jobTypeId) {
this.jobTypeId = jobTypeId;
}
public File getContext() {
return context;
}
public void setContext(File context) {
this.context = context;
}
public File getPic() {
return pic;
}
public void setPic(File pic) {
this.pic = pic;
}
}
package com.panli.dao;
/**
* 對t_employee表進行增刪改操作
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.panli.dbutil.DbUtil1;
import com.panli.model.Employee;
public class EmployeeDao {
private static DbUtil dbUtil = new DbUtil();
/**
* 對employee表新增資料
* @param employee
* @return
* @throws Exception
*/
public static int addData(Employee employee) throws Exception{
Connection conn = dbUtil.getCon();
String sql = "insert into t_employee values(null,?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, employee.getUserName());
pstmt.setDouble(2, employee.getSalary());
pstmt.setString(3, employee.getJob());
pstmt.setInt(4, employee.getJobTypeId());
int result = pstmt.executeUpdate();
dbUtil.close(pstmt, conn);
return result;
}
/**
* 對資料庫表內容進行修改
* @param employee
* @return
* @throws Exception
*/
public static int updateData(Employee employee) throws Exception{
Connection conn = dbUtil.getCon();
String sql = "update t_employee set userName=?,salary=?,job=?,jobTypeId=? where id = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, employee.getUserName());
pstmt.setDouble(2, employee.getSalary());
pstmt.setString(3, employee.getJob());
pstmt.setInt(4, employee.getJobTypeId());
pstmt.setInt(5, employee.getId());
int result = pstmt.executeUpdate();
dbUtil.close(pstmt, conn);
return result;
}
/**
* 對資料表內容刪除
* @param employee
* @return
* @throws Exception
*/
public static int deleteData(Employee employee) throws Exception{
Connection conn = dbUtil.getCon();
String sql = "delete from t_employee where id=? ";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, employee.getId());
int result = pstmt.executeUpdate();
dbUtil.close(pstmt, conn);
return result;
}
}
package com.panli.test;
/**
* 對使用PreparedStatement操作資料庫表內容的增刪改操作的測試
*/
import com.panli.dao.EmployeeDao;
import com.panli.model.Employee;
public class Test1 {
private static EmployeeDao employeeDao = new EmployeeDao();
public static void main(String[] args) throws Exception {
/**
* 對資料庫表內容新增
*/
/*
Employee employee = new Employee("川普", 100,"總統", 3);
int result = employeeDao.addData(employee);
if(result == 1){
System.out.println("資料插入成功!");
}else{
System.out.println("資料插入失敗!");
}
*/
/**
* 對資料表內容修改
*/
/*
Employee employee = new Employee(3,"科比",800,"創業",2);
int result = employeeDao.updateData(employee);
if(result == 1){
System.out.println("資料修改成功!");
}else{
System.out.println("資料修改失敗!");
}
*/
Employee employee = new Employee(7);
int result = employeeDao.deleteData(employee);
if(result == 1){
System.out.println("資料刪除成功!");
}else{
System.out.println("資料刪除失敗!");
}
}
}