BeanUtils工具

什麼是BeanUtils工具

BeanUtils工具是一種方便咱們對JavaBean進行操做的工具,是Apache組織下的產品。java

 

BeanUtils工具通常能夠方便javaBean的哪些操做?

1)beanUtils 能夠便於對javaBean的屬性進行賦值。sql

2)beanUtils 能夠便於對javaBean的對象進行賦值。數據庫

3)beanUtils能夠將一個MAP集合的數據拷貝到一個javabean對象中。數組

 

BeanUtils的使用

使用beanUtils按照如下步驟~工具

 

前提:約定前提: 參數名稱 須要和javabean的屬性名稱保持一致!!!!spa

 

步驟一code

導包:導入commons-beanutils-1.8.3 對象

與 commons-logging-1.1.3 blog

 

步驟二資源

寫代碼使用~下面就來演示下常見的用法

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();
        }
        
    }
    

這就完成了~

優缺點

優勢:比較通用

缺點:就是每次調用這兩個方法都要在內部生產一個鏈接池,這樣一個鏈接池來完成一條語句是十分浪費的,因此這一點能夠改進~改進方法也比較簡單~這裏就不演示了~

相關文章
相關標籤/搜索