首页 > 代码库 > BeanUtils工具

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 =http://www.mamicode.com/ 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 =http://www.mamicode.com/ 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 =http://www.mamicode.com/ 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();        }            }    

这就完成了~

优缺点

优点:比较通用

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

 

 

 

 

BeanUtils工具