数据库Dao层抽象出BasicDao类 | 许久没碰Java了、致Java初学者

前言: 最近呢,接了一个PLC-ERP的项目,要使用RS232串口通信,时间很赶、实在没有办法了,就是用Java动身喽。好早学习Java的时候,仅仅封装了一个连接以及关闭数据库的类,这次呢,那肯定要抽象出操作的Event方法的。


有了BasicDao之后,在简单的增删改查中,你会体验到特别方便!


如何连接数据库就不说了(jdbc),重点在于封装操作MySQL数据库的方法,还是直接看代码!

package com.samego.java.dev.dao.basic;

import com.samego.java.dev.common.BasicConnection;
import com.samego.java.dev.dao.presenter.SameGoToolDao;
import org.apache.commons.beanutils.BeanUtils;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * BaseDao的实现
 * 所有的Dao都要继承该类
 * Created by alic(AlicFeng) on 17-5-24.
 * Email is alic@samego.com
 */
public class BasicDao {
    private Connection connection;
    private PreparedStatement preparedStatement;
    private ResultSet resultSet;

    /**
     * 更新的通用方法 including update/insert/delete
     *
     * @param sql         SQL
     * @param paramsValue prepareStatement sql语句中占位符对应的值(如果没有占位符,传入null)
     * @param logMessage  日志信息
     * @return 数据库更新的数目
     */
    public int update(String sql, Object[] paramsValue, String[] logMessage) {
        int result = -1;
        try {
            connection = BasicConnection.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            int count = preparedStatement.getParameterMetaData().getParameterCount();
            if (paramsValue != null && paramsValue.length > 0) {
                //循环给参数赋值
                for (int i = 0; i < count; i++) {
                    preparedStatement.setObject(i + 1, paramsValue[i]);
                }
            }
            result = preparedStatement.executeUpdate();
        } catch (SQLException e) {
            this.writeLog(logMessage);
            e.printStackTrace();
        } finally {
            BasicConnection.closeConnection(null, preparedStatement, connection);
        }
        return result;
    }

    /**
     * 查询通用方法
     *
     * @param sql         SQL
     * @param paramsValue prepareStatement
     * @param tClass      对象的类
     * @param logMessage  日志
     * @param <T>         返回类的集合
     * @return 返回类的集合
     */
    public <T> List<T> query(String sql, Object[] paramsValue, Class<T> tClass, String[] logMessage) {
        List<T> list = new ArrayList<>();
        connection = BasicConnection.getConnection();
        try {
            preparedStatement = connection.prepareStatement(sql);
            if (paramsValue != null && paramsValue.length > 0) {
                for (int i = 0; i < paramsValue.length; i++) {
                    preparedStatement.setObject(i + 1, paramsValue[i]);
                }
            }
            resultSet = preparedStatement.executeQuery();
            ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
            int columnCount = resultSetMetaData.getColumnCount();
            T t;
            while (resultSet.next()) {
                t = tClass.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = resultSetMetaData.getColumnName(i + 1);
                    Object value = resultSet.getObject(columnName);
                    BeanUtils.copyProperty(t, columnName, value);
                }
                list.add(t);
            }
        } catch (Exception e) {
            this.writeLog(logMessage);
            e.printStackTrace();
        } finally {
            BasicConnection.closeConnection(resultSet, preparedStatement, connection);
        }
        return list;
    }

    /**
     * @param sql         SQL
     * @param paramsValue prepareStatement
     * @param columnName  查询的字段名
     * @param logMessage  日志
     * @return 数量值
     */
    public Object queryByOne(String sql, Object[] paramsValue, String columnName, String[] logMessage) {
        Object result = null;
        connection = BasicConnection.getConnection();
        try {
            preparedStatement = connection.prepareStatement(sql);
            if (paramsValue != null && paramsValue.length > 0) {
                for (int i = 0; i < paramsValue.length; i++) {
                    preparedStatement.setObject(i + 1, paramsValue[i]);
                }
            }
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                result = resultSet.getObject(columnName);
            }
        } catch (Exception e) {
            this.writeLog(logMessage);
            e.printStackTrace();
        } finally {
            BasicConnection.closeConnection(resultSet, preparedStatement, connection);
        }
        return result;
    }

    /**
     * 写日志
     *
     * @param logMessage 日志信息
     */
    private void writeLog(String[] logMessage) {
        if (null != logMessage && 2 == logMessage.length) {
            SameGoToolDao.queryLog(logMessage[0], logMessage[1], false);
        }
    }
}

封装好了之后,那么我们就早Dao类继承,使用简洁又简单!看代码

  • update
    @Override
    public boolean updateFinishPerProductTimeUnit(int time) {
        boolean result = false;
        String[] logMessage = {"更改系统值", "修改每一件产品的用时失败"};
        Object[] paramValues = {time};
        if (super.update(SQLCommands.UPDATE_PER_PRODUCT_TIME_UNIT, paramValues, logMessage) > 0) {
            result = true;
            ETCVar.PRODUCT_UNIT_TIME = time;
            SameGoToolDao.queryLog("更改系统值", "修改每一件产品的用时成功", true);
        }
        return result;
    }
  • query
    @Override
    public ArrayList<MachineWork> machineWorkSign() {
        ArrayList<MachineWork> machineWorks = super.query(SQLCommands.MACHINE_WORK_SIGN_CHECK, null, MachineWork.class, null);
    }
  • queryByOne
    @Override
    public int getLastMonthFinishedOrderNum() {
        Object[] paramsValues = {Strings.ORDER_STATUS_LIST[2]};
        String[] logMessage = {"报告报表", "查询上个月的订单数失败"};
        int lastMonthOrderFinishedNum = Integer.parseInt(super.queryByOne(SQLCommands.LAST_MONTH_FINISHED_ORDER_NUM, paramsValues, "order_num", logMessage).toString());
        SameGoToolDao.queryLog("报告报表", "查询上个月的订单数成功", true);
        return lastMonthOrderFinishedNum;
    }

注意: 使用到的第三方Jar有

  • org.apache.commons.beanutils.BeanUtils
  • commons-logging-1.0.4.jar这个编辑代码看不出,但是一定要引入,上面的依赖这个

个人的建议: 1、对于SQL语句呢,最好集中在一个类文件 2、使用占位符赋值-PreparedStatement,防止SQL注入


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Flutter入门

Weex是如何在Android客户端上跑起来的

Weex可以通过自己设计的DSL,书写.we文件或者.vue文件来开发界面,整个页面书写分成了3段,template、style、script,借鉴了成熟的MV...

1874
来自专栏大魏分享(微信公众号:david-share)

实战:应用对持久数据访问| 从开发角度看应用架构9

JPA的API有主要以下几个:实体(entity)、持久性单元(persistence units)、持久性上下文( persistence context)、...

863
来自专栏IT笔记

SpringBoot开发案例之整合Spring-data-jpa

即使你是天才,如果你不努力,你也会被其它人超越。 ? 201509100645102367.jpg 扯淡 扯了那么多篇SpringBoot的相关案例,基本每行代...

3104
来自专栏扎心了老铁

springboot mybatis 事务管理

本文主要讲述springboot提供的声明式的事务管理机制。 一、一些概念 声明式的事务管理是基于AOP的,在springboot中可以通过@Transacti...

3967
来自专栏Web项目聚集地

手写一个Mybatis框架

在手写自己的Mybatis框架之前,我们先来了解一下Mybatis,它的源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,才能够更深入的理解源...

772
来自专栏.NET后端开发

ADO.NET入门教程(七) 谈谈Command对象高级应用

摘要 在上一篇文章《你必须知道的ADO.NET(六) 谈谈Command对象与数据检索》中,我详细讲解了Command对象的基础知识以及基本用法。作为ADO.N...

3768
来自专栏Android Note

Realm 基本用法

1477
来自专栏difcareer的技术笔记

JNI实现源码分析【四 函数调用】正文0x01:dvmCallMethodV0x02:nativeFunc0x03: 何时赋值

有了前面的铺垫,终于可以说说虚拟机是如何调用JNI方法的了。JNI方法,对应Java中的native方法,所以我们跟踪对Native方法的处理即可。

684
来自专栏陈树义

简单笔记

1、类的表面类型和实际类型 实例对象有两个类型:表面类型(Apparent Type)和实际类型(ActualType),表面类型是声明时的类型,实际类型是对象...

2455
来自专栏Java帮帮-微信公众号-技术文章全总结

数据库连接池、dbutil_知识点全掌握

数据库连接池、dbutil ? 数据库连接池 1 数据库连接池的概念 用池来管理Connection,这可以重复使用Connection。有了池,所以我们就不用...

2835

扫码关注云+社区