package io.terminus.trantorframework.sdk.sql;
import io.terminus.datastore.dsl.*;
import io.terminus.datastore.dsl.conf.ParamType;
import io.terminus.trantor.module.base.model.result.BooleanResult;
import io.terminus.trantor.module.base.model.result.IntResult;
import io.terminus.trantorframework.Page;
import io.terminus.trantorframework.Paging;
import io.terminus.trantorframework.api.BaseModel;
import io.terminus.trantorframework.api.annotation.SearchSqlType;
import io.terminus.trantorframework.querymodel.QAdvancedSearch;
import io.terminus.trantorframework.querymodel.QModel;
import java.util.Collection;
import java.util.stream.Collectors;
private static DataStoreClient dataStoreClient;
* 面向模型的数据插入接口,返回主键值,不支持模型级连插入
* 假如存在Order和OrderDetail模型,Order模型中使用LinkMeta关联了OrderDetail模型,调用当前接口传入order对象时会将order对象的基础字段和
* OrderDetail的id值插入到Order模型对应的表中。
* Order order = new Order();
* IntResult result = create(order);
* @param model 需要插入的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> IntResult create(Model model) {
Long id = dataStoreClient.create(model);
return new IntResult(id);
* 面向模型的数据批量插入接口,返回主键值集合,其他参考create(Model model)
* {@link io.terminus.trantorframework.sdk.sql.DS#create(Model model)}
* @param models 需要插入的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> List<IntResult> create(Collection<Model> models) {
return dataStoreClient.create(models).stream().map(IntResult::new).collect(Collectors.toList());
* 当model没有主动设置id值时,调用该接口等同于{@link io.terminus.trantorframework.sdk.sql.DS#create(Model model)},
* 如果model主动设置了id值, 等同与{@link io.terminus.trantorframework.sdk.sql.DS#update(Model model)}
* 如果调用save接口时给模型主动设置了id,如果id对应的数据不存在,既不会更新数据,也不会插入数据,会返回成功
* @param model 需要插入的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> IntResult save(Model model) {
return new IntResult(dataStoreClient.save(model));
* 面向模型的批量save接口, 功能描述参考{@link io.terminus.trantorframework.sdk.sql.DS#save(Model model)}
* @param models 需要插入的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> List<IntResult> save(Collection<Model> models) {
return dataStoreClient.save(models, false).stream().map(IntResult::new).collect(Collectors.toList());
* 面向模型的save接口, 不忽略模型中为null的属性,如果某一个属性的值为null,会把该列更新到数据库
* 与{@link io.terminus.trantorframework.sdk.sql.DS#save(Model model)}的区别在于是否忽略null值
* 其他特性与{@link io.terminus.trantorframework.sdk.sql.DS#save(Model model)}一致
public static <Model extends BaseModel<Long>> IntResult saveWithNull(Model model) {
return new IntResult(dataStoreClient.save(model, true));
* 面向模型的批量save接口, 不忽略模型中为null的属性, 功能描述参考{@link io.terminus.trantorframework.sdk.sql.DS#saveWithNull(Model model)}
* @param models 需要save的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> List<IntResult> saveWithNull(Collection<Model> models) {
return dataStoreClient.save(models, true).stream().map(IntResult::new).collect(Collectors.toList());
* 面向模型的数据update接口,如果模型中存在为null的属性,则忽略该属性的更新,返回更新结果,不支持级联更新,
* 这个API不会执行乐观锁的逻辑,即使_version字段传了值
* @param model 需要更新的已经设置好插入值的模型对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> BooleanResult update(Model model) {
return updateWithoutCheckVersion(model);
* 面向模型的数据update接口,等同于{@link io.terminus.trantorframework.sdk.sql.DS#update(Model model)}
* @param model 需要更新的已经设置好插入值的模型对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> BooleanResult updateWithoutCheckVersion(Model model) {
return new BooleanResult(dataStoreClient.updateWithoutCheckVersion(model));
* 基于乐观锁的面向模型的数据update接口,需要主动设置_version的值,如果不传会报错。如果更新不成功,也会抛出异常
* 如果模型中存在为null的属性,则忽略该属性的更新,返回更新结果,不支持级联更新
* @param model 需要更新的已经设置好插入值的模型对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> BooleanResult updateWithCheckVersion(Model model) {
return new BooleanResult(dataStoreClient.updateWithCheckVersion(model));
* 基于自定义手写TSQL的update接口,该接口容易存在维护困难,SQL注入等问题,推荐使用{@link io.terminus.trantorframework.sdk.sql.DS#update(Query update)}
* 假如存在Order模型,需要更新Order模型id为123的行的status为SUCCESS
* IntResult result = update(Order.class, "`status` = 'SUCCESS'", "id = ?", 123);
* @param modelClass 需要更新模型的modelClass
* @param where update的where条件
* @param params update TSQL中的参数
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> IntResult update(Class<Model> modelClass, String set, String where, Object... params) {
return new IntResult(dataStoreClient.update(modelClass, set, where, params));
* 基于TSQL-DSL的update接口,简单使用示例如下:
* 假如存在Order模型,需要更新Order模型id为123的行的status为SUCCESS
* Query update = TSQL.update(Order.class).set(TSQL.field(Order.status_field), "SUCCESS").where(TSQL.field(Order.id_field).eq(1));
* IntResult result = DS.update(update);
* 更多使用示例请参考trnator使用文档:https://trantor-docs.app.terminus.io/v1.x/doc/quick-start/base-crud
* @param update 构造好的TSQL-DSL对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> IntResult update(Query update) {
return new IntResult(dataStoreClient.update(update.getSQL(ParamType.INLINED), null));
* 面向模型的批量更新接口,请参考{@link io.terminus.trantorframework.sdk.sql.DS#update(Model model)}
* @param models 需要更新的已经设置好插入值的模型对象集合
public static <Model extends BaseModel<Long>> IntResult update(Collection<Model> models) {
return updateWithoutCheckVersion(models);
* 面向模型的数据update接口,等同于{@link DS#update(java.util.Collection)}
* @param models 需要更新的已经设置好插入值的模型对象集合
public static <Model extends BaseModel<Long>> IntResult updateWithoutCheckVersion(Collection<Model> models) {
return new IntResult(dataStoreClient.updateWithoutCheckVersion(models));
* 基于乐观锁的面向模型的数据批量update接口,请参考{@link io.terminus.trantorframework.sdk.sql.DS#updateWithCheckVersion(Model model)}
* @param models 需要更新的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> IntResult updateWithCheckVersion(Collection<Model> models) {
return new IntResult(dataStoreClient.updateWithCheckVersion(models));
* 面向模型的数据update接口,不忽略模型中为null的属性,如果某一个属性的值为null,会把该列更新到数据库
* 这个API不会执行乐观锁的逻辑,即使_version字段传了值
* 与{@link io.terminus.trantorframework.sdk.sql.DS#update(Model model)}的区别在于是否忽略null值
* 其他特性与{@link io.terminus.trantorframework.sdk.sql.DS#update(Model model)}一致
* @param model 需要更新的已经设置好插入值的模型对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> BooleanResult updateWithNull(Model model) {
return updateWithoutCheckVersionWithNull(model);
* 面向模型的数据update接口,等同于{@link io.terminus.trantorframework.sdk.sql.DS#updateWithNull(Model model)}
* @param model 需要更新的已经设置好插入值的模型对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> BooleanResult updateWithoutCheckVersionWithNull(Model model) {
return new BooleanResult(dataStoreClient.updateWithoutCheckVersion(model, true));
* 基于乐观锁的面向模型的数据update接口,需要主动设置_version的值,如果不传会报错。如果更新不成功,也会抛出异常
* 不忽略模型中为null的属性,如果某一个属性的值为null,会把该列更新到数据库,返回更新结果,不支持级联更新
* 与{@link io.terminus.trantorframework.sdk.sql.DS#updateWithCheckVersion(Model model)}的区别在于是否忽略null值
* 其他特性与{@link io.terminus.trantorframework.sdk.sql.DS#updateWithCheckVersion(Model model)}一致
* @param model 需要更新的已经设置好插入值的模型对象
* @return 更新结果 true or false
public static <Model extends BaseModel<Long>> BooleanResult updateWithCheckVersionWithNull(Model model) {
return new BooleanResult(dataStoreClient.updateWithCheckVersion(model, true));
* 面向模型的不忽略null值的批量更新接口,请参考{@link io.terminus.trantorframework.sdk.sql.DS#updateWithNull(Model model)}
* @param models 需要更新的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> IntResult updateWithNull(Collection<Model> models) {
return updateWithoutCheckVersionWithNull(models);
* 面向模型的数据批量update接口,等同于{@link DS#updateWithNull(java.util.Collection))}
* @param models 需要更新的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> IntResult updateWithoutCheckVersionWithNull(Collection<Model> models) {
return new IntResult(dataStoreClient.updateWithoutCheckVersion(models, true));
* 基于乐观锁的面向模型的数据批量update接口,不忽略null值, 请参考{@link io.terminus.trantorframework.sdk.sql.DS#updateWithCheckVersionWithNull(Model model)}
* @param models 需要更新的已经设置好插入值的模型对象
public static <Model extends BaseModel<Long>> IntResult updateWithCheckVersionWithNull(Collection<Model> models) {
return new IntResult(dataStoreClient.updateWithCheckVersion(models, true));
* @param model 需要删除的已经设置好id值的对象
public static <Model extends BaseModel<Long>> BooleanResult delete(Model model) {
return new BooleanResult(dataStoreClient.delete(model));
* 面向模型的批量delete接口,只能根据id删除
* @param models 需要删除的已经设置好id值的对象集合
public static <Model extends BaseModel<Long>> IntResult delete(Collection<Model> models) {
return new IntResult(dataStoreClient.delete(models));
* @param modelClass 删除模型class
public static <Model extends BaseModel<Long>> BooleanResult delete(Class<Model> modelClass, Long id) {
return new BooleanResult(dataStoreClient.delete(modelClass, id));
* IntResult 类型id值的delete接口
* @param modelClass 删除模型class
public static <Model extends BaseModel<Long>> BooleanResult delete(Class<Model> modelClass, IntResult id) {
return new BooleanResult(dataStoreClient.delete(modelClass, id.getValue().longValue()));
* 基于Long 类型id值的批量delete接口
* @param modelClass 删除模型class
public static <Model extends BaseModel<Long>> IntResult delete(Class<Model> modelClass, Collection<Long> ids) {
return new IntResult(dataStoreClient.delete(modelClass, ids));
* 基于TSQL-DSL的delete接口, 简单示例如下:
* 假如存在Order模型, 删除id为123的行
* Query delete = TSQL.delete(Order.class).where(TSQL.field(Order.id_field).eq(1));
* IntResult result = DS.delete(delete);
* 更多使用示例请参考trnator使用文档:https://trantor-docs.app.terminus.io/v1.x/doc/quick-start/base-crud
* @param query 使用TSQL-DSL构造好的删除对象
public static IntResult delete(Query query) {
return new IntResult(dataStoreClient.count(query.getSQL(ParamType.INLINED)));
* 根据id查询反序列化好的模型数据,查询所有字段
* @param modelClass 需要查新的模型class
public static <Model extends BaseModel<Long>> Model findById(Class<Model> modelClass, Long id) {
return dataStoreClient.findById(modelClass, id);
* 根据id查询反序列化好的模型数据,查询指定有字段
* @param modelClass 需要查新的模型class
* @param select 需要查询的字段,多个字段用,隔开
public static <Model extends BaseModel<Long>> Model findById(Class<Model> modelClass, Long id, String select) {
return dataStoreClient.findById(modelClass, id, select);
* 根据IntResult id查询反序列化好的模型数据,查询所有字段
* @param modelClass 需要查新的模型class
public static <Model extends BaseModel<Long>> Model findById(Class<Model> modelClass, IntResult id) {
return dataStoreClient.findById(modelClass, id.getValue().longValue());
* 根据IntResult id查询反序列化好的模型数据,查询指定字段
* @param modelClass 需要查新的模型class
public static <Model extends BaseModel<Long>> Model findById(Class<Model> modelClass, IntResult id, String select) {
return dataStoreClient.findById(modelClass, id.getValue().longValue(), select);
* 根据id集合查询反序列化好的模型数据,查询所有字段
* @param modelClass 需要查新的模型class
public static <Model extends BaseModel<Long>> List<Model> findByIds(Class<Model> modelClass, Collection<Long> ids) {
return dataStoreClient.findByIds(modelClass, ids);
* 根据IntResult id集合查询反序列化好的模型数据,查询所有字段
* @param modelClass 需要查新的模型class
public static <Model extends BaseModel<Long>> List<Model> findByIntResultIds(Class<Model> modelClass, Collection<IntResult> ids) {
Collection<Long> longIds = ids.stream().map(IntResult::longValue).collect(Collectors.toList());
return dataStoreClient.findByIds(modelClass, longIds);
* 基于TSQL的单条数据查询接口,如果能查到多条数据会抛出ValidationException("The query expected one piece of data, but found more than one")异常
* 当前接口存在SQL注入风险,建议使用基于TSQL-DSL的findOne接口,{@link io.terminus.trantorframework.sdk.sql.DS#findOne(Query query)}
* 假如存在Order模型, 查询orderName,orderCode,过滤条件为id=123
* Order order = DS.findOne(Order.class, "`orderName`,`orderCode`", "id = ?", 123);
* 更多使用说明请参考:https://trantor-docs.app.terminus.io/v1.x/doc/quick-start/base-crud
* @param modelClass 需要查询的模型的class
* @param select 查询列,多个列用,隔开, 列名最好加上反引号
public static <Model extends BaseModel<Long>> Model findOne(Class<Model> modelClass, String select, String where, Object... params) {
return dataStoreClient.findOne(modelClass, select, where, params);
* 基于TSQL-DSL的查询单条数据接口,如果能查到多条数据会抛出ValidationException("The query expected one piece of data, but found more than one")异常
* 假如存在Order模型, 查询orderName,orderCode,过滤条件为id=123
* Query query = TSQL.select(TSQL.field(Order.orderName_field), TSQL.field(Order.orderCode_field))
* .from(Order.class).where(TSQL.field(Order.id_field).eq(123));
* Order order = DS.findOne(query);
* @param query 基于TSQL-DSL构造好的findOne查询TSQL
public static <Model extends BaseModel<Long>> Model findOne(Query query) {
return (Model) dataStoreClient.findOne(query.getModelClass(), query.getSQL(ParamType.INDEXED), query.getBindValues());
* 当前接口存在SQL注入风险,建议使用基于TSQL-DSL的findAll接口,{@link io.terminus.trantorframework.sdk.sql.DS#findAll(Query query)}
* @param modelClass 需要查询的模型的class
* @param select 查询列,多个列用,隔开, 列名最好加上反引号
public static <Model extends BaseModel<Long>> List<Model> findAll(Class<Model> modelClass, String select, String where, Object... params) {
return dataStoreClient.findAll(modelClass, select, where, params);
* @param query 基于TSQL-DSL构造好的findOne查询TSQL
public static <Model extends BaseModel<Long>> List<Model> findAll(Query query) {
return dataStoreClient.findAll(query.getModelClass(), query.getSQL(ParamType.INDEXED), query.getBindValues());
* TSQL-DSL分页查询数据接口,使用该接口可以方便实现动态SQL的功能,简单举例:
* 假如存在根据不同条件组合的订单列表查询需求,可以根据订单名称,订单号任意组合,然后根据订单创建时间倒序排序,根据订单名称正序排序,进行分页查询:
* List<SelectField<Object>> selectFields = new ArrayList<>();
* selectFields.add(TSQL.field(Order.name_field));
* selectFields.add(TSQL.field(Order.orderCode_field));
* //构造一个trueCondition,等同于where true或者where 1=1,可以按需求构造falseCondition,condition用来构造查询条件
* Condition condition = TSQL.trueCondition();
* if (StringUtils.isNotEmpty(order.getName())) {
* condition = condition.and(TSQL.field(Order.name_field).eq(order.getName()));
* if (StringUtils.isNotEmpty(order.getOrderCode())) {
* condition = condition.and(TSQL.field(Order.orderCode_field).eq(order.getOrderCode()));
* List<OrderField<Object>> orderBy = Lists.newArrayList();
* orderBy.add(TSQL.field(Order.createdAt_field).desc());
* orderBy.add(TSQL.field(Order.name_field).asc()); //或者orderBy.add(TSQL.field(Order.name_field));默认为正序
* Paging<Order> result = DS.paging(Order.class, selectFields, condition, orderBy, page);
* 生成的count查询语句为select count(*) from xxx where xxx ;
* 生成的数据查询语句为select xxx from xxx where xxx order by xxx limit x,x;
* @param modelClass 当前查询主模型
* @param condition 分页查询条件
* @param orderBy 分页查询order By条件
public static <Model extends BaseModel<Long>> Paging<Model> paging(Class<Model> modelClass,
List<SelectField<Object>> selects,
List<OrderField<Object>> orderBy, Page page) {
return dataStoreClient.paging(modelClass, selects, condition, null, orderBy, page);
* TSQL-DSL分页查询数据接口,使用该接口可以方便实现动态SQL的功能,支持groupBy
* 一般来说,分页查询没有group by条件,但是我们遇到过需要group by的场景,但是之前的分页接口如果存在group by条件时获取的count存在问题,
* 因为生成的查询count的SQL为 select count(*) from xxx group by xxx,这样获取的是分组后每一组的数量,之前的paging接口获取的count默认取的第一组的数量,
* 正常count的值应该为所有分组的数量,而不关心每一个分组有多少条数据
* 所以,当前分页查询接口groupBy条件不为空时,
* 生成的count查询语句为select count(distinct `xxx`) from xxx;
* 生成的数据查询语句为select xxx from xxx where xxx group by xxx order by xxx limit x,x;
* @param modelClass 当前查询主模型
* @param condition 分页查询条件
* @param groupBy 分页查询group By条件
* @param orderBy 分页查询order By条件
public static <Model extends BaseModel<Long>> Paging<Model> paging(Class<Model> modelClass,
List<SelectField<Object>> selects,
List<Field<Object>> groupBy,
List<OrderField<Object>> orderBy,
return dataStoreClient.paging(modelClass, selects, condition, groupBy, orderBy, page);
* 基于手动拼装TSQL的分页查询接口(不推荐使用)
* 示例可参考:https://trantor-docs.app.terminus.io/v1.x/doc/quick-start/base-crud#%E5%88%86%E9%A1%B5%E6%9F%A5%E8%AF%A2:%20%E9%80%9A%E8%BF%87%E4%B8%BB%E6%A8%A1%E5%9E%8B%E6%9D%A1%E4%BB%B6%E6%9F%A5%E8%AF%A2%E4%B8%BB%E5%AD%90%E6%A8%A1%E5%9E%8B
* 1.{@link DS#paging(java.lang.Class, java.util.List, io.terminus.datastore.dsl.Condition, java.util.List, io.terminus.trantorframework.Page)}
* 2.{@link DS#paging(java.lang.Class, java.util.List, io.terminus.datastore.dsl.Condition, java.util.List, java.util.List, io.terminus.trantorframework.Page)}
* @param modelClass 需要查询的模型的class
* @param select 查询列,多个列用,隔开, 列名最好加上反引号
* @return Paging<Model>对象
public static <Model extends BaseModel<Long>> Paging<Model> paging(Class<Model> modelClass, String select, String where, Page page, Object... params) {
return dataStoreClient.paging(modelClass, select, where, page, SearchSqlType.SQL.getIsSearchSql(), params);
* @param queryModel QModel对象
public static <Model extends BaseModel<Long>> Model findOne(QModel<Model> queryModel) {
return dataStoreClient.findOne(queryModel);
* @param advancedSearch QAdvancedSearch
* @param <Model> <Model> model泛型
public static <Model extends BaseModel<Long>> Model findOne(QAdvancedSearch advancedSearch) {
return dataStoreClient.findOne(advancedSearch);
* @param queryModel QModel对象
public static <Model extends BaseModel<Long>> List<Model> findAll(QModel<Model> queryModel) {
return dataStoreClient.findAll(queryModel);
public static <Model extends BaseModel<Long>> List<Model> findAll(QAdvancedSearch advancedSearch) {
return dataStoreClient.findAll(advancedSearch);
* 基于TSQL的find接口,返回没有序列化的原始List<Map<String, Object>>
* @param params TSQL params
* @return List<Map<String, Object>>格式结果集
public static List<Map<String, Object>> find(String sql, Object... params) {
return dataStoreClient.find(sql, params);
* 基于TSQL-DSL的TSQL find接口,返回没有序列化的原始List<Map<String, Object>>
* @param query 使用TSQL-DSL构造好的TSQL查询对象
* @return List<Map<String, Object>>格式结果集
public static List<Map<String, Object>> find(Query query) {
return dataStoreClient.find(query.getSQL(ParamType.INDEXED), query.getBindValues().toArray());
* @param queryModel QModel对象
public static <Model extends BaseModel<Long>> Paging<Model> paging(QModel<Model> queryModel) {
return dataStoreClient.paging(queryModel, SearchSqlType.SQL.getIsSearchSql());
public static <Model extends BaseModel<Long>> Paging<Model> paging(QAdvancedSearch advancedSearch) {
return dataStoreClient.paging(advancedSearch, SearchSqlType.SQL.getIsSearchSql());
* @param modelClass 目标模型Class
public static <Model extends BaseModel<Long>> long count(Class<Model> modelClass, String where, Object... params) {
return dataStoreClient.count(modelClass, where, params);
public static long count(Query query) {
return dataStoreClient.count(query.getSQL(ParamType.INLINED));
public static void execute(String sql, Object... params) {
dataStoreClient.execute(sql, params);
* @param sql 完整的TSQL体,如:update table set name = 'name' where id = 1
public static void execute(String sql) {
dataStoreClient.execute(sql);
* @return 当指定ID对应的数据为软删除状态时,返回对应的软删除数据;当指定ID不存在或者对应的数据不是软删除状态时,返回null
public static <Model extends BaseModel<Long>> Model findSoftDeletedDataById(Class<Model> modelClass, IntResult id) {
return dataStoreClient.findSoftDeletedDataById(modelClass, id.getValue().longValue());
* @return 当指定ID对应的数据为软删除状态时,返回对应的软删除数据;当指定ID不存在或者对应的数据不是软删除状态时,返回null
public static <Model extends BaseModel<Long>> Model findSoftDeletedDataById(Class<Model> modelClass, Long id) {
return dataStoreClient.findSoftDeletedDataById(modelClass, id);
* @return 当指定IDs对应的数据为软删除状态时,返回对应的软删除数据;当所有指定IDs不存在或者对应的数据不是软删除状态时,返回null
public static <Model extends BaseModel<Long>> List<Model> findSoftDeletedDataByIds(Class<Model> modelClass, Collection<Long> ids) {
return dataStoreClient.findSoftDeletedDataByIds(modelClass, ids);
* @param modelClass 目标模型Class
public static <Model extends BaseModel<Long>> Long nextId(Class<Model> modelClass) {
return nextIds(modelClass, 1).get(0);
* @param modelClass 目标模型Class
* @param count 需要获取的ID总数,必须是大于0的正整数,否则会抛出IllegalArgumentException
public static <Model extends BaseModel<Long>> List<Long> nextIds(Class<Model> modelClass, int count) {
return dataStoreClient.nextIds(modelClass, count);
* @param modelClass modelClass
* @param ruleFieldName 规则字段名称
public static <Model extends BaseModel<Long>> String nextCode(Class<Model> modelClass, String ruleFieldName) {
return nextCodes(modelClass, ruleFieldName, 1).get(0);
* @param modelClass modelClass
* @param ruleFieldName 规则字段名称
public static <Model extends BaseModel<Long>> List<String> nextCodes(Class<Model> modelClass, String ruleFieldName, int count) {
return dataStoreClient.nextCodes(modelClass, ruleFieldName, count);
public static DataStoreClient getDataStoreClient() {