上一篇博客中我讲了使用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("数据删除失败!");
}
}
}