# persistence-core
# 基本信息
# Maven/Gradle configuration
Add the Maven dependency:
<dependency>
<groupId>com.happy3w</groupId>
<artifactId>persistence-core</artifactId>
<version>0.0.5</version>
</dependency>
2
3
4
5
Add the Gradle dependency:
implementation 'com.happy3w:persistence-core:0.0.5'
# git地址
https://github.com/boroborome/persistence-core (opens new window)
# 组件介绍
# RdAssistant
行数据助理,负责在处理以行为单位的文件数据,比如excel,csv。
提供从page读写行数据的常用方法,方法命名规则如下:{Action}{DataType}
- Action范围
- read: 从page读取数据操作
- write: 将数据写入page功能
- DataType范围
- Value: 表示操作数据仅仅是一个简单数据,需要写入一个单元格中。此时如果传入的需要写入的数据为List,则将List中内容拼接为一个字符串输出
- List:表示操作数据为列表,方法会遍历列表中每个值,执行对应writeValueXXX方法
- Obj:表示操作数据为代表这一行数据的完整对象,需要根据对象定义从对象上获取需要输出的属性,这个输出
- Row:表示操作的数据为代表行数据的一个Wrapper
- Tag范围
- Cfg:表示需要通过特定配置输出
使用时通过如下代码就可以方便的读取数据
IRdTableDef rdTableDef = ...//某个数据定义
IReadDataPage page = ...//某个可以读数据的页面信息
// 读取所有数据
MessageRecorder messageRecorder = new MessageRecorder();
Stream<MyData> datas = RdAssistant.readObjs(rdTableDef, page, messageRecorder);
2
3
4
5
具体Demo可以参见 Excel读取的Demo
# ObjRdTableDef
这个名字是:Object Row Data Table Definition 的缩写,它用于定义一个可以用一行表示一个对象的信息,也叫对象行数据表。
这里将Excel或者CSV当做一个表,这个表的特点是,每行都是独立的一个数据,所以称这种表为:行数据表。
IRdTableDef是用于定义这种行数据表,ObjRdTableDef是将一个对象映射成一行数据的一种实现。此外还有RdTableDef,单独的直接凭空创建一个行数据表。这里着重讲ObjRdTableDef的使用
# Demo
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@NumFormat("#.00") // 配置在对象使用的默认数据格式为固定显示两位小数
public static class MyData {
@ObjRdColumn(value = "名字") // 配置这个字段文件中的列头名称
@FillForegroundColor(HssfColor.RED) // 配置在导出Excel时使用红色背景色(这个在库persistence-excel中)
private String name;
@ObjRdColumn(value = "年龄", required = false) // 配置列头时可以配置列是否必须出现在文件中
@NumFormat("000") // 配置这列使用的数字格式
private int age;
// 配置列头时,同时配置了使用特定的getter和setter配置这个属性,getter和setter操作的数据类型可以和这个属性不同,但getter和setter必须一致
@ObjRdColumn(value = "在校生", getter = "getEnabledText", setter = "setEnabledText")
private boolean enabled;
@ObjRdColumn("生日")
@DateFormat("yyyy-MM-dd HH:mm:ss") // 配置使用的时间格式
private Date birthday;
@ObjRdColumn("Favorite Date")
@DateFormat("yyyy-MM-dd HH:mm:ss")
@DateZoneId("UTC-8") // 配置读写文件时使用的时区
private Long favoriteDate; // 属性配置了格式类配置时,会先将数据通过TypeConverter转换为格式类配置期望的数据类型,再读写文件
/**
* 配置数据从文件加载后需要额外做的一些操作。比如年龄必须大于0,小于100的检测;名字可能带有不需要的前缀,需要去掉。
* ObjRdPostAction对被注解的方法名称、参数个数、参数顺序都没有要求,但一个对象只能有一个postAction。工具根据需要自动注入
* @param data 刚刚解析数据使用的行信息,包括page name,行数等信息
* @param recorder 如果有需要返回给用户的消息,通过这个recorder记录下来
*/
@ObjRdPostAction
public void postInit(RdRowWrapper<MyData> data, MessageRecorder recorder) {
if (age < 0 || age > 100) {
recorder.appendError("Wrong age:{0}", age);
}
if (name.startsWith("Name:")) {
name = name.substring(5);
}
}
public String getEnabledText() {
return Boolean.toString(enabled);
}
// 列头注册的setter方法可以带有两个额外的参数,属性值必须在第一位,其他参数数量和顺序没有要求,工具自动注入
public void setEnabledText(String enabled, RdRowWrapper<MyData> data, MessageRecorder recorder) {
this.enabled = Boolean.parseBoolean(enabled);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 配置规则
一般配置都既可以在属性上使用也可以在对象上使用,在属性上使用时表示这个配置只在某一列生效,在对象上配置时在所有列生效。
如果列上有和对象上一样类型的配置,则列上配置覆盖对象上配置。
# 扩展注解
注解和配置是独立的,也就是说没有注解的配置,可以通过代码直接添加到IRdTableDef上一样生效。
为了使用方便一般都会成对出现。自定义注解方法可以参考:DateFormat和DateFormatImpl。
- DateFormat 这是一个注解,用于在ObjRdTableDef中配置时间格式
@ObjRdConfigMap(DateFormatCfg.class) // 配置这个注解对应的配置类型
public @interface DateFormat {
String value(); // 需要的配置
}
2
3
4
- DateFormatCfg 这是一个配置。为了让注解和配置能直观的配对,所以使用了相同的前缀
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class DateFormatCfg implements IAnnotationRdConfig<DateFormat> { // 这个而配置支持从注解生成,所以继承自IAnnotationRdConfig,如果只是单纯的使用一个配置可以继承IRdConfig
private String format; // 配置需要的属性
// IAnnotationRdConfig接口的实现,负责从注解生成配置
@Override
public void initBy(DateFormat annotation) {
this.format = annotation.value();
}
// 构建用于比较的Key字符串。如果两个Config的内容是相同的,则生成的Key相同,如果Config内容不同,则生成的Key也不同。不需要包含自己的类型信息
@Override
public void buildContentKey(StringBuilder builder) {
builder.append(format);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ListRdTableDef
一个自定义的行数据,对于没有对象,只是单纯的直接访问excel或者csv时,可以使用这个对象。 使用时直接添加需要管理的列以及需要的定制配置信息即可。访问文件时使用List<Object>作为一行数据。
适用于将统计数据输出到文件,或者自定制输出内容场景。
# MapRdTableDef
一个自定义的行数据,对于没有对象,只是单纯的直接访问excel或者csv时,可以使用这个对象。 使用时直接添加需要管理的列以及需要的定制配置信息即可。访问文件时使用Map<String, Object>作为一行数据。
适用于将统计数据输出到文件,或者自定制输出内容场景。
# IDataPage
数据页接口。用于访问一个excel sheet或者一个csv文件。 这个接口是对文件的抽象,根据具体使用情况可以实现读接口IReadDataPage和写接口IWriteDataPage。
在persistence-excel中,SheetPage操作的是内存Dom所以同时实现了两个接口,但是在csv的访问中,会出现ReadPage和WritePage。
根据自己数据的特点可以实现自己的IDataPage。
/**
* 读文件接口
* @param <T> 自身类型
*/
public interface IReadDataPage<T extends IReadDataPage<T>> extends IDataPage<T> {
/**
* 读取指定单元格数据
* @param rowIndex 行索引
* @param columnIndex 列索引
* @param dataType 期望这个单元格的数据类型。返回类型应该和这个类型一致
* @param extConfigs 这个单元格上的配置
* @param <D> 返回数据类型
* @return 返回读取到的数据
*/
<D> D readValue(int rowIndex, int columnIndex, Class<D> dataType, ExtConfigs extConfigs);
}
/**
* 写数据接口
* @param <T> 自身类型
*/
public interface IWriteDataPage<T extends IWriteDataPage<T>> extends IDataPage<T> {
/**
* 换行。表示结束当前数据
* @return 返回自己。这是为了方便操作
*/
T newLine();
/**
* 写一个数据到当前位置,写完后向后移动一列。
* @param value 需要写入的值
* @param configs 写入数据使用的配置
* @return 返回自己。这是为了方便操作
*/
T writeValueCfg(Object value, ExtConfigs configs);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 历史
# 0.0.5
- 优化使用体验ExtConfig更容易使用
- 修复RdRowIterator的NullPointer异常
- 重构IDataPage,多数逻辑拆分到IReadDataPage和IWriteDataPage
- 丰富自定义过滤条件IFilter。实现了String,Int,Range,Date等过滤条件
- 完善IDbAssistant
- 扩展读取表数据逻辑,支持动态表头
- 增强ObjRdTableDef,使其识别注解在子类上的注解。
# 0.0.4
- 修改过滤条件为正向命名