数据库相关框架

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

框架编写

在这里插入图片描述

package com.itheima05;

import com.itheima.utils.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.*;

public class JDBCTemplate {

    /// 定义参数变量(数据源,连接对象,执行者对象,结果集对象)
    private DataSource dataSource;
    private Connection connection;
    private PreparedStatement preparedStatement;
    private ResultSet resultSet;

    /// 有参构造方法为数据源赋值
    public JDBCTemplate(DataSource dataSource)
    {
        this.dataSource=dataSource;
    }


    /// 定义update,参数sql语句,sql语句中的参数
    public int update(String sql,Object...objects)
    {
        ///定义int类型变量,用于接收增删改后影响的行数
        int result =0;
        try {
            connection=dataSource.getConnection();
            /// 通过连接对象获取执行者对象,并对sql语句进行预编译
            preparedStatement = connection.prepareStatement(sql);

            /// 执行者对象获取源信息的对象
            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            /// 判断参数数量是否一致
            if(count!=objects.length)
            {
                throw new RuntimeException("参数个数不匹配");
            }

            /// 为sql语句占位符赋值
            for (int i=0;i<objects.length;i++)
            {
                preparedStatement.setObject(i+1,objects[i]);
            }

            ///执行sql语句
            result=preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            DataSourceUtils.close(connection,preparedStatement);
        }

        return result;
    }


}

查询功能

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.itheima05.handler;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Locale;

/*
        实现类:用于将查询到的一条记录,封装为Student对象并返回
     */
public class BeanHandler<T> implements ResultSetHandler<T>{

    /// 定义Class对象类型变量
    private Class<T> beanClass;
    /// 通过有参构造为变量赋值
    public BeanHandler(Class<T> beanClass)
    {
        this.beanClass =beanClass;
    }

    //重写handler方法,用来将一条记录封装到自定义对象中
    @Override
    public  T handler(ResultSet resultSetHandler) {
        ///声明自定义对象类型
        T bean =null;

        try {
            /// 创建传递参数的对象,为自定义对象赋值
            bean=beanClass.newInstance();
            /// 判断结果集中是否有数据
            if(resultSetHandler.next())
            {
                /// 通过结果集对象获取结果集源信息的对象
                ResultSetMetaData metaData = resultSetHandler.getMetaData();

                // 通过结果集源信息对象获取烈数
                int columnCount = metaData.getColumnCount();

                /// 通过循环遍历列数
                for (int i=1;i<=columnCount;i++)
                {
                    /// 通过结果集源信息对象获取列名
                    String columnName =metaData.getColumnName(i);

                    /// 通过列名获取该列的数据
                    Object value = resultSetHandler.getObject(columnName);

                    /// 创建属性描述器对象,将获取到的值通过该对象的set方法进行赋值
                    PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName.toLowerCase(Locale.ROOT),beanClass);

                    ///获取set方法
                    Method writeMethod =propertyDescriptor.getWriteMethod();

                    /// 执行set方法,给对应执行对象进行赋值
                    writeMethod.invoke(bean,value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        /// 返回封装好的对象
        return bean;
    }
}

在这里插入图片描述
在这里插入图片描述

package com.itheima05.handler;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/*
        实现类:用于将查询到的多条记录,封装为Student对象并返回
     */
public class BeanListHandler<T> implements ResultSetHandler<T>{

    /// 定义Class对象类型变量
    private Class<T> beanClass;
    /// 通过有参构造为变量赋值
    public BeanListHandler(Class<T> beanClass)
    {
        this.beanClass =beanClass;
    }

    //重写handler方法,用来将多条记录封装到自定义对象中并添加集合返回
    @Override
    public List<T> handler(ResultSet resultSetHandler) {
        ///声明集合对象类型
       List<T> list = new ArrayList<>();

        try {

            /// 判断结果集中是否有数据
            while (resultSetHandler.next())
            {
                /// 创建传递参数的对象,为自定义对象赋值
                T bean=beanClass.newInstance();
                /// 通过结果集对象获取结果集源信息的对象
                ResultSetMetaData metaData = resultSetHandler.getMetaData();

                // 通过结果集源信息对象获取烈数
                int columnCount = metaData.getColumnCount();

                /// 通过循环遍历列数
                for (int i=1;i<=columnCount;i++)
                {
                    /// 通过结果集源信息对象获取列名
                    String columnName =metaData.getColumnName(i);

                    /// 通过列名获取该列的数据
                    Object value = resultSetHandler.getObject(columnName);

                    /// 创建属性描述器对象,将获取到的值通过该对象的set方法进行赋值
                    PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName.toLowerCase(Locale.ROOT),beanClass);

                    ///获取set方法
                    Method writeMethod =propertyDescriptor.getWriteMethod();

                    /// 执行set方法,给对应执行对象进行赋值
                    writeMethod.invoke(bean,value);
                }

                /// 将对象保存到集合中
                list.add(bean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        /// 返回封装好的对象
        return list;
    }
}


在这里插入图片描述

package com.itheima05.handler;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

public class ScalarHandler<T> implements ResultSetHandler<T>{
    @Override
    public Long handler(ResultSet resultSet) {
       /// 定义一个long类型的变量
        Long value = null;
        try {
            if(resultSet.next())
            {
                /// 获取结果集源信息的对象
                ResultSetMetaData metaData = resultSet.getMetaData();
                /// 获取第一列的列名
                String  columnName= metaData.getColumnName(1);
                value = resultSet.getLong(columnName);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return value;
    }
}

在这里插入图片描述

核心代码

package com.itheima05;

import com.itheima.utils.DataSourceUtils;
import com.itheima05.handler.ResultSetHandler;

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

public class JDBCTemplate {

    /// 定义参数变量(数据源,连接对象,执行者对象,结果集对象)
    private DataSource dataSource;
    private Connection connection;
    private PreparedStatement preparedStatement;
    private ResultSet resultSet;

    /// 有参构造方法为数据源赋值
    public JDBCTemplate(DataSource dataSource)
    {
        this.dataSource=dataSource;
    }


    /*
        查询方法 用于将聚合函数进行返回
     */

    public Long queryForScalar(String sql, ResultSetHandler<Long> resultSetHandler, Object...objects)
    {
        ///定义int类型变量,用于接收增删改后影响的行数
       Long value =null;
        try {
            connection=dataSource.getConnection();
            /// 通过连接对象获取执行者对象,并对sql语句进行预编译
            preparedStatement = connection.prepareStatement(sql);

            /// 执行者对象获取源信息的对象
            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            /// 判断参数数量是否一致
            if(count!=objects.length)
            {
                throw new RuntimeException("参数个数不匹配");
            }

            /// 为sql语句占位符赋值
            for (int i=0;i<objects.length;i++)
            {
                preparedStatement.setObject(i+1,objects[i]);
            }

            ///执行sql语句
            resultSet= preparedStatement.executeQuery();

            /// 通过ScalarHandler方式对结果进行处理
            value = resultSetHandler.handler(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            DataSourceUtils.close(connection,preparedStatement,resultSet);
        }

        return value;
    }

     /*
        查询方法 用于将多条记录封装成自定义对象并返回
     */

    public <T> List<T> queryForList(String sql, ResultSetHandler<T> resultSetHandler, Object...objects)
    {
        ///定义int类型变量,用于接收增删改后影响的行数
        List<T> list= new ArrayList<>();
        try {
            connection=dataSource.getConnection();
            /// 通过连接对象获取执行者对象,并对sql语句进行预编译
            preparedStatement = connection.prepareStatement(sql);

            /// 执行者对象获取源信息的对象
            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            /// 判断参数数量是否一致
            if(count!=objects.length)
            {
                throw new RuntimeException("参数个数不匹配");
            }

            /// 为sql语句占位符赋值
            for (int i=0;i<objects.length;i++)
            {
                preparedStatement.setObject(i+1,objects[i]);
            }

            ///执行sql语句
            resultSet= preparedStatement.executeQuery();

            /// 通过BeanListHandler方式对结果进行处理
            list = resultSetHandler.handler(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            DataSourceUtils.close(connection,preparedStatement,resultSet);
        }

        return list;
    }
    /*
        查询方法 用于将一条记录封装成自定义对象并返回
     */

    public <T> T queryForObject(String sql, ResultSetHandler<T> resultSetHandler,Object...objects)
    {
        ///定义int类型变量,用于接收增删改后影响的行数
        T obj=null;
        try {
            connection=dataSource.getConnection();
            /// 通过连接对象获取执行者对象,并对sql语句进行预编译
            preparedStatement = connection.prepareStatement(sql);

            /// 执行者对象获取源信息的对象
            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            /// 判断参数数量是否一致
            if(count!=objects.length)
            {
                throw new RuntimeException("参数个数不匹配");
            }

            /// 为sql语句占位符赋值
            for (int i=0;i<objects.length;i++)
            {
                preparedStatement.setObject(i+1,objects[i]);
            }

            ///执行sql语句
            resultSet= preparedStatement.executeQuery();

            /// 通过BeanHandler方式对结果进行处理
            obj = resultSetHandler.handler(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            DataSourceUtils.close(connection,preparedStatement,resultSet);
        }

        return obj;
    }

    /// 定义update,参数sql语句,sql语句中的参数
    public int update(String sql,Object...objects)
    {
        ///定义int类型变量,用于接收增删改后影响的行数
        int result =0;
        try {
            connection=dataSource.getConnection();
            /// 通过连接对象获取执行者对象,并对sql语句进行预编译
            preparedStatement = connection.prepareStatement(sql);

            /// 执行者对象获取源信息的对象
            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int count = parameterMetaData.getParameterCount();

            /// 判断参数数量是否一致
            if(count!=objects.length)
            {
                throw new RuntimeException("参数个数不匹配");
            }

            /// 为sql语句占位符赋值
            for (int i=0;i<objects.length;i++)
            {
                preparedStatement.setObject(i+1,objects[i]);
            }

            ///执行sql语句
            result=preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            DataSourceUtils.close(connection,preparedStatement);
        }

        return result;
    }


}

测试代码

package com.itheima05;

import com.itheima.utils.DataSourceUtils;
import com.itheima05.domain.Student;
import com.itheima05.handler.BeanHandler;
import com.itheima05.handler.BeanListHandler;
import com.itheima05.handler.ScalarHandler;
import org.junit.Test;

import java.util.List;

/*
    模拟dao层
 */
public class JDBCTemplate1 {

    private JDBCTemplate template = new JDBCTemplate(DataSourceUtils.getDataSource());

    @Test
    public void queryForScalar()
    {
        String sql = "select count(*) from student";
       Long aLong =template.queryForScalar(sql,new ScalarHandler<>());
        System.out.println(aLong);

    }
    @Test
    public void queryForList()
    {
        String sql = "select * from student";
        List<Student> list =template.queryForList(sql,new BeanListHandler<>(Student.class));
        for (Student student:list)
        {
            System.out.println(student);
        }

    }

    @Test
    public void queryForObject()
    {
        String sql = "select * from student where sid =?";
        Student student=template.queryForObject(sql,new BeanHandler<>(Student.class),1);
        System.out.println(student);

    }

    @Test
    public void delete()
    {
        /// 输出数据的测试
        String sql = "delete from student where name=?";
        int result = template.update(sql,"周七");
    }

    @Test
    public void update()
    {
        /// 修改数据的测试
        String sql = "update student set age=? where name=?";
        Object[] objects ={34,"周七"};
        int result = template.update(sql,objects);
        System.out.println(result);

    }


    @Test
    public void insert()
    {
        String sql ="insert into student values(?,?,?,?)";
        Object[] objects = {5,"周七",27,"1997-07-07"};
        int update = template.update(sql, objects);
        if(update!=0)
        {
            System.out.println("添加成功");
        }
        else
        {
            System.out.println("添加失败");
        }
    }
}
注意,此版本不包含源代码,只是一个绿色的可以随时打开的版本,开发工具为:delphi7+sqlserver2000我的PDF(Perfect Developer Frame),想要 简单,快速,健壮,因此我用的还是C/S结构,因为客户可不管你用的是什么最高新的技术!经过一两年的完善,以及几个小的项目的使用,基本上还能拿得出客户正式使用!现在拿出来征求大伙的意见,看看在哪方面还要做改进,以达到更好...如果您的意见很好,被我们实现在PDF上,那么您就可以得到一份PDF 插件版的源代码.诚心希望与您的交流:EMAIL:kingjit@163.comMSN:kingjit@163.comQQ:112876992=================================================本系统使用了绿色SQLSERVER 4.0,只供下载学习,版权归微软公司所有请下载后24小时内删除系统使用方法(纯绿色版本):1.下载并解压2.打开目录下的SERVERadmin.exe,并确保数据库已经启动3.打开CLIENTXiandi.exe即可使用,密码为空这个版本是没有完成的版本,但材料的进销存还是可以用的,请帮助测试==============================2005-10-12 jacky 第一次做开发记录以前所有的都没有做开发记录,所以很多功能都写了而无法查证,所以希望以后能坚持写下去,保留一份最完整的开发记录供后人查阅.*BUG:在单据审核后使用反审核及新增单据都会报已被审核不能修改.*NEW:单据在审核或反审核,结单或反结单时都会被记录在UserLog记录中.*NEW:新增公共部分的部门和人员表,以便在其他的功能中使用.*NEW:如果在编辑状态在GRID中移动,并且定义了Button的OnClick事件,则会自动触发 但要注意,只能在Col中增加Button并写事件或者在Col的OnButtonClick中写事件才行,在Grid的onButtonClick事件中写代码,则不会触发,要注意2005-10-14 jacky*NEW:把系统改为简繁自动切换界面的软件,界面用SILANG处理,报表用RMLOCAL.LOADDLL处理,UNIT里面用CS函数转换字符串*NEW:新增一个工具,LangTrans,来自动转换SIL语言文件,默认第一个语言是简体,第二个语言是繁体的转换2005-10-15 jacky*NEW:新增单据,会自动根据BILLTYPE及TABLE等自动生成BILLNO的生成格式信息,前缀默认为B开头*BUG:通用查询,过滤,报表窗口的DFM文件都有错误,不是OBJECT开头而是inherted*NEW:LangTrans完成*BUG:TFrmSysLog中,给尚未登出人员设置颜色时,没有检测FIELD是否存在,所以出错*NEW:在模版中创建FORM时就查询Dataset中是否有被LOOKUP的字段,如果有,则其FIELD的默认值填0,函数放在FUNCTION中*BUG:在审核时,会跳到编辑界面*NEW:把单据的录入窗口中,子表的录入新增按钮等放到GRID的右边*NEW:主界面的状态栏改为9号字,看起来好看多了*NEW:单据中的字段现在也可以是常用的固定FIELDNAME自动转换成常用的中文标签*BUG:BILL模版中,结单的状态文字,错误的打成审核了*BUG:系统经常出现错误,及不稳定现象,应该是内存泄露,正在查...2005-10-16 jacky*BUG:内存泄露的问题,稍稍解决了一些,是否经得住考验还得测试*BUG:我觉得主从表好象有问题,查询从表的时候,总是不带条件的,这样从表记录多了,该如何是好啊!所以想改一下其打开的方式*NEW:OK搞定主从表重新的方式取得数据,从表不会出现没有条件的select * from detail table*NEW:以前是在DATASET的FIELD中设置只读,则表格标题为红色,必须有值,则标题显示蓝色,现在如果GRID的COLUMN也是只读,则也显示红色.*NEW:上面说的功能,把它写在了一个函数中,SetGridTitleColor,而且只在Dataset的AfterOpen中执行一次,这样程式的性能应该会有提高.2005-10-16 jacky*BUG:主窗口的状态栏上显示文字的格子不够宽,加宽一些2005-10-18 jacky*TODO:在主窗口的功能列上,在功能项上按右键,应该有一个加入收藏夹的功能*记忆:在FIELD的DEFAULTEXPRESS中填DATE表示默认当前日期*NEW:把KU中SELECT相关的过程中,设置表格宽度的参数部分,如果为负数,则不改变默认宽度*NEW:在功能项目上按右键,即有菜单把项目加入到收藏夹中*NEW:AccountManager已经被改成双语版的了2005-10-23 jacky*TODO:新增一张单据的具体操作步骤如下: 1.从uBaseBill模版中继承建立一个FORM 2.建立好主从表,并且主从表的关键字都是固定名称:BillNO 3.把类名称改名,并保存单元,然后从自动建立列表中移除 4.在REGUNIT中注册此类 5.在MenuMoudle中建立一个菜单项,其中HINT要写上刚刚注册的类名称即可 6.ADSMain中commandtext,在FROM 后面加上主表名称 7.ADSDETAIL的commandtext中一般只要写上"select * from 子表名称",即可 8.调整各dataset中字段显示的名称,及表格中的位置等等,后面做的工作就可以很灵活了,如添加LOOKUP字段及做统计等等工作了2005-10-25 jacky*NEW:旧的万能过滤感觉不太好使,所以换成了EHLIB自带的万能过滤,不知道好不好用*BUG:没有登录的情况下是不可以点收藏夹右键的*BUG:没有登录的情况下是不可以点修改密码的2005-10-26 jacky*BUG:修改导航功能,让其能正常显示与隐藏,边界大小等,哈完美解决*NEW:导航显示时,让主界面也不出现灰色标题栏*WHY:系统参数设置FORM上没有光标出现,这种现象在其他FORM上好象偶尔也会出现==好象是解决了*NEW:在FrmMain中增加处理子窗口打开的消息,完全解决只要有子FORM打开,则功能列消失的功能*NEW:在系统管理中设置系统更新路径后,就可以在程序起动期间或是手动点工具栏按钮更新程序2005-10-29 jacky*NEW:如果进入GRID后,有写代码,按右键弹出,是不是会好一些呢?*NEW:在界面上按回车跳转的功能,遇到TDBMEMO等就不应该再跳了*NEW:在SELECT_FORM中,搜索栏位选择中,不再出现隐藏的字段了*NEW:SELECT_FORM中的MEMO字段要显示出文字*TODO:如果有把DataSet中的字段拉出来,变成文本框的录入,可以在其OnEnter和OnExit事件中选择PubEnter和PubExit事件,以达到进入编辑时,改变颜色,以醒目*NEW:如果是模版建立的窗口,则自动建立OnEnter和OnExit事件,以改变控件颜色*NEW:KU.GetParam函数有了重载的版本,即是可以有预设值的,而且也不会因为没有这个参数而出错*OK:先迪的材料进销存部分,已经完成库存数量之间的触发关系,所有单据在审核后数量才会改变2005-10-30 jacky
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值