MySQL数据库入门学习(四)——使用工具类封装JDBC实现MySQL的更新操作
1.前言
我们知道,事实上,MySQL的 “增删查改”其实就是分为两类,一类是更新操作:int executeUpdate(String sql)包括了插入(insert),更新(update),删除(delete);另外一类是查询操作(select),由ResultSet executeQuery(String sql) 实现。
观察数据库更新操作时的代码:
/**
* @param book 需要保存的对象
* @return 保存成功返回1否则返回 0
*/
public int saveByPrepareStatement(Book book) {
//拼接需要执行的sql语句
String sql = "insert into book(name,price,status,discount,isBorrowed,createTime) values(?,?,?,?,?,?)";
int result = 0;
try {
//获取创建连接
Connection connection = JDBCUtil.getConnection();
//创建预处理对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置name占位符对应的值
preparedStatement.setString(1, book.getName());
//设置price占位符对应的值
preparedStatement.setDouble(2, book.getPrice());
//设置status占位符对应的值
preparedStatement.setByte(3, book.getStatus());
//设置discount占位符对应的值
preparedStatement.setFloat(4, book.getDiscount());
//设置isBorrowed对应占位符的值
preparedStatement.setBoolean(5, book.isBorrowed());
//设置createTime占位符对应的值,需要将 java.Util.Date 转化为 java.sql.Date才可以
preparedStatement.setDate(6,new Date(book.getCreateTime().getTime()));
//开始执行,并返回影响的行数
result = preparedStatement.executeUpdate();
//释放资源,先开启的后释放
JDBCUtil.close(connection, preparedStatement, null);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
/**
* 更新book
* @param newBook
* @return 返回受影响的行数
*/
public int updateBookByPreparedStatement(Book newBook) {
//拼接需要执行的更新sql语句
String sql = "update book set name=?,price = ?,status = ?,discount = ?,isBorrowed = ?,createTime = ? where id = ?";
int result = 0;
try {
//获取创建连接
Connection connection = JDBCUtil.getConnection();
//创建预处理对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置name占位符对应的值
preparedStatement.setString(1, newBook.getName());
//设置price占位符对应的值
preparedStatement.setDouble(2, newBook.getPrice());
//设置status占位符对应的值
preparedStatement.setByte(3, newBook.getStatus());
//设置discount占位符对应的值
preparedStatement.setFloat(4, newBook.getDiscount());
//设置isBorrowed对应占位符的值
preparedStatement.setBoolean(5, newBook.isBorrowed());
//设置createTime占位符对应的值,需要将 java.Util.Date 转化为 java.sql.Date才可以
preparedStatement.setDate(6,new Date(newBook.getCreateTime().getTime()));
//设置id占位符对应的值
preparedStatement.setInt(7, newBook.getId());
//开始执行更新,并返回影响的行数
result = preparedStatement.executeUpdate();
//释放资源,先开启的后释放
JDBCUtil.close(connection, preparedStatement, null);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
/**
* 删除book
* @param id 需要删除书籍的ID
* @return 返回受影响的行数
*/
public int deleteBookById(int id) {
//拼接需要执行的删除的sql语句
String sql = "delete from book where id = ?";
int result = 0;
try {
//获取创建连接
Connection connection = JDBCUtil.getConnection();
//创建预处理对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置id占位符对应的值
preparedStatement.setInt(1, id);
//开始执行更新,并返回影响的行数
result = preparedStatement.executeUpdate();
//释放资源,先开启的后释放
JDBCUtil.close(connection, preparedStatement, null);
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
我们发现,更新(insert,update,delete)这三个操作有这几个步骤:
①获取连接对象Connection 。
②根据sql语句创建预处理对象PreparedStatement
③使用实际参数替换PreparedStatement 中的占位符“?”。
④执行更新操作
⑤关闭资源
⑥返回影响的行数result(一个int类型)
其中preparedStatement.setXXX(int parameterIndex, XXX x);中XXX也就是填充的实际参数类型是不确定的。这时候我们可以使用preparedStatement.setObject(int parameterIndex, Object x)来进行设置参数。因为Object是所有类的公共父类,所以使用这个参数可以达到代码通用性来设置占位符“?"。
由此我们可以将更新操作封装成一个方法int upDate(String sql,Object … params)。
其中参数sql为需要执行的包含有占位符“?”的SQL语句,比如“delete from book where id =?” ,params是一个Object可变数组,存储着preparedStatement中占位符“?”的实际参数,有多少个占位符就有多少个实际参数,并且每个占位符的次序和其对应的实际参数的次序要一样。
2. 在工具类JDBCUtil.java中更新操作方法的封装实现
/**
* 执行sql的更新语句。
* @param sql 需要执行的sql语句
* @param params 预处理占位符中的实际参数数组
* @return 返回受影响的行数
*/
public static int upDate(String sql,Object... params){
if (params==null||params.length==0) return 0;
//获取连接对象
Connection connection=JDBCUtil.getConnection();
PreparedStatement preparedStatement=null;
int result = 0;
try {
//创建预处理对象
preparedStatement= connection.prepareStatement(sql);
//使用实际参数替换占位符
for (int i= 0;i < params.length;i++){
//parameterIndex从1开始
preparedStatement.setObject(i+1,params[i]);
}
//执行sql语句
result = preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
//关闭资源
JDBCUtil.close(connection,preparedStatement,null);
return result;
}
3.修改BookDao.java中属于更新操作(insert,delete,update)的代码使用封装好的int upDate(String sql,Object… params)
package dao;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import entity.Book;
import util.JDBCUtil;
/**
* @author 陌意随影
TODO : BookDao
*2020年10月30日 下午9:04:08
*/
public class BookDao {
/**
* @param book 需要保存的对象
* @return 保存成功返回1否则返回 0
*/
public int saveByPrepareStatement(Book book) {
//需要执行的sql语句
String sql = "insert into book(name,price,status,discount,isBorrowed,createTime) values(?,?,?,?,?,?)";
//调用工具类封装的更新方法进行插入操作
int result = JDBCUtil.upDate(sql,
book.getName(),book.getPrice(),
book.getStatus(),book.getDiscount(),
book.isBorrowed(),book.getCreateTime()
);
return result;
}
/**
* 更新book
* @param newBook
* @return 返回受影响的行数
*/
public int updateBookByPreparedStatement(Book newBook) {
//需要执行的更新sql语句
String sql = "update book set name=?,price = ?,status = ?,discount = ?,isBorrowed = ?,createTime = ? where id = ?";
//调用工具类封装的更新方法进行更新操作
int result = JDBCUtil.upDate(sql,
newBook.getName(),newBook.getPrice(),
newBook.getStatus(),newBook.getDiscount(),
newBook.isBorrowed(),newBook.getCreateTime()
,newBook.getId());
return result;
}
/**
* 删除book
* @param id 需要删除书籍的ID
* @return 返回受影响的行数
*/
public int deleteBookById(int id) {
//需要执行的删除的sql语句
String sql = "delete from book where id = ?";
//调用工具类封装的更新方法进行删除操作
int result = JDBCUtil.upDate(sql, id);
return result;
}
/**
* 通过ID查询book
* @param id 要查询的book的ID
* @return 返回ID对应的book
*/
public Book findBookById(int id) {
//需要执行的查找的sql语句
String sql = "select * from book where id = ?";
//结果集
ResultSet resultSet = null;
Book book = null;
try {
//获取创建连接
Connection connection = JDBCUtil.getConnection();
//创建预处理对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//设置id占位符对应的值
preparedStatement.setInt(1, id);
//开始执行查询语句,并返回查询的结果集
resultSet = preparedStatement.executeQuery();
//如果查询到结果不为空而是有记录
if(resultSet.next()) {
//获取book的name
String name = resultSet.getString("name");
//获取book的status
byte status = resultSet.getByte("status");
//获取book的price
double price = resultSet.getDouble("price");
//获取book的discount
float discount = resultSet.getFloat("discount");
//获取book的isBorrowed
boolean isBorrowed = resultSet.getBoolean("isBorrowed");
//获取book的createTime
Date date = resultSet.getDate("createTime");
book = new Book();
book.setBorrowed(isBorrowed);
book.setDiscount(discount);
book.setId(id);
book.setPrice(price);
book.setName(name);
book.setStatus(status);
book.setCreateTime(date);
}
//释放资源,先开启的后释放
JDBCUtil.close(connection, preparedStatement, resultSet);
} catch (SQLException e) {
e.printStackTrace();
book = null;
}
return book;
}
/**
* 查询所有图书
* @return 返回List<book>
*/
public List<Book> findAllBook() {
//拼接需要执行的查找的sql语句
String sql = "select * from book ";
//结果集
ResultSet resultSet = null;
List<Book> bookList = null;
try {
//获取创建连接
Connection connection = JDBCUtil.getConnection();
//创建预处理对象
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//开始执行查询语句,并返回查询的结果集
resultSet = preparedStatement.executeQuery();
bookList = new ArrayList<>();
//如果查询到结果不为空而是有记录
while(resultSet.next()) {
//获取book的ID
int id = resultSet.getInt("id");
//获取book的name
String name = resultSet.getString("name");
//获取book的status
byte status = resultSet.getByte("status");
//获取book的price
double price = resultSet.getDouble("price");
//获取book的discount
float discount = resultSet.getFloat("discount");
//获取book的isBorrowed
boolean isBorrowed = resultSet.getBoolean("isBorrowed");
//获取book的createTime
Date date = resultSet.getDate("createTime");
Book book = new Book();
book.setBorrowed(isBorrowed);
book.setDiscount(discount);
book.setId(id);
book.setPrice(price);
book.setName(name);
book.setStatus(status);
book.setCreateTime(date);
bookList.add(book);
}
//释放资源,先开启的后释放
JDBCUtil.close(connection, preparedStatement, resultSet);
} catch (SQLException e) {
e.printStackTrace();
bookList = null;
}
return bookList;
}
}
4.使用JUnit单元测试
package test;
import java.util.Date;
import java.util.List;
import org.junit.jupiter.api.Test;
import dao.BookDao;
import entity.Book;
class BookDaoTest {
@Test
void testUpdateBook() {
Book newBook = new Book();
newBook.setId(1);
newBook.setName("红楼梦");
newBook.setCreateTime(new Date());
newBook.setBorrowed(Book.isBorrowed_FALSE);
newBook.setPrice(60.5);
newBook.setStatus(Book.STATUS_NORMAL);
BookDao bookDao = new BookDao();
int result = bookDao.updateBookByPreparedStatement(newBook);
if(result == 1) {
System.out.println("更新书籍成功!");
}else {
System.out.println("更新书籍失败!");
}
}
@Test
void testdeleteBookById() {
BookDao bookDao = new BookDao();
int result = bookDao.deleteBookById(2);
if(result == 1) {
System.out.println("删除书成功!");
}else {
System.out.println("删除书失败!");
}
}
@Test
void testFindBookById() {
BookDao bookDao = new BookDao();
Book book = bookDao.findBookById(3);
if(book != null) {
System.out.println("查找书籍成功:"+ book);
}else {
System.out.println("数据库中不存在该书籍!");
}
}
@Test
void testFindAllBook() {
BookDao bookDao = new BookDao();
List<Book> bookList = bookDao.findAllBook();
if(bookList == null || bookList.size() == 0) {
System.out.println("书籍为空!");
}else {
for(Book book : bookList) {
System.out.println(book);
}
}
}
}
经过测试发现可以正常进行数据库的更新操作。
5.本次实验环境
eclipse219 ,jdk1.8,mysql8.0