简体   繁体   English

如何动态创建Java bean?

[英]How to create java beans dynamically?

从Java中的表读取列后,如何动态创建bean(保留bean中的列数据类型)?

UPDATE Previous answer was an attempt to solve the issue immediately. 更新先前的答案是尝试立即解决问题。 So it's not the final code for FlexBean. 因此,这不是FlexBean的最终代码。 For the final code, visit https://github.com/ramazanpolat/flexbean 有关最终代码,请访问https://github.com/ramazanpolat/flexbean

OLD ANSWER 老答案

I had the same problem so I wrote FlexBean. 我遇到了同样的问题,所以我写了FlexBean。

public class FlexBean {
    private List<String> propertyNames = new ArrayList<>();
    private Map<String, Object> propertyValueMap = new LinkedHashMap<>();
    private List<Type> propertyTypes  = new ArrayList<>();

    public FlexBean() {

    }

    public void setProperties(Map<String, Object> props){
        for (String propName:props.keySet()){
            addProperty(propName, props.get(propName));
        }
    }


    public void addPropertyNames(List<String> propertyNames){
        for (String name: propertyNames) {
            addProperty(name);
        }
    }

    public Collection<Object> getPropertyValues(){
        return propertyValueMap.values();
    }

    public List<String> getPropertyNames() {
        return propertyNames;
    }

    public Map<String, Object> getPropertyValueMap() {
        return propertyValueMap;
    }

    public List<Type> getPropertyTypes() {
        return propertyTypes;
    }

    public void addProperty(String propName, Type propType){
        propertyNames.add(propName);
        propertyTypes.add(propType);
    }

    public void addProperty(String propName){
        // default property type is String
        addProperty(propName, String.class);
    }

    public void addProperty(String propName, Object value){
        addProperty(propName);
        setProperty(propName, value);
    }

    public void addProperty(String propName, Type propType, Object value){
        addProperty(propName, propType);
        setProperty(propName, value);
    }

    public int getPropertyIndex(String propName){
        return propertyNames.indexOf(propName);
    }

    public Type getPropertyType(String propName){
        int index = getPropertyIndex(propName);
        return Iterables.get(propertyTypes,index);
    }

    public void setProperty(String propName, Object propValue){
        propertyValueMap.put(propName, propValue);
    }

    public Object getPropertyValue(String propName){
        return propertyValueMap.get(propName);
    }

    public <Any> Any getTypedPropertyValue(String propName){
        return (Any)((Any) propertyValueMap.get(propName));
    }

    public Object getProperty(int propIndex){
        return Iterables.get(propertyValueMap.entrySet(),propIndex).getValue();
    }
}

Usage: 用法:

FlexBean flexBean = new FlexBean();

flexBean.addProperty("prop1", 1); // int inferred
flexBean.addProperty("prop2", "value2"); // string inferred
flexBean.addProperty("prop3", 0.1f); // float inferred

for (Object o: flexBean.getPropertyValues()) {
    System.out.println(o);
}

int prop1 = flexBean.getTypedPropertyValue("prop1");
String prop2 = flexBean.getTypedPropertyValue("prop2");
float prop3 = flexBean.getTypedPropertyValue("prop3");

You can create classes dynamically with some framework like http://www.csg.ci.iu-tokyo.ac.jp/~chiba/javassist/ . 您可以使用诸如http://www.csg.ci.iu-tokyo.ac.jp/~chiba/javassist/之类的框架动态创建类。 Alternatively you could store data in a Map where key is column name and value is column value, multiple rows could be stored in a List of Maps 或者,您可以将数据存储在Map中,其中键是列名,值是列值,多行可以存储在Maps列表中

You might consider Apache BeanUtils. 您可能考虑使用Apache BeanUtils。

It provides several classes for creating beans dynamically. 它提供了几个用于动态创建bean的类。 They all implement the DynaBean interface. 它们都实现了DynaBean接口。 For example, with the LazyDynaBean : 例如,使用LazyDynaBean

DynaBean myBean = new LazyDynaBean();
myBean.set("myProperty", "myValue");

There're several frameworks/libraries that are available which can help you generate classes. 有几个可用的框架/库可以帮助您生成类。 Evgeniy suggested javassist. Evgeniy建议使用Javassist。 There're similar libraries like cglib, asm as well that you can explore. 您也可以探索类似的库,例如cglib,asm。

But I would really like to know more about your use-case because in my opinion, dynamically generated classes have their drawbacks in a statically-typed language, such as Java. 但是我真的很想了解您的用例,因为在我看来,动态生成的类在静态类型的语言(例如Java)中有其缺点。 Also, getting field data types, would require introspection using Java reflection mechanism. 同样,获取字段数据类型将需要使用Java反射机制进行自省。 That in itself adds to complexity. 这本身就增加了复杂性。

I would suggest, either of the following: 我建议以下任何一种:

  • If you've access to the database schema, consider generating the bean classes beforehand. 如果您有权访问数据库模式,请考虑事先生成Bean类。 There're several tools/plugins available for your favorite IDE to achieve this. 有多种工具/插件可用于您喜欢的IDE来实现。

  • Consider storing your data in an implementation of the Map interface. 考虑将数据存储在Map接口的实现中。 For example, you can use one of these to map your column id to the data type and another to map the column id with the data retrieved. 例如,您可以使用其中之一将列ID映射到数据类型,使用另一个将列ID映射到检索到的数据。 You can then use these two maps in your code without the need of creating any beans at runtime. 然后,您可以在代码中使用这两个映射,而无需在运行时创建任何bean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM