Apache BeanUtils ツールの紹介

beanutils は、その名前が示すように、Java Bean のツール クラスであり、Bean プロパティ値の読み取り (取得) と設定 (設定)、Bean プロパティの動的定義とアクセスを簡単に行うことができます。注意していれば、JDK が.beans パッケージでも上記の機能を実現できますが、使用するのが面倒なので、Apache Commons beanutils が誕生しました; 実際には、Apache Commons beanutils は Java をベースに実装されていることがソース コードからわかります。 jdk の .beans パッケージ。

メイブン:

<dependency>
        <groupId>commons-chain</groupId>
        <artifactId>commons-chain</artifactId>
        <version>1.2</version>
</dependency>

commons-chain パッケージには主に、BeanUtils、PropertyUtils、ConvertUtils の 3 つのツール クラスがあります。

1. Bean プロパティの設定とアクセス

1.1) Javabean には一般に次の特徴があります。

1) クラスにはパブリック アクセス権が必要で、パブリックな引数なしの構築メソッドが必要です。この理由は主に、オブジェクト インスタンスを動的に作成する Java リフレクションの使用を容易にするためです。

クラス beanClass = Class.forName(className);

オブジェクト beanInstance = beanClass.newInstance();

2) Javabean の構築メソッドにはパラメータがないため、Bean の動作設定 (つまり、Bean のプロパティ値の設定) を構築メソッド内で完了することができず、set メソッドを通じてプロパティ値を設定する必要があります。ここでのセッター メソッドには、setHireDate、setName などの特定の規則に従って名前が付けられます。

3) Bean プロパティ値の読み取りと設定の命名規則、つまりゲッター メソッドとセッター メソッド。ただし、ここでは、次の例に示すように、ブール型の規則に特別な注意を払う必要があります。

private String firstName;
private String lastName;
private Date hireDate;
private boolean isManager;
public String getFirstName();
public void setFirstName(String firstName);
public String getLastName();
public void setLastName(String lastName);
public Date getHireDate();
public void setHireDate(Date hireDate);
public boolean isManager();
public void setManager(boolean manager);

4) 各属性にセッター メソッドとゲッター メソッドを提供する必要はありません。セッター メソッドを定義せずに、属性のゲッター メソッドのみを定義できます。このような属性は通常、読み取り専用の属性です。

1.2) 実戦

Bean プロパティは、BeanUtils および PropertyUtils を通じて設定および取得できます。

1) PropertyUtils はプロパティを設定および取得します。

  • 基本的なデータ型:
    • PropertyUtils.getSimpleProperty(オブジェクト, 文字列)
    • PropertyUtils.setSimpleProperty(オブジェクト, 文字列, オブジェクト)
  • インデックスの種類:
    • PropertyUtils.getIndexedProperty(オブジェクト, 文字列)
    • PropertyUtils.getIndexedProperty(Object, String, int)
    • PropertyUtils.setIndexedProperty(オブジェクト, 文字列, オブジェクト)
    • PropertyUtils.setIndexedProperty(Object, String, int, Object)
  • マップの種類:
    • PropertyUtils.getMappedProperty(オブジェクト, 文字列)
    • PropertyUtils.getMappedProperty(オブジェクト, 文字列, 文字列)
    • PropertyUtils.setMappedProperty(オブジェクト, 文字列, オブジェクト)
    • PropertyUtils.setMappedProperty(オブジェクト, 文字列, 文字列, オブジェクト)
  • ネストされた型:
    • PropertyUtils.getNestedProperty(オブジェクト, 文字列)
    • PropertyUtils.setNestedProperty(オブジェクト, 文字列, オブジェクト)
  • 汎用タイプ:
    • PropertyUtils.getProperty(オブジェクト, 文字列)
    • PropertyUtils.setProperty(オブジェクト, 文字列, オブジェクト)

例:

//定义bean
@Data
@ToString
public class Course {
	private String name;
    private List<String> codes;
    private Map<String, Student> enrolledStudent = new HashMap<>();
}
@Data
@ToString
public class Student {
	private String name;
}

//测试
Course course = new Course(); //该类必须是public的、且有默认构造方法

String name = "Computer Science";
List<String> codes = Arrays.asList("CS", "CS01");

//Simple Property
PropertyUtils.setSimpleProperty(course, "name", name);
PropertyUtils.setSimpleProperty(course, "codes", codes);
System.out.println(course);
String nameV = (String)PropertyUtils.getSimpleProperty(course, "name");
System.out.println(nameV);

//Indexed Property
PropertyUtils.setIndexedProperty(course, "codes[1]", "CS02");
PropertyUtils.setIndexedProperty(course, "codes", 1, "CS03");
System.out.println(course);
String indexedProperty = (String)PropertyUtils.getIndexedProperty(course, "codes", 1);
String indexedProperty2 = (String)PropertyUtils.getIndexedProperty(course, "codes[1]");
System.out.println(indexedProperty + "," + indexedProperty2);

Student student = new Student();
String studentName = "Joe";
student.setName(studentName);

//Mapped Property
PropertyUtils.setMappedProperty(course, "enrolledStudent(ST-1)", student);
PropertyUtils.setMappedProperty(course, "enrolledStudent", "ST-1", student);
System.out.println(course);
Student mappedProperty = (Student)PropertyUtils.getMappedProperty(course, "enrolledStudent", "ST-1");
Student mappedProperty2 = (Student)PropertyUtils.getMappedProperty(course, "enrolledStudent(ST-1)");
System.out.println(mappedProperty + "," + mappedProperty2);

//Nested Property
PropertyUtils.setNestedProperty(course, "enrolledStudent(ST-1).name", "Joe_1");
String nameValue = (String) PropertyUtils.getNestedProperty(course, "enrolledStudent(ST-1).name");
//等价于 String name = course.getEnrolledStudent("ST-1").getName();
System.out.println(nameValue);

上記は次のように使用することもできます。

private static void test1_1() throws Exception {
        Course course = new Course();
        
        String name = "Computer Science";
        List<String> codes = Arrays.asList("CS", "CS01");
        
        //Simple Property
        PropertyUtils.setProperty(course, "name", name);
        PropertyUtils.setProperty(course, "codes", codes);
        System.out.println(course);
        String nameV = (String)PropertyUtils.getProperty(course, "name");
        System.out.println(nameV);
        
        //Indexed Property
        PropertyUtils.setProperty(course, "codes[1]", "CS02");
        System.out.println(course);
        
        Student student = new Student();
        String studentName = "Joe";
        student.setName(studentName);
        
        //Mapped Property
        PropertyUtils.setProperty(course, "enrolledStudent(ST-1)", student);
        System.out.println(course);
        
        //Nested Property
        PropertyUtils.setProperty(course, "enrolledStudent(ST-1).name", "Joe_1");
        String nameValue = (String) PropertyUtils.getProperty(course, "enrolledStudent(ST-1).name");
        System.out.println(nameValue);
}

2) BeanUtils はプロパティを設定および取得します。

BeanUtils にはプロパティを設定および取得するメソッドが次の 2 つしかありません

  • BeanUtils.getProperty(オブジェクト, 文字列)
  • BeanUtils.setProperty(オブジェクト, 文字列, オブジェクト)

 例:

private static void test1_2() throws Exception {
        Course course = new Course();
        
        String name = "Computer Science";
        List<String> codes = Arrays.asList("CS", "CS01");
        
        //Simple Property
        BeanUtils.setProperty(course, "name", name);
        BeanUtils.setProperty(course, "codes", codes);
        System.out.println(course);
        String nameV = (String)BeanUtils.getProperty(course, "name");
        System.out.println(nameV);
        
        //Indexed Property
        BeanUtils.setProperty(course, "codes[1]", "CS02");
        System.out.println(course);
        
        Student student = new Student();
        String studentName = "Joe";
        student.setName(studentName);
        
        //Mapped Property
        BeanUtils.setProperty(course, "enrolledStudent(ST-1)", student);
        System.out.println(course);
        
        //Nested Property
        BeanUtils.setProperty(course, "enrolledStudent(ST-1).name", "Joe_1");
        String nameValue = (String) BeanUtils.getProperty(course, "enrolledStudent(ST-1).name");
        System.out.println(nameValue);
}

2. Bean のプロパティをコピーします。

2.1) BeanUtils には次の 2 つのメソッドがあります。

  • Populate: マップ内のキーと値のペアの値を Bean のプロパティ値にコピーします。
  • copyProperties: ある Bean のプロパティを別の Bean にコピーします。浅いコピーに注意してください。

注: Populate と copyProperties の違いは、Integer、Float、Boolean 型の場合、null 値の前者 (populate) が Bean のプロパティにコピーされた後のデフォルト値になることです。

1)人口:

//bean定义
import java.util.Date;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Employee {
	private Integer id;
	private String name;
	private Boolean isGood;
   private Float score;
	private Date createTime;
	
	public Employee(Integer id, String name, Boolean isGood, Float score, Date createTime) {
           this.id = id;
           this.name = name;
           this.isGood = isGood;
           this.score = score;
           this.createTime = createTime;
	}
}
//测试
Map<String, Object> map = new HashMap<>(2);
map.put("id", null);
map.put("name", "employee1");
map.put("isGood", null);
map.put("createTime", new Date()); //如果是null,会报错
map.put("add", "add1");
// map > obj
Employee e = new Employee();
BeanUtils.populate(e, map);
System.out.println(e); //Employee(id=0, name=employee1, isGood=false, createTime=Tue Aug 15 10:42:14 CST 2023)

//支持类型转换
Map<String, Object> map = new HashMap<>(5);
map.put("id", "123"); 
map.put("name", 1.9);
map.put("isGood", "2"); 
map.put("score", null);
map.put("createTime", new Date());
map.put("add", "add1");
// map > obj
Employee e = new Employee();
BeanUtils.populate(e, map);
System.out.println(e); //Employee(id=123, name=1.9, isGood=false, score=1.0, createTime=Tue Aug 15 12:34:41 CST 2023)

例証します:

  • Integer、Float、Boolean 型の場合、null の場合、Bean のプロパティに変換された後、デフォルト値 (0、0.1、false) になります。
  • Date 型の場合、null またはその他の型の場合、Bean に変換されるときにエラーが報告され、型変換には ConvertUtils を使用する必要があります (下記を参照)。
  • 型変換のサポート: Integer と String 間の変換など

2)コピープロパティ:

別のオブジェクトがあります (従業員とは異なるタイプ)

@Data
public class Employee2 {
	private Integer id;
	private String name;
	private String isGood;
	private String score;
	private String createTime;
	private Float f1;
}

テスト

private static void test2_1() throws Exception {
        Employee ee = new Employee(null, "employee2", null, null, null);
        Employee2 e1 = new Employee2();
        BeanUtils.copyProperties(e1, ee);
        System.out.println(e1); //Employee2(id=null, name=employee2, isGood=null, score=null, createTime=null, f1=null)
        
        Employee ee2 = new Employee(1, "employee2", true, 4.3f, new Date());
        Employee2 e2 = new Employee2();
        BeanUtils.copyProperties(e2, ee2);
        System.out.println(e2); //Employee2(id=1, name=employee2, isGood=true, score=4.3, createTime=Tue Aug 15 11:45:06 CST 2023, f1=null)
}

例証します:

  • Integer、Float、Boolean、および Date 型の場合、null の場合、コピー後も null になります。
  • 型変換のサポート: 2 つの Bean のプロパティ名が同じである限り、型を変換してコピーできます。たとえば、Integer、Float、Boolean 型を String に変換します。

2.2) プロパティ コピー用の PropertyUtils:

1) BeanUtils との違い:

  • PropertyUtils は 2 つの Bean 間のプロパティのコピーのみをサポートし、Bean へのマップはサポートしません。
  • PropertyUtils が 2 つの Bean 間でプロパティをコピーする場合、名前と型が同じであることを確認する必要があります。そうでない場合は、エラーが報告されます。BeanUtils がプロパティをコピーすると、名前は同じになり、型を変換できます。

 

Employee ee = new Employee(null, "employee2", null, null, null);
Employee2 e1 = new Employee2();
PropertyUtils.copyProperties(e1, ee);
System.out.println(e1); //Employee2(id=null, name=employee2, isGood=null, score=null, createTime=null, f1=null)

Employee ee2 = new Employee(1, "employee2", true, 4.3f, new Date());
Employee2 e2 = new Employee2();
PropertyUtils.copyProperties(e2, ee2);
System.out.println(e2); //报错

エラーメッセージ:

 

2) 説明:

  • PropertyUtils は型変換をサポートしていません。
  • null 値の場合、コピー後の PropertyUtils も null になります。

3. ConvertUtils カスタム型変換

1)日付コンバータ:

DateConverter は、Beanutils パッケージに付属する時刻型変換である DateTimeConverter を継承します。次のものが含まれます。

DateConverter converter = new DateConverter();
converter.setPattern("yyyy-MM-dd");
ConvertUtils.register(converter, java.util.Date.class);

Map<String, Object> map = new HashMap<>(5);
map.put("id", 1); 
map.put("name", "testConvertUtils");
map.put("isGood", false); //可以是Integer或String,1或"1" true 其他表示false,null表示false
map.put("score", 1.1f);
map.put("createTime", "2023-08-15");
map.put("add", "add1");

// map > obj
Employee e = new Employee();
BeanUtils.populate(e, map);
System.out.println(e); //Employee(id=1, name=testConvertUtils, isGood=false, score=1.1, createTime=Tue Aug 15 00:00:00 CST 2023)

2) カスタマイズ: 

ConvertUtils.register(new Converter() {
    public Object convert(Class type, Object value) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return simpleDateFormat.parse(value.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}, Date.class);
Employee e1 = new Employee();
BeanUtils.setProperty(e1, "createTime", "2022-09-09");
System.out.println(e1.getCreateTime()); //Fri Sep 09 00:00:00 CST 2022

注: setProperty の場合、時刻型がある場合は、カスタム コンバーターが必要です。

おすすめ

転載: blog.csdn.net/liuxiao723846/article/details/132422611