Skip to content

Java客户端 UpdatableEntity

He, Jiehui edited this page Apr 27, 2017 · 2 revisions

概述

本文介绍了UpdatableEntity的功能和使用方式。

需求

为了提高更新效率,目前的更新操作会缺省忽略为NULL的字段。对于用户新创建的对象,这样做效率很高,但如果用户是直接在读出的记录上修改,系统就无法判断哪些字段是更新的,并且对于用户特意设置为NULL的字段会缺省忽略。

为了更方便用户在已经读出现有记录的情况下做更有效率的更新操作,DAL提供了UpdatableEntity作为entity的父类。其内部会保存所有字段的修改标记,以供更新操作使用

用法

用户需要通过Code Gen生成新的实体类(目前还不支持),或者自行手工修改现有类。

修改方式:

  • 将现有类的继承关系改为继承UpdatableEntity
  • 修改所有的set方法,添加update("列名");方法调用

UpdatableEntity示例

@Entity
@Database(name="MySqlSimpleDbTableShard")
@Table(name="dal_client_test")
public class UpdatableClientTestModel extends UpdatableEntity {
    @Id
    @Column(name="id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Type(value=Types.INTEGER)
    private Integer id;
     
    @Column(name="quantity")
    @Type(value=Types.INTEGER)
    private Integer quantity;
     
    @Column(name="dbIndex")
    @Type(value=Types.INTEGER)
    private Integer dbIndex;
     
    @Column(name="tableIndex")
    @Type(value=Types.INTEGER)
    private Integer tableIndex;
     
    @Column(name="type")
    @Type(value=Types.SMALLINT)
    private Short type;
     
    @Column(name="address")
    @Type(value=Types.VARCHAR)
    private String address;
     
    @Column(name="last_changed")
    @Type(value=Types.TIMESTAMP)
    @Version
    private Timestamp lastChanged;
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        update("id");
        this.id = id;
    }
 
    public Integer getQuantity() {
        return quantity;
    }
 
    public void setQuantity(Integer quantity) {
        update("quantity");
        this.quantity = quantity;
    }
 
    public Integer getDbIndex() {
        return dbIndex;
    }
 
    public void setDbIndex(Integer dbIndex) {
        update("dbIndex");
        this.dbIndex = dbIndex;
    }
 
    public Integer getTableIndex() {
        return tableIndex;
    }
 
    public void setTableIndex(Integer tableIndex) {
        update("tableIndex");
        this.tableIndex = tableIndex;
    }
     
    public Short getType() {
        return type;
    }
 
    public void setType(Short type) {
        update("type");
        this.type = type;
    }
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        update("address");
        this.address = address;
    }
 
    public Timestamp getLastChanged() {
        return lastChanged;
    }
 
    public void setLastChanged(Timestamp lastChanged) {
        update("last_changed");
        this.lastChanged = lastChanged;
    }
}

单元测试代码示例

@Test
public void testExecuteUpdatableEntity() throws SQLException {
    BatchUpdateTask<UpdatableClientTestModel> test = new BatchUpdateTask<>();
    test.initialize(getParser(UpdatableClientTestModel.class));
    DalHints hints = new DalHints();
     
    try {
        List<UpdatableClientTestModel> pojos = getAll(UpdatableClientTestModel.class);
        for(UpdatableClientTestModel model: pojos)
            model.setAddress("1122334455");
         
        int[] result = test.execute(hints, test.getPojosFieldsMap(pojos), pojos);
        assertEquals(3, result.length);
        assertArrayEquals(new int[]{1, 1 , 1}, result);
        assertEquals(3, getCount());
         
        pojos = getAll(UpdatableClientTestModel.class);
        for(UpdatableClientTestModel model: pojos)
            assertEquals("1122334455", model.getAddress());
         
    } catch (SQLException e) {
        e.printStackTrace();
        fail();
    }
}

特殊处理

缺省情况下,更新操作会忽略未修改的字段,某些情况下,这种做法不能满足用户需求。当用户需要更新未修改字段时,可以通过设置updateUnchangedField的hints来实现

@Test
public void testUpdateUnchangedField() throws SQLException {
    BatchUpdateTask<UpdatableClientTestModel> test = new BatchUpdateTask<>();
    test.initialize(getParser(UpdatableClientTestModel.class));
    DalHints hints = new DalHints();
     
    try {
        List<UpdatableClientTestModel> pojos = getAll(UpdatableClientTestModel.class);
        for(UpdatableClientTestModel model: pojos) {
            model.setType((Short)null);
            model.setQuantity(-100);
        }
         
        List<ClientTestModel> pojos2 = getAll();
        for(ClientTestModel model: pojos2) {
            model.setTableIndex(-1);
            model.setDbIndex(-2);
        }
         
        // Update data
        int[] result = getDao().batchUpdate(new DalHints(), pojos2);
         
        result = test.execute(hints.updateUnchangedField(), test.getPojosFieldsMap(pojos), pojos);
         
        pojos = getAll(UpdatableClientTestModel.class);
         
        // Check if still old value in UpdatabvleEntity
        int i = 0;
        for(UpdatableClientTestModel model: pojos) {
            assertNull(model.getType());
            assertEquals(-100, model.getQuantity().intValue());
            assertEquals(i++, model.getTableIndex().intValue());
            assertEquals(0, model.getDbIndex().intValue());
        }
         
    } catch (SQLException e) {
        e.printStackTrace();
        fail();
    }
}