0

我有一个 A 类,它的属性很少:

class A {

private String col1;
private String col2;
private List<B> bList;

// setters and getters
}

Class B {
private String b1;
private String b2;
//setters and getters
}

我正在尝试使用 supercsv 和 dozer 将其写入 csv 文件。

csv 的行数应与 A 类中的列表 bList 中的元素相同。并且应具有四列 col1、col2(这对于所有行都是通用的)和 b1、b2 来自 A 类中的 B 类列表.

目前在映射文件中我有:

<mapping type="one-way" wildcard="false" map-null="true">
                <class-a>package.a</class-a>
                <class-b>org.supercsv.io.dozer.CsvDozerBeanData</class-b>
.....
</mapping>

但它只将数据映射到一行。在不将其映射到更扁平的类的情况下,有什么更好的方法来做到这一点。在映射中可以将它从 A 类映射到 CsvDozerBeanData 列表吗?那会奏效吗?

谢谢。

4

1 回答 1

1

你能添加一个从Bback to的关系A吗?然后,您可以使用以下 bean 映射遍历每个子列表:

new String[] { "a.col1", "a.col2", "b1", "b2" }

这是一个如何使用它的示例。注意嵌套循环在 each 中迭代Beach A

public class DozerTest {

    @Test
    public final void test() throws IOException {
        StringWriter out = new StringWriter();
        ICsvDozerBeanWriter writer = new CsvDozerBeanWriter(out, 
                CsvPreference.STANDARD_PREFERENCE);
        writer.configureBeanMapping(B.class, 
                new String[] { "a.col1", "a.col2", "b1", "b2" });

        for (A a : generateData()) {
            for (B b : a.getbList()) {
                writer.write(b);
            }
        }
        writer.flush();
        System.out.println(out.toString());
    }

    private List<A> generateData() {
        List<A> data = new ArrayList<A>();

        for (int i = 0; i < 3; i++) {
            A a = new A();
            a.setCol1("col1 for a" + i);
            a.setCol2("col2 for a" + i);

            B firstB = new B();
            firstB.setB1("first b1 for a" + i);
            firstB.setB2("first b2 for a" + i);
            firstB.setA(a);

            B secondB = new B();
            secondB.setB1("second b1 for a" + i);
            secondB.setB2("second b2 for a" + i);
            secondB.setA(a);

            a.setbList(Arrays.asList(firstB, secondB));
            data.add(a);
        }

        return data;
    }

}

这打印:

col1 for a0,col2 for a0,first b1 for a0,first b2 for a0
col1 for a0,col2 for a0,second b1 for a0,second b2 for a0
col1 for a1,col2 for a1,first b1 for a1,first b2 for a1
col1 for a1,col2 for a1,second b1 for a1,second b2 for a1
col1 for a2,col2 for a2,first b1 for a2,first b2 for a2
col1 for a2,col2 for a2,second b1 for a2,second b2 for a2

更新以解决评论

如果你不能添加关系,那么你可以只使用 CellProcessors(你甚至不需要使用 Dozer)。我刚刚创建了 3 个简单的单元处理器:

  • ElementAt- 只需在所需索引处抓取元素
  • GetB1- 获取b1a 的字段B
  • GetB2- 获取b2a 的字段B

他们在这里行动:

@Test
public final void test2() throws IOException {
    StringWriter out = new StringWriter();
    ICsvDozerBeanWriter writer = new CsvDozerBeanWriter(out, 
        CsvPreference.STANDARD_PREFERENCE);
    writer.configureBeanMapping(A.class, 
        new String[] { "col1", "col2", "bList", "bList" });

    for (A a : generateData()) {
        for (int i = 0; i < a.getbList().size(); i++) {
            CellProcessor[] processors = new CellProcessor[] { null, null, 
                new ElementAt(i, new GetB1()),
                new ElementAt(i, new GetB2()) };
            writer.write(a, processors);
        }
    }
    writer.flush();
    System.out.println(out.toString());
}

class GetB1 extends CellProcessorAdaptor {
    public Object execute(Object value, CsvContext context) {
        validateInputNotNull(value, context);
        return ((B) value).getB1();
    }
}

class GetB2 extends CellProcessorAdaptor {
    public Object execute(Object value, CsvContext context) {
        validateInputNotNull(value, context);
        return ((B) value).getB2();
    }
}

class ElementAt extends CellProcessorAdaptor {

    private final int index;

    public ElementAt(int index) {
        this.index = index;
    }

    public ElementAt(int index, CellProcessor next) {
        super(next);
        this.index = index;
    }

    public Object execute(Object value, CsvContext context) {
        validateInputNotNull(value, context);
        Object element = ((List<?>) value).get(index);
        return next.execute(element, context);
    }

}

输出:

col1 for a0,col2 for a0,first b1 for a0,first b2 for a0
col1 for a0,col2 for a0,second b1 for a0,second b2 for a0
col1 for a1,col2 for a1,first b1 for a1,first b2 for a1
col1 for a1,col2 for a1,second b1 for a1,second b2 for a1
col1 for a2,col2 for a2,first b1 for a2,first b2 for a2
col1 for a2,col2 for a2,second b1 for a2,second b2 for a2

ps 我不建议您提供您自己的推土机映射 XML,除非您真的必须这样做(在这种情况下,它似乎没有必要)。

于 2014-02-19T03:24:16.363 回答