![cover](/upload/数据库原理.jpg)
数据库原理:作业 09
实验6:JDBC进阶(3)
相关知识点
- JDBC基本概念
- 批处理
- DAO和OR映射
实验目的:
掌握批量SQL语句执行的方法,理解DAO和ORM的基本概念
实验内容:
利用批量SQL语句执行的方法实现实验5中的最后两个方法:
编写批量借阅读书函数: public void lendbooks(String readerId,Collection barcodes) .... 。其中第二个参数为图书条码集合。
public void lendbooks(String readerId,Collection<String> barcodes) throws BaseException {
Object[] objects = barcodes.toArray();
for (int i = 0; i < objects.length; i++) {
lend((String) objects[i],readerId);
}
}
编写批量设置罚金函数:public void setPenalSum(String readerId,Map<String,Double> penalSums) .... 。其中第二个参数的key为barcode,value为改读者尚未归还图书的罚金(注意,不要设置已经归还图书的罚金)。
public void setPenalSum(String readerId,Map<String,Double> penalSums) throws Exception {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = DBUtil.getConnection();
String sql = "update beanbooklendrecord set penalSum = ? where readerid = ? and bookBarcode = ? and returnDate is null";
ps = conn.prepareStatement(sql);
ps.setObject(2,readerId);
for (Map.Entry<String,Double> x : penalSums.entrySet()) {
String barcode = x.getKey();
double penal = x.getValue();
ps.setObject(1,penal);
ps.setObject(3,barcode);
ps.execute();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.closeResorce(conn,ps);
}
}
模仿SystemUserDAO类,实现BookDAO类,并改造BookManager类,使之通过BookDAO操作数据库。
给出BookDAO类代码。
package cn.edu.zucc.booklib.dao;
import cn.edu.zucc.booklib.model.BeanBook;
import cn.edu.zucc.booklib.util.BaseException;
import cn.edu.zucc.booklib.util.BusinessException;
import cn.edu.zucc.booklib.util.DBUtil;
import cn.edu.zucc.booklib.util.DbException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class BookDAO {
public List<BeanBook> searchBook(String keyword, String bookState) throws BaseException {
List<BeanBook> result = new ArrayList<BeanBook>();
Connection conn = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from view_book" + " where state='" + bookState + "' ";
if (keyword != null && !"".equals(keyword))
sql += " and (bookname like ? or barcode like ?)";
sql += " order by barcode";
java.sql.PreparedStatement pst = conn.prepareStatement(sql);
if (keyword != null && !"".equals(keyword)) {
pst.setString(1, "%" + keyword + "%");
pst.setString(2, "%" + keyword + "%");
}
java.sql.ResultSet rs = pst.executeQuery();
while (rs.next()) {
BeanBook b = new BeanBook();
b.setBarcode(rs.getString(1));
b.setBookname(rs.getString(2));
b.setPubid(rs.getString(3));
b.setPrice(rs.getDouble(4));
b.setState(rs.getString(5));
b.setPubName(rs.getString(6));
result.add(b);
}
} catch (SQLException e) {
e.printStackTrace();
throw new DbException(e);
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
public void createBook(BeanBook b) throws BaseException {
if (b.getBarcode() == null || "".equals(b.getBarcode()) || b.getBarcode().length() > 20) {
throw new BusinessException("条码必须是1-20个字");
}
if (b.getBookname() == null || "".equals(b.getBookname()) || b.getBookname().length() > 50) {
throw new BusinessException("图书名称必须是1-50个字");
}
Connection conn = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from BeanBook where barcode=?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, b.getBarcode());
ResultSet rs = pst.executeQuery();
if (rs.next()) throw new BusinessException("条码已经被占用");
rs.close();
pst.close();
sql = "insert into BeanBook(barcode,bookname,pubid,price,state) values(?,?,?,?,'在库')";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, b.getBarcode());
ps.setObject(2, b.getBookname());
ps.setString(3, b.getPubid());
ps.setDouble(4, b.getPrice());
ps.execute();
pst.close();
} catch (SQLException e) {
e.printStackTrace();
throw new DbException(e);
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void modifyBook(BeanBook b) throws BaseException {
if (b.getBookname() == null || "".equals(b.getBookname()) || b.getBookname().length() > 50) {
throw new BusinessException("图书名称必须是1-50个字");
}
Connection conn = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from BeanBook where barcode=?";
java.sql.PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, b.getBarcode());
java.sql.ResultSet rs = pst.executeQuery();
if (!rs.next()) throw new BusinessException("图书不存在");
rs.close();
pst.close();
sql = "update BeanBook set bookname=?,pubid=?,price=?,state=? where barcode=?";
pst = conn.prepareStatement(sql);
pst.setString(1, b.getBookname());
pst.setString(2, b.getPubid());
pst.setDouble(3, b.getPrice());
pst.setString(4, b.getState());
pst.setString(5, b.getBarcode());
pst.execute();
pst.close();
} catch (SQLException e) {
e.printStackTrace();
throw new DbException(e);
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public BeanBook loadBook(String barcode) throws DbException {
Connection conn = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from view_book " + " where barcode=? ";
java.sql.PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, barcode);
java.sql.ResultSet rs = pst.executeQuery();
if (rs.next()) {
BeanBook b = new BeanBook();
b.setBarcode(rs.getString(1));
b.setBookname(rs.getString(2));
b.setPubid(rs.getString(3));
b.setPrice(rs.getDouble(4));
b.setState(rs.getString(5));
b.setPubName(rs.getString(6));
return b;
}
} catch (SQLException e) {
e.printStackTrace();
throw new DbException(e);
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
给出改造后BookManager类的各个方法的代码。
public List<BeanBook> searchBook(String keyword, String bookState) throws BaseException, SQLException {
Connection conn = null;
try {
conn = DBUtil.getConnection();
return dao.searchBook(keyword, bookState);
} catch (SQLException e) {
e.printStackTrace();
} catch (BaseException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return null;
}
public void createBook(BeanBook b) throws BaseException, SQLException {
Connection conn = null;
try {
conn = DBUtil.getConnection();
dao.createBook(b);
} catch (SQLException e) {
e.printStackTrace();
} catch (BaseException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public void modifyBook(BeanBook b) throws BaseException, SQLException {
Connection conn = null;
try {
conn = DBUtil.getConnection();
dao.modifyBook(b);
} catch (SQLException e) {
e.printStackTrace();
} catch (BaseException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
public BeanBook loadBook(String barcode) throws DbException, SQLException {
Connection conn = null;
try {
conn = DBUtil.getConnection();
dao.loadBook(barcode);
} catch (SQLException e) {
e.printStackTrace();
} catch (DbException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return null;
}
在BaseDAO中,增加方法,实现根据主码提取对象的方法load。
写出函数代码
ublic T load(Connection conn, Class<T> clazz, Map<String,Object> primaryKey) {
PreparedStatement ps = null;
ResultSet rs = null;
try {
//primayKey的key为主码的各个属性名称,value为主码值
//假设对象的类名和表名一致,属性名和字段名一致
String tableName = clazz.getSimpleName();
String sql = "select * from "+tableName+" where"; //动态构建sql
for (Map.Entry mp : primaryKey.entrySet()) {
sql += " " + mp.getKey().toString() + " = ? and";
}
sql = sql.substring(0,sql.length()-3);
Object[] parmas = new Object[primaryKey.size()];
//从map中获取参数值,并写入params
int pos = 0;
for (Map.Entry<String, Object> mp : primaryKey.entrySet()) {
parmas[pos++] = mp.getValue();
}
ps = conn.prepareStatement(sql);
for (int i = 0; i < parmas.length; i++) {
ps.setObject(i+1,parmas[i]);
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
if (rs.next()) {
T t = clazz.getDeclaredConstructor().newInstance();
for (int i = 0; i < rsmd.getColumnCount(); i++) {
//获取当前rs指针的i+1字段的值
Object value = rs.getObject(i+1);
//获取当前rs指针的i+1字段的列名
String columnLable = rsmd.getColumnLabel(i+1);
//将value赋值给对应属性,反射
Field field = clazz.getDeclaredField(columnLable);
field.setAccessible(true);
field.set(t, value);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtil.closeResorce(null,ps,rs);
}
return null;
}
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Owen
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果