JDBC的DML增删改查的代码重构设计(下)

本文介绍了一种基于JDBC的模板方法模式,并通过具体示例展示了如何利用该模式进行数据库操作。此外,还介绍了如何使用Hibernate进行对象关系映射(ORM),包括对象的保存、删除、更新、查询等操作。

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

JDBC的操作模板:

流程:1.创建ProductResultSetHandler对象:
     2.作为参数传递给query方法
     3.在query方法中:rsh.handler,其实调用的是ProductResultSetHanlder方法

结果集处理规范:

//定义一个专门的约束处理结果集的接口:ResultSetHandler:结果集处理器
public interface ResultSetHandler<T> {
    //同意规定,必须有一个处理结果集的方法:handle,处理之后返回结果
    T handle(ResultSet rs) throws SQLException;
}

调用的模板方法:

public class JdbcTemplate {

    private JdbcTemplate() {

    }

    /**
     * 
     *@param sql   DML各自的SQL,由调用者决定
     *@param params      DML操作需要的参数,由调用者决定
     *@return     受影响的行数
     */
    public static int update(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn = JdbcUtil.INSTANCE.getConn();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.INSTANCE.close(conn, ps, null);
        }
        return 0;
    }

    public static <T>T query(String sql, ResultSetHandler<T> rsh ,Object... params) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtil.INSTANCE.getConn();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            rs = ps.executeQuery();
            return rsh.handle(rs);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.INSTANCE.close(conn, ps, rs);
        }
        return null;
    }

实现类的操作代码:

public class ProductDAOImpl implements IProductDAO {

    public void save(Product pro) {
        /*String sql = "insert into product (productName,brand,supplier,salePrice,costPrice,cutoff,dir_id ) values (?,?,?,?,?,?,?)";
        Object[] params = { pro.getProductName(), pro.getBrand(), pro.getSupplier(), pro.getSalePrice(),
                pro.getCostPrice(), pro.getCutoff(), pro.getDir_id() };
        JdbcTemplate.update(sql, params);*/
        //拓展Hibernate的save操作:
        HibernateMock.save(pro); 
    }

    public void delete(Long id) {
        String sql = "delete from product where id =  ? ";
        JdbcTemplate.update(sql, id);
    }

    public void update(Product pro) {
        String sql = "UPDATE product SET productName = ?, brand = ?, supplier = ?, salePrice = ?, costPrice = ?, cutoff = ?, dir_id = ?  WHERE id = ?";
        Object[] params = { pro.getProductName(), pro.getBrand(), pro.getSupplier(), pro.getSalePrice(),
                pro.getCostPrice(), pro.getCutoff(), pro.getDir_id(), pro.getId() };
        JdbcTemplate.update(sql, params);
    }

    public Product get(Long id) {
        String sql = "select * from product where id = ?";
        List<Product> list = JdbcTemplate.query(sql, new ProductResultHandler(),id);
        return list.size()==1? list.get(0):null;
    }

    public List<Product> list() {
        String sql = "SELECT * FROM product";
        return JdbcTemplate.query(sql,new ProductResultHandler());
    }

    //定义处理商品对象的结果集处理器
    class ProductResultHandler implements ResultSetHandler<List<Product>>{
        @Override
        public List<Product> handle(ResultSet rs) throws SQLException {
            List<Product> list = new ArrayList<>();
            while (rs.next()) {
                Product pro = new Product();
                list.add(pro);
                pro.setId(rs.getLong("id"));
                pro.setProductName(rs.getString("productName"));
                pro.setBrand(rs.getString("brand"));
                pro.setSupplier(rs.getString("supplier"));
                pro.setSalePrice(rs.getBigDecimal("salePrice"));
                pro.setCostPrice(rs.getBigDecimal("costPrice"));
                pro.setCutoff(rs.getDouble("cutoff"));
                pro.setDir_id(rs.getLong("dir_id"));
            }
            return list;
        }
    }

拓展Hibernate的save操作:

public class HibernateMock {

    /**
     * 保存操作
     * @param obj
     * 1.拼SQL
     * 2.设置封装参数
     */
    //约定优于配置:
    //要求:表中的列和对象的属性相同
    public static void save(Object obj){
        //使用内省机制获取JivaBean对象的属性
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(),Object.class);
            PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
            StringBuilder sqlBuilder = new StringBuilder();//拼接SQL
            List<Object> params = new ArrayList<>();//封装属性的值/参数值
            String tableName = obj.getClass().getSimpleName();
            sqlBuilder.append("INSERT INTO ").append(tableName).append("(");
            StringBuilder sign = new StringBuilder();//拼接占位符
            for (PropertyDescriptor pd : pds) {
                String propertyName = pd.getName();//属性名/表中的列名
                sqlBuilder.append(propertyName).append(",");//拼接列名
                sign.append("?").append(",");
                Object value = pd.getReadMethod().invoke(obj);//获取每个属性的值
                params.add(value);
            }
            sqlBuilder.deleteCharAt(sqlBuilder.length()-1);
            sign.deleteCharAt(sign.length()-1);
            sqlBuilder.append(")VALUES(").append(sign);
            sqlBuilder.append(")");
            //封装参数,执行SQL
            //调用之前编写的MDL操作模板
            JdbcTemplate.update(sqlBuilder.toString(),params.toArray());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

测试类

public class ProductDAOTest {
    private IProductDAO dao = new ProductDAOImpl();
    @Test
    public void testSave() {
        Product pro = new Product();
        pro.setProductName("iphone8s");
        pro.setBrand("apple");
        pro.setSupplier("苹果公司");
        pro.setSalePrice(new BigDecimal("7000"));
        pro.setCostPrice(new BigDecimal("2000"));
        pro.setCutoff(0.9);
        pro.setDir_id(3L);
        //pro.setId(12L);
        dao.save(pro);
    }

    @Test
    public void testDelete() {
        dao.delete(26L);
    }

    @Test
    public void testUpdate() {
        Product pro = new Product();
        pro.setProductName("iphone6s");
        pro.setBrand("apple9s");
        pro.setSupplier("苹果公司2");
        pro.setSalePrice(new BigDecimal("6000"));
        pro.setCostPrice(new BigDecimal("1000"));
        pro.setCutoff(0.8);
        pro.setDir_id(5L);
        pro.setId(8L);
        dao.update(pro);
    }

    @Test
    public void testGet() {
        Product pro = dao.get(6L);
        System.out.println(pro);
    }

    @Test
    public void testList() {
        List<Product> list = dao.list();
        for (Product p : list) {
            System.out.println(p);
        }
    }
}

JdbcUtil工具类

public enum JdbcUtil {

    INSTANCE;

    private static Properties p = new Properties();

    //只需要注册一次驱动即可,没必要每次都注册,放到jdbcutil类的静态代码块中(当字节码被加载进jvm,就会执行)
    static {
        try {
            //从classpath的根路径去加载db.properties文件
            InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
            p.load(inStream);
            Class.forName(p.getProperty("driverClassName"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建connection对象
     * @return
     */
    public Connection getConn() {
        try {
            return DriverManager.getConnection(p.getProperty("url"), p.getProperty("usename"),p.getProperty("password"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void close(Connection conn, Statement st, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (st != null) {
                    st.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (conn != null) {
                        conn.close();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

db.properties文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo?useSSL=false
usename=root
password=111111

商品对象

public class Product {
    private Long id;
    private String productName;
    private String brand;
    private String supplier;
    private BigDecimal salePrice;
    private BigDecimal costPrice;
    private Double cutoff;
    private Long dir_id;//分类编号
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public String getSupplier() {
        return supplier;
    }
    public void setSupplier(String supplier) {
        this.supplier = supplier;
    }
    public BigDecimal getSalePrice() {
        return salePrice;
    }
    public void setSalePrice(BigDecimal salePrice) {
        this.salePrice = salePrice;
    }
    public BigDecimal getCostPrice() {
        return costPrice;
    }
    public void setCostPrice(BigDecimal costPrice) {
        this.costPrice = costPrice;
    }
    public Double getCutoff() {
        return cutoff;
    }
    public void setCutoff(Double cutoff) {
        this.cutoff = cutoff;
    }
    public Long getDir_id() {
        return dir_id;
    }
    public void setDir_id(Long dir_id) {
        this.dir_id = dir_id;
    }
    @Override
    public String toString() {
        return "Product [id=" + id + ", productName=" + productName + ", brand=" + brand + ", supplier=" + supplier
                + ", salePrice=" + salePrice + ", costPrice=" + costPrice + ", cutoff=" + cutoff + ", dir_id=" + dir_id
                + "]";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值