• BeanUtils工具


    什么是BeanUtils工具

    BeanUtils工具是一种方便我们对JavaBean进行操作的工具,是Apache组织下的产品。

     

    BeanUtils工具一般可以方便javaBean的哪些操作?

    1)beanUtils 可以便于对javaBean的属性进行赋值。

    2)beanUtils 可以便于对javaBean的对象进行赋值。

    3)beanUtils可以将一个MAP集合的数据拷贝到一个javabean对象中。

     

    BeanUtils的使用

    使用beanUtils按照以下步骤~

     

    前提:约定前提: 参数名称 需要和javabean的属性名称保持一致!!!!

     

    步骤一

    导包:导入commons-beanutils-1.8.3 

    与 commons-logging-1.1.3 

     

    步骤二

    写代码使用~下面就来演示下常见的用法

    1)设置javaBean的参数

        @Test
        public void test1() throws Exception
        {
            //先演示一下不用工具时的做法
            //1.生成对象
            Student s = new Student();
            
            /*2.通过set方法赋值
            s.setId(1);
            s.setName("VN");
            s.setAge(19);
            s.setClassID(5);
            s.setBirthday(new Date());
            用以上这种方法来给对象的属性赋值实在是太麻烦了,下面我们用BeanUtils来进行赋值
            */
            
            //1.得到javaBean的一个字节码对象
            Class clazz = Class.forName("com.vmaxtam.beanutiltest.Student");
            
            //2.生成该字节码的一个对象
            Object obj = clazz.newInstance();
            
            //4.注册一个日期格式转换器
            ConvertUtils.register(new DateLocaleConverter(), java.util.Date.class);
            
            //3.使用工具对该对象进行赋值
            //注意: 对于基本数据类型,beanutils工具进行自动类型转换。把String自动转成Integer,Double,Float
            BeanUtils.setProperty(obj, "id", "1");
            BeanUtils.setProperty(obj, "name", "VN");
            BeanUtils.setProperty(obj, "age", "19");
            BeanUtils.setProperty(obj, "classID", "5");
            //如果要使用特殊的日期类型,则String->Date 不能自动转换,这时候就要注册一个转换器
            BeanUtils.setProperty(obj, "birthday", "1996-06-06");
            
            System.out.println(obj);        
        }

    对比一下,我们发现,使用BeanUtils里赋值好像更麻烦。。。但这只是在这段代码中而已,运用BeanUtils上面代码的这个功能,

    我们可以写出一个通用的方法,可以把请求中的参数拷贝到javaBean对象中!

     

    约定前提: 请求中的参数名称 需要和javabean的属性名称保持一致!!!!
    public static <T>T requestToBean(HttpServletRequest request , Class<T> clazz)
        {
            //创建javaBean对象    
            Object obj=null;
            try {
                obj=clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            
            //得到请求中的每个参数
            Enumeration<String> enu = request.getParameterNames();
            while(enu.hasMoreElements())
            {
                //获得参数名
                String name = enu.nextElement();
                //获得参数值
                String value = request.getParameter(name);
                //然后把参数拷贝到javaBean对象中
                try {
                    BeanUtils.setProperty(obj, name, value);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
            return (T)obj;
        }

     

    上面这个方法是一个泛型方法,传不同的javaBean进去都可以从request中获取参数值。在一个工程较大的项目中,如果使用这个通用的方法,就能节省很多代码。

    2)把一个javaBean的属性拷贝到另一个javaBean对象中

    @Test
        public void test2() throws Exception
        {
            //1.生成对象
            Student s1 = new Student();
            Student s2 = new Student();
            
            //2.通过set方法赋值
            s1.setId(1);
            s1.setName("VN");
            //s1.setAge(19);//基本数据类型可以为null,null也能拷贝
            s1.setClassID(5);
            s1.setBirthday(new Date());//特殊类型不能为null
    
            //需求:把s1的属性值拷贝到S2中,注意参数的顺序
            BeanUtils.copyProperties(s2, s1);
            
            System.out.println(s1);
            System.out.println(s2);    
        }

    一句代码就完成拷贝了,不用像以前那样先用get()方法把s1的属性值拿出来,再用set()方法供给s2属性赋值

    3)把一个map集合中的数据拷贝到javaBean

    @Test
        public void test3() throws Exception
        {
            //1.生成对象
            Map<String,Object> map = new HashMap<String,Object>();
        
            //2.给一些参数
            map.put("id", 2);
            map.put("name", "EZ");
            map.put("age", 22);
            map.put("classID", 3);
            map.put("birthday", new Date());
            
            //需求:把map的属性值拷贝到S中
            Student s = new Student();
            BeanUtils.copyProperties(s, map);
            
            System.out.println(s);
        }

    上面这个也是一步到位,也是使用copyProperties()这个方法来完成,这样减少了我们很多的操作了,十分简便。

     

     

    下面介绍一个新的概念,学会这个东西后,它能够和beanUtils组合写出更多的通用代码!方便我们的项目!

    元数据(MetaData

    什么是数据库的元数据

    数据库中的元数据有三种:

     

    1)数据库元数据(DatabaseMetaData):可以从connection对象中获取。

    这些元数据的信息包括:当前使用什么数据库,数据库的版本,数据库驱动的版本

     

    2)参数元数据(ParameterMetaData):可以从PreparedStatement中获取,指sql语句中的参数

    元数据的信息:参数的个数,以及每个参数的类型

     

    3)结果集元数据(ResultSetMetaData):可以从ResultSet对象中获取

    元数据信息:结果集的列数,以及每列的名称

     

    下面就来显示下怎么获取这些信息吧~

    获取数据库的元数据

        @Test
        public void Test1()
        {
            //获取连接池
            ComboPooledDataSource pool = new ComboPooledDataSource();
            try {
                //获取连接
                Connection conn = pool.getConnection();
                //获取数据库元数据
                DatabaseMetaData md =     conn.getMetaData();
                
                //获得数据库的主版本和副版本
                int mj = md.getDatabaseMajorVersion();
                int mi =md.getDatabaseMinorVersion();
                System.out.println(mj + "."+ mi);
                
                //获得驱动版本
                int dmj = md.getDriverMajorVersion();
                int dmi = md.getDriverMinorVersion();
                System.out.println(dmj + "."+dmi);
                
                //当前使用什么数据库
                String b =md.getDatabaseProductName();
                System.out.println(b);
                                
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }    
        }

    这个和beanutils没什么关系,所以不是重点。

    获取参数元数据

        PreparedStatement sta=null;
        Connection conn=null;
        @Test
        public void Test2()
        {
            //获取连接池
            ComboPooledDataSource pool = new ComboPooledDataSource();
            try {
                //获取连接
                 conn = pool.getConnection();
                //准备SQL语句
                String sql ="insert into student(sid,sname) values(?,?)";
                //获得Statement
                 sta = conn.prepareStatement(sql);
                
                //获取元数据
                ParameterMetaData md = sta.getParameterMetaData();
                //获取参数的一些信息:参数的个数
                int count = md.getParameterCount();
                //然后利用这个数来给参数赋值
                //方便参数赋值
                Object value[] = new Object[]{17,"VN"};
                for(int i = 0;i<count ;i++)
                {
                    sta.setObject(i+1, value[i]);
                }
                //执行
                sta.executeUpdate();
                
                //有可能具体数据库厂商不支持下面方法
                //System.out.println("第一个参数的类型:"+md.getParameterTypeName(1));
                            
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                //关闭资源
                if(sta!=null){
                    try {
                        sta.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }if(conn!=null)
                    {
                        try {
                            conn.close();
                        } catch (SQLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

    以上就是使用元数据来对预编译的SQL语句来进行方便的参数赋值的方法~当参数比较多的时候,我们就不必一个一个地自己赋值,可以利用循环来给它赋值。

     

    获取结果集的元数据

    我们先发送一个查询语句获得一个结果集,然后可以利用元数据来很方便地封装结果集返回的结果~

        @Test
        public void Test3()
        {
    
            try {
                //获取连接池
                ComboPooledDataSource pool = new ComboPooledDataSource();
                //获取连接
                conn = pool.getConnection();
                //准备SQL语句
                String sql="select * from student";
                //获得statement对象
                sta = conn.prepareStatement(sql);
                
                //执行,返回结果集
                ResultSet res = sta.executeQuery();
                //获取结果集的元素据
                ResultSetMetaData rd = res.getMetaData();
                
                //利用元数据来封装对象
                List<Students> list = new ArrayList<Students>();
                //获得结果集的列数
                int colcount = rd.getColumnCount();
                //循环结果集来封装对象
                while(res.next())
                {
                    Students s = new Students();
                    for(int i = 1; i <= colcount ; i++)
                    {
                        
                        //得到列名
                        String colname = rd.getColumnName(i);
                        //得到列值
                        Object value = res.getObject(colname);
                        //利用BeanUtils,放入对象中
                        BeanUtils.setProperty(s, colname, value);
                    }
                    //把封装好的对象放入集合
                    list.add(s);
                }
                //然后可以对List其他操作~        
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            //关闭资源
        }

    这就是利用元数据和BeanUtil结合方便我们封装结果集数据的一个例子了~利用这个特点,我们可以写出更多的通用的方法。

    利用元数据和BeanUtil 编写通用的 更新方法 和 查询方法

    以下就是一个通用的查询方法

    参数说明:

        sql:要预编译的查询语句

        values:把sql语句的参数放到这个数组中

        clazz:最后集合中返回的javaBean的类型

        public static <T> List<T> query(String sql,Object[] values,Class<T> clazz)
        {
            Connection conn = null;
            PreparedStatement sta = null;
            ResultSet res = null;
            
            try {
                //获取连接池
                ComboPooledDataSource pool = new ComboPooledDataSource();
                //获取连接
                conn = pool.getConnection();
                //获取statement对象,预编译
                sta = conn.prepareStatement(sql);    
                
                //利用参数的元数据给预编译的SQL语句赋值
                ParameterMetaData pmd = sta.getParameterMetaData();
                //获得参数个数
                int pcount = pmd.getParameterCount();
                
                //赋值
                if(values != null)
                {
                    for(int i=1 ;i<=pcount;i++)
                    {
                        sta.setObject(i, values[i-1]);
                    }
                }
                
                //执行
                res = sta.executeQuery();
                
                //获得结果集元数据
                ResultSetMetaData rsmd = res.getMetaData();
                //创建存储对象的集合
                List<T> list = new ArrayList<T>();
                //获取列的数量
                int colcount = rsmd.getColumnCount();
                //封装对象
                while(res.next())
                {
                    //生成要封装的对象的实例
                    Object obj = clazz.newInstance();
                    for(int i=1;i<=colcount;i++)
                    {
                        //获得列名
                        String colname = rsmd.getColumnName(i);
                        //获得列值
                        Object colvalue = res.getObject(i);
                        //封装
                        BeanUtils.setProperty(obj, colname, colvalue);
                    }
                    //把封装好的对象放入集合
                    list.add((T) obj);
                }
                return (List<T>)list;            
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }finally{
                //释放资源
                if(res!=null){
                try {
                    res.close();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                    }}
                if(sta!=null){
                try {
                    sta.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }}
                if(conn!=null){
                try {
                    conn.close();//放回连接池
                } catch (SQLException e) {
                    e.printStackTrace();
                }}
            }    
        }

    以上就是一个通用的查询方法啦~下面来看一个通用的更新方法,比上面的简单~

    通用的更新方法

        public static void update(String sql,Object[] values)
        {
            Connection conn =null;
            PreparedStatement sta = null;
    
            try {
                
                //获取连接池
                ComboPooledDataSource pool = new ComboPooledDataSource();
                //获取连接
                conn = pool.getConnection();
                //预编译
                sta= conn.prepareStatement(sql);
                
                //获取参数的元数据
                ParameterMetaData pmt = sta.getParameterMetaData();
                
                //获取参数的个数
                int pcount = pmt.getParameterCount();
                //参数赋值
                for(int i = 1; i<=pcount;i++)
                {
                    sta.setObject(i, values[i-1]);
                }
                
                //执行更新
                sta.executeUpdate();
                
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        

    这就完成了~

    优缺点

    优点:比较通用

    缺点:就是每次调用这两个方法都要在内部生产一个连接池,这样一个连接池来完成一条语句是十分浪费的,所以这一点可以改进~改进方法也比较简单~这里就不演示了~

     

  • 相关阅读:
    java中date日期格式的各种转换
    idea配置网络代理
    idea连接操作数据库
    数据库mysql之慢查询优化
    【统一异常处理】@ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常
    freemarker【FTL】常见语法大全
    MySQL高级知识(七)——索引面试题分析
    MySQL高级知识(八)——ORDER BY优化
    MySQL高级知识(六)——索引优化
    MySQL高级知识(四)——Explain
  • 原文地址:https://www.cnblogs.com/vmax-tam/p/4159985.html
Copyright © 2020-2023  润新知