上一篇我们写完了数据库连接的封装

没有看的请移步上一篇关于数据库连接的内容

这次我们讲数据库操作的封装。数据库的操作就是增删改查;心再大一点就可以直接分为查询和其他。

因为查询是有返回对象的,而其他都不用返回值(事实是可以返回执行该语句所影响数据表中的行数,但是用处不大,仅做判断用)

话不多说,看代码,代码比较长,但是我大概写了一些注释,有理解不到位的地方还请指正

package com.yck.database;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DataUtil
{

    /**
     * 以List的形式返回多条查询语句的结果
     * @param clazz
     * @param sql
     * @param objects
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static <T> List<T> selectForBeanList(Class clazz,String sql,Object...objects)
    {
        List<T> list = new ArrayList<T>();
        List<Map<String,Object>> mapList = queryForMapList(sql,objects);
        for(Map<String,Object> map:mapList )
        {
            list.add(queryForBean(map, clazz));
        }
        return list;
    }

    /**
     * 以javabean 对象的形式返回从数据空中查找出来的单条数据
     * @param clazz
     * @param sql
     * @param objects
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static <T>T selectForBean(Class clazz,String sql,Object...objects)
    {
        Map<String,Object> map = queryForMap(sql,objects);

        return queryForBean(map,clazz);
    }

    /**
     * 除了查询外,都用这个
     * @param updateSQL
     * @param objects
     * @return
     */
    public static int updata(String updateSQL,Object...objects)
    {
        Connection conn = DButil.getConnection();   //建立与数据库的连接
        PreparedStatement pStam = null;
        int result = 10;
        try
        {
            pStam = DButil.prepareStatement(conn, updateSQL);
            for(int i=0;i<objects.length;i++) //对sql语句的通配符?进行填充
            {
                pStam.setObject(i+1, objects[i]);
            }
            result = pStam.executeUpdate(); //得到update结果
        } catch (SQLException e)
        {
            e.printStackTrace();
        }finally
        {
            DButil.closePreparedStatement(pStam);
            DButil.closeConnection(conn);
        }
        return result;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static <T>T queryForBean(Map<String,Object> map,  Class clazz)
    {
        T obj = null;
        Field field = null;
        try
        {
            obj = (T) clazz.newInstance();     //实例化一个clazz对象
        } catch (InstantiationException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(map == null)
            return null;
        for(String columnName:map.keySet())       //遍历map的key
        {
            Method method = null;
            String propertyName = StringUtil.columnToProperty(columnName); //将存在map中的key值转化成bean中的属性字段,驼峰命名

            try
            {
                field = clazz.getDeclaredField(propertyName);      //在类clazz中匹配相应的字段信息
            } catch (NoSuchFieldException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            String fieldType = field.toString().split(" ")[1];   //将字段信息以空格分割,第二条为字段类型(0 是第一条,一般为private)
            Object value = map.get(columnName);                  //得到相应的值
            if(value == null)
            {
                continue;
            }
            String setMethodName ="set"+StringUtil.upperCaseFirstCharacter(propertyName); //拼接set方法
            String valueType = value.getClass().getName();  

            if(!fieldType.equalsIgnoreCase(valueType))   //根据类型转换value值
            {
                if(fieldType.equalsIgnoreCase("java.lang.Integer"))
                {
                    value =Integer.parseInt(String.valueOf(value));
                }
                else if(fieldType.equalsIgnoreCase("java.lang.String"))
                {
                    value = String.valueOf(value);
                }
                else if(fieldType.equalsIgnoreCase("java.util.Date"))
                {
                    valueType = "java.lang.Date";
                    String datestr = String.valueOf(value);
                    Timestamp ts = Timestamp.valueOf(datestr);
                    Date date = new Date(ts.getTime());
                    value = date;
                }
            }
            try
            {
                method = clazz.getDeclaredMethod(setMethodName, Class.forName(fieldType));
                method.invoke(obj, value);
            } catch (NoSuchMethodException e)
            {
                e.printStackTrace();
            } catch (SecurityException e)
            {
                e.printStackTrace();
            } catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (IllegalArgumentException e)
            {
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                e.printStackTrace();
            }

        }
        return obj;
    }
    /**
     * 需要返回单个对象信息时,我们用Map存储,如果查询到不止一个对象或者没有查询到对象,返回null;
     * @param sql
     * @param objects
     * @return
     */
    private static Map<String,Object> queryForMap(String sql,Object...objects)
    {

        //新建一个Map,存放结果。key存放从数据库中取出的column名称,value存放相应column取出来的值(用rs.getObject(columnname)方法取出)
        //
        Map<String,Object> result = new HashMap<String,Object>();
        Connection conn = DButil.getConnection();   //建立与数据库的连接
        PreparedStatement pStam = null;
        ResultSet rs = null;
        try
        {
            pStam = DButil.prepareStatement(conn, sql);
            for(int i=0;i<objects.length;i++) //对sql语句里的 ?进行填充
            {
                pStam.setObject(i+1, objects[i]);
            }
            rs = pStam.executeQuery(); //拿到查询结果

            if(rs.next())
            {

                ResultSetMetaData rsmd = rs.getMetaData();  //拿到查询结果的字段
                int count = rsmd.getColumnCount();          //字段数量
                for(int i=0;i<count;i++)
                {
                    result.put(rsmd.getColumnName(i+1), rs.getObject(rsmd.getColumnName(i+1)));
                }
                if(rs.next())
                    result = null;

            }
        } catch (SQLException e)
        {
            e.printStackTrace();
        }finally
        {
            DButil.closeResultSet(rs);
            DButil.closePreparedStatement(pStam);
            DButil.closeConnection(conn);
        }
        return result;
    }

    /**
     * 要返回多个对象时,我们把查询出来的单个对象的信息全部放在一个Map中,然后把这些单个对象的信息全放到
     * List中返回
     * @param sql
     * @param objects
     * @return
     */
    private static List<Map<String,Object>> queryForMapList(String sql,Object...objects)
    {
        List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();  //建立一个存放结果的List
        Connection conn = DButil.getConnection();   //建立与数据库的连接
        PreparedStatement pStam = null;
        ResultSet rs = null;
        try
        {
            pStam = DButil.prepareStatement(conn, sql);
            for(int i=0;i<objects.length;i++) //对sql语句里的 ?进行填充
            {
                pStam.setObject(i+1, objects[i]);
            }
            rs = pStam.executeQuery(); //拿到查询结果
            while(rs.next())
            {
                ResultSetMetaData rsmd = rs.getMetaData();  //拿到查询结果的字段
                int count = rsmd.getColumnCount();          //字段数量
                Map<String,Object> map = new HashMap<String,Object>();  //一个存放数据的map,key=字段名称,value=字段的内容
                for(int i=0;i<count;i++)
                {
                    map.put(rsmd.getColumnName(i+1), rs.getObject(rsmd.getColumnName(i+1)));
                }
                result.add(map);//将存放一条数据的map放进List
            }

        } catch (SQLException e)
        {
            e.printStackTrace();
        }finally
        {
            DButil.closeResultSet(rs);
            DButil.closePreparedStatement(pStam);
            DButil.closeConnection(conn);
        }
        return result;
    }

}

在Test类中做如下测试

package com.yck.test;

import java.util.List;

import com.yck.bean.User;
import com.yck.database.DataUtil;

public class Test
{

    public static void main(String[] args)
    {
        String sql1 = "select * from t_user where name = ?";
        User user = DataUtil.selectForBean(User.class, sql1, "张三");
        System.out.println(user);
        String sql2 = "select * from t_user";
        List<User> list1 = DataUtil.selectForBeanList(User.class, sql2);
        System.out.println("第一次查询的结果:"+list1);

        String sql3 = "insert into t_user values (null,?,?)";
        DataUtil.updata(sql3, "王老五",90);
        List<User> list2 = DataUtil.selectForBeanList(User.class, sql2);
        System.out.println("增加王老五之后:"+list2);

        String sql4 = "update t_user set age=? where name =?";
        DataUtil.updata(sql4, 200,"张三");
        List<User> list3 = DataUtil.selectForBeanList(User.class, sql2);
        System.out.println("把张三的年龄改掉之后:"+list3);

    }

}

结果如下所示

数据库结果

忘了贴上上面用到的StringUtil的方法。

package com.yck.database;

import java.util.UUID;

public class StringUtil
{

    public static String columnToProperty(String column)
    {
        //判断column是否为空
        if(column.equals(null)||column.equals(""))
            return "";

        Byte length = (byte) column.length();        //获取字段的长度
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++)              //遍历字符
        {
            if (column.charAt(i) == '_')              //判断字符是否为下划线  _
            {
                while (column.charAt(i + 1) == '_')   //如果是并且下一个还是是下划线,自增一个单位
                {
                    i++;
                }
                sb.append(("" + column.charAt(++i)).toUpperCase());  //如果是并且下一个不是下划线,下一个字母变为大写

            }
            else
            {

                    sb.append(column.charAt(i));            //如果不是下划线,直接保存
            }
        }

         return sb.toString();
     }

    /**
     * 把首字母大写
     * @param str
     * @return
     */
    public static String upperCaseFirstCharacter(String str)
    {
        StringBuilder strBuilder = new StringBuilder();
        char[] arr = str.toCharArray();
        for(int i=0;i<arr.length;i++)
        {
            if(i==0)
                strBuilder.append((arr[i]+"").toUpperCase());
            else strBuilder.append(arr[i]+"");
        }
        return strBuilder.toString();
    }

    /**
     * 生成32位uuid
     * @return
     */
    public static String createUniqueid()
    {
        UUID uniqueid = UUID.randomUUID();
        String str = uniqueid.toString();
        String uuidStr=str.replace("-", "");
        return uuidStr;

    }

}

手把手封装数据层之DataUtil数据库操作的封装的更多相关文章

  1. PHP中对数据库操作的封装

    在动态网面设计中很多都要涉及到对数据库的操作,但是有时跟据需要而改用其它后台数据库,就需要大量修改程序.这是一件枯燥.费时而且容易出错的功作.其实我们可以用PHP中的类来实现对数据库操作的封装,从而使 ...

  2. C# .NET更智能的数据库操作的封装完整版(重构)

    前述: 第一次发表文章,不过是对数据库简单的封装,主要是阐述下思路.那么在上篇文章,在大家的指导下和提出意见,并自己对代码进行了思考.在这两天我重构了新的框架,我觉得我写的可以称得上框架,为什么?请大 ...

  3. C# .NET更智能的数据库操作的封装

    前述: 对数据库操作的封装,相信网络上已经有一大堆,ORM框架,或者是.NET本身的EF,都很好的支持数据库操作.这篇文章是分享自己所思考的,对数据库操作的简单封装.我对于这篇文章,认为被浏览者所关注 ...

  4. 05:ModelForm 数据验证 & 生成html & 数据库操作

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  5. 手把手封装数据层之DButil数据库连接的封装

    最近这段时间一直在用SSM框架做增删改查,突然想把以前还不会用框架的时候,综合百度和各种资料结合API文档抄袭而来的数据层的封装分享给大家.这边先封装一个DButil. 我这个封装就是烂大街的那种,没 ...

  6. android菜鸟学习笔记20----Android数据存储(四))Android数据库操作

    Android内置了一个名为SQLite的关系型数据库,这是一款轻量型的数据库,操作十分简便.SQLite与别的数据库不同的是,它没有数据类型.可以保存任何类型的数据到你所想要保存的任何表的任何列中. ...

  7. django的模型类管理器-----------数据库操作的封装

    模型实例方法 str():在将对象转换成字符串时会被调用. save():将模型对象保存到数据表中,ORM框架会转换成对应的insert或update语句. delete():将模型对象从数据表中删除 ...

  8. Android数据读取之Sqlite数据库操作

    咱们书接上文,继续来说说Android数据读取,这回,我们要讲的是Sqlite数据库的相关操作.以一个实例开始吧: 首先,上图,看看做成后的效果: 大概描述:类似于浏览器的收藏夹,网站名称,网站地址, ...

  9. 常用的PHP函数封装,有排序和数据库操作函数

    //二分查找 function bin_sch($array, $low, $high, $k) { if ($low <= $high) { $mid = intval(($low + $hi ...

随机推荐

  1. WPF转换器之通用转换器

    WPF中的转换器是一个非常好的数据类型转换解决方案,实用和强大, 它的作用是将源数据转换为WPF自身需要的类型,对数据实体没有侵略性,会在项目工程中频繁使用.所以掌握转换器是WPF开发的必备技能. 我 ...

  2. (转)java反射机制及简单工厂模式

    第一步,定义一个接口类 package factory.face; /** * 接口,为了保证返回的对象可以统一用 Product接受 * @author Administrator */ publi ...

  3. HTML5 开发APP(MUI的一些特性)

    先附mui文档地址:http://dev.dcloud.net.cn/mui/ui/  .mui的UI组件比较简单而且在文档中很好找就不过多说了. 1 在app开发中,使用HTML5+的api,必须m ...

  4. 让初学者快速了解Git

    Git工作原理 为了更好的学习Git,我们们必须了解Git管理我们文件的3种状态,分别是已提交(committed).已修改(modified)和已暂存(staged),由此引入 Git 项目的三个工 ...

  5. python中全局变量和局部变量的一个小坑

    python 中全局变量和局部变量在使用过程中的一个容易出错的地方 什么是全局变量 python中,在函数外部声明的变量可以叫做全局变量. x = 10 def fn1(): pass fn1() 什 ...

  6. Jetty的工作原理

    Jetty的工作原理 Jetty 的基本架构 Jetty 目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器,它有一个基本数据模型,这个数据模型就 ...

  7. ps-ef|grep-vgrep|grepsep|awk'{print"kill-9"$2}'|sh 这个表达式到底是什么意思啊?

    最佳答案   kill 掉sep这个程序ps -ef | 获取当前服务器所有进程grep -v grep 相当于grep自己吧自己过滤掉,就是不显示grepgrep seq 过滤出seqawk 截取 ...

  8. Hadoop新生报到(一) hadoop2.6.0伪分布式配置详解

    首先先不看理论,搭建起环境之后再看: 搭建伪分布式是为了模拟环境,调试方便. 电脑是win10,用的虚拟机VMware Workstation 12 Pro,跑的Linux系统是centos6.5 , ...

  9. Selenium+Java显示等待和隐式等待

    描述:用来操作界面上的等待时间,显示等待是等待某一条件满足,条件满足后进行后面的操作:隐式等待是给出一个等待时间,在时间到达之前若满足条件,则立即执行后续操作. public class TestSe ...

  10. 神经网络中的BP神经网络和贝叶斯

    1 贝叶斯网络在地学中的应用 1 1.1基本原理及发展过程 1 1.2 具体的研究与应用 4 2 BP神经网络在地学中的应用 6 2.1BP神经网络简介 6 2.2基本原理 7 2.3 在地学中的具体 ...