1. 程式人生 > >幾種封裝javaBean的方法

幾種封裝javaBean的方法

開發框架時,經常需要使用java物件(javaBean)的屬性來封裝程式的資料,封裝javaBean的方法有很多,比如反射,內省,以及使用工具類。下面從反射開始介紹。

1.javaBean介紹:

  1. 簡介:
    JavaBean是使用Java語言開發的一個可重用的元件,在開發中可以使用JavaBean減少重複程式碼,使整個程式碼的開發更簡潔。
  2. 編寫要求:
    javaBean本身是一個類,設計該類的時候要遵循一下方法:

    1.如果成員變數的名字是xxx,則相應地有兩個用來得到成員變數值和設定變數值的方法,它們分別是getXxx()和setXxx()且是public的:
     public
    datatype getXxx(); public void setXxx(datatype data); (2)如果成員變數是boolean型資料,使用is代替get方法;: public boolean isXxx(); (3)需要一個無引數的建構函式。
  3. 一個javaBean的例子:

//javaBean
public class Person {
        private int id;
    private String name;
    public Person(int id, String name) {
        super();
        this
.id = id; this.name = name; } //無引數建構函式 public Person(){} //獲得Id屬性 public int getId() { return id; } //設定 public void setId(int id) { this.id = id; } //get方法 public String getName() { return name; } public void setName(String name) { this
.name = name; } //tostring不在要求之中; @Override public String toString() { return "id:"+ this.id+" name:"+ this.name; } }

2.使用反射封裝JavaBean:

通過反射更改物件域來封裝JavaBean,通過getDeclaredField方法獲得對應的域,並呼叫set方法進行修改。
下面的方法通過配置檔案更改JavaBean的屬性:

配置檔案內容如下:obj.txt
com.rlovep.bean.Person
id=22
name=peace
程式碼與註釋:
public class CofigRef {
    public static void main(String[] args) {
        try {
            //獲得更改後的物件;
            Person p=(Person)getInstance();
            System.out.println(p);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //根據配置檔案的內容生產物件的物件並且要把物件的屬性值封裝到物件中。
        public static Object getInstance() throws Exception{
            //通過字元流進行輸入;
            BufferedReader bufferedReader = new BufferedReader(new FileReader("obj.txt"));
            String className =  bufferedReader.readLine(); //讀取配置檔案獲取到完整的類名。
            Class clazz = Class.forName(className);
            //通過class物件獲取到無參的構造方法
            Constructor constructor = clazz.getConstructor(null);
            //建立物件
            Object o  = constructor.newInstance(null);
            //讀取屬性值
            String line = null;
            while((line = bufferedReader.readLine())!=null){
                String[] datas = line.split("=");
                //通過屬性名獲取到對應的Field物件。
                Field field =   clazz.getDeclaredField(datas[0]);
                field.setAccessible(true);
                if(field.getType()==int.class){
                    //更改屬性內容;
                    field.set(o, Integer.parseInt(datas[1]));
                }else{
                    field.set(o, datas[1]);
                }

            }
            bufferedReader.close();
            return o;

        }

此去用反射進行更改,直接更改實現域的值;比較麻煩。需要各種判斷和操作,不適合用於開發。

3.通過內省封裝JavaBean:

內省(Introspector) 是Java 語言對 JavaBean 類屬性、事件的一種預設處理方法。Java JDK中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,這就是內省。
1. PropertyDescriptor類:
屬性描述器類,利用該類可以獲得對應屬性的get和set方法。
getReadMethod(),獲得用於讀取屬性值的方法;getWriteMethod(),獲得用於寫入屬性值的方法;
演示如下:

       //屬性描述器
        PropertyDescriptor descriptor = new PropertyDescriptor("id", Person.class);
        //獲取屬性對應的get或者是set方法設定或者獲取屬性了。
        Method  m = descriptor.getWriteMethod();  //獲取屬性的set方法。
        //執行該方法設定屬性值
        m.invoke(p,110);
         //獲得get方法;
        Method readMethod = descriptor.getReadMethod(); //是獲取屬性的get方法
        System.out.println(readMethod.invoke(p, null));
  1. Introspector類:
    通過呼叫Introspector.getBeanInfo(People.class)方法可以獲得BeanInfo物件,改物件封裝了people類的所有屬性。
    而BeanInfo中有方法 getPropertyDescriptors(),獲得屬性的描述PropertyDescriptor[],可以通過遍歷返回結果可以操作JavaBean。演示如下:
   //Introspector 內省類
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
        //通過BeanInfo獲取所有的屬性描述
        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); //獲取一個類中的所有屬性描述器
        for(PropertyDescriptor p : descriptors){
            //獲得所有get方法
            System.out.println(p.getReadMethod()); //get方法
        }

通過這兩個類的比較可以看出,都是需要獲得PropertyDescriptor,只是方式不一樣:前者通過建立物件直接獲得,後者需要遍歷,所以使用PropertyDescriptor類更加方便。
內省封裝比反射相對來說簡單點,但是實質上是反射的一種變體。

4利用BeanUtils封裝JavaBean

  1. 介紹:
    每次都使用反射技術完成此類操作過於麻煩,所以Apache開發了一套簡單、易用的API來操作Bean的屬性–BeanUtils工具包。
    注意:應用的時候還需要一個logging
    BeanUtils下載地址:連結
    logging下載地址:連結
  2. 使用BeanUtils:
    BeanUtils主要解決 的問題: 把物件的屬性資料封裝 到物件中。
    屬性值從配置檔案中獲取時可能都是String型別, BeanUtils好處是如果屬性是基本資料 型別,BeanUtils會自動幫我轉換資料型別。如果設定的屬性是其他的引用 型別資料,這時候可以註冊一個型別轉換器。
    1.獲得屬性的方法:BeanUtils.getProperty(admin,”userName”);
    2.設定屬性的方法:BeanUtils.setProperty(admin, “id”, 001);
    3.拷貝屬性的方法:BeanUtils.copyProperty(admin, “usetName”, “peace”);與set效果相同。
    4.當屬性不能自動轉換通過ConvertUtils.register(new Converter())註冊轉換器;
  3. 演示如下:
    需要引入包:commons-logging.jar 、 commons-beanutils-1.8.0.jar
    Admin中的屬性:
private int id;
private String userName;
private String pwd;
private int age;
private Date birth;

BeanUtils使用如下:

public class BeanOpr {
    private String name;

    @Test
    /**
     * 
    * @Title: testHello 
    * @Description: beanutiils拷貝的介紹 
    * @return:void   
    * @throws 
    * @author peace [email protected]
     */
    public void testHello(){
        Admin admin=new Admin();
        try {
            //獲得屬性方法:
            System.out.println(BeanUtils.getProperty(admin,"userName"));
            //拷貝屬性
            BeanUtils.copyProperty(admin, "usetName", "peace");
            //類似於設定屬性
            BeanUtils.setProperty(admin, "id", 001);
            //物件的拷貝
            Admin admin2=new Admin();
            BeanUtils.copyProperties(admin2, admin);
            //輸出兩個admin
            System.out.println(admin);
            System.out.println(admin2);
            //map資料,拷貝到物件中
            Map<String, Object> map=new HashMap<>();
            map.put("userName","peace2");
            map.put("age", 22);
            map.put("id", 002);
            map.put("pwd", 123456);
            //通過Map拷貝:
            BeanUtils.populate(admin,map);
            System.out.println(admin);
        } catch (IllegalAccessException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }
    /**
     * 
    * @Title: testRegist 
    * @Description: 實現對不支援的類進行轉換。 
    * @return:void   
    * @throws 
    * @author peace [email protected]
     */
    @Test
      public void testRegist(){

        // 註冊日期型別轉換器:1, 自定義的方式
          ConvertUtils.register(new Converter() {
              /**
               * 轉換函式,實現對date的轉換。
               */
            @Override
            public Object convert(Class type, Object value) {
                 //判斷是否為Date型別
                if(type!=Date.class)
                   return null;
                //判斷是否為空
                if(value==null||"".equals(value.toString().trim()))
                       return null;
            try {
                //轉換方式
                SimpleDateFormat date=new SimpleDateFormat("yyyy-mm-dd");
            return date.parse(value.toString());
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            }
        }, Date.class);
          //執行
          Admin admin=new Admin();
            Map<String, Object> map=new HashMap<>();
            map.put("userName","peace2");
            map.put("age", 22);
            map.put("id", 002);
            map.put("pwd", 123456);
            map.put("birth", new Date(2015, 10, 9));
            try {
                BeanUtils.populate(admin,map);
                System.out.println(admin);
            } catch (IllegalAccessException | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
       }
     @Test
     /**
      * 
     * @Title: testRigest2 
     * @Description: 使用提供的date型別轉換器 
     * @return:void   
     * @throws 
     * @author peace [email protected]
      */
     public void testRigest2(){
         ConvertUtils.register(new DateConverter(), Date.class);
         //執行
          Admin admin=new Admin();
            Map<String, Object> map=new HashMap<>();
            map.put("userName","peace2");
            map.put("age", 22);
            map.put("id", 002);
            map.put("pwd", 123456);
            map.put("birth", new Date(2015, 10, 9));
            try {
                BeanUtils.populate(admin,map);
                System.out.println(admin);
            } catch (IllegalAccessException | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     }
   }

5.Dbutils資料庫JDBC專用工具也可以封裝JavaBean:

commons-dbutils 是 Apache 組織提供的一個開源 JDBC工具類庫,它是對JDBC的簡單封裝,學習成本極低,並且使用dbutils能極大簡化jdbc編碼的工作量,同時也不會影響程式的效能。
下載連結:連結
此去只是簡要介紹,後面jdbc教程中在做完整介紹使用如下:

    @Test
    /**
     * 
    * @Title: testQueryOne 
    * @Description: 使用元件提供的結果集物件封裝資料。 
    * @return:void   
    * @throws 
    * @author peace [email protected]
     */
    public void testQueryOne(){
        String sql="select * from admin where id=?";
        //獲取連線
        connection=JdbcUtil.getConnection();
        //建立Dbutils核心工具類
        QueryRunner qr=new QueryRunner();
        //查詢返回單個物件
        try {
            //使用beanhandle進行封裝
            //引數依次為:連線,sql語句,結果處理器,位置引數
            //查下你結果封裝到Admin
            Admin admin=qr.query(connection,sql, new BeanHandler<Admin>(Admin.class), 4);
            System.out.println(admin);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
          try {
            connection.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }

封裝javaBean的方法介紹就到這裡.來自一條小鯊魚wpeace(rlovep.com)