泛型方法应用场景

非泛型类能用泛型方法

public static <T> void synInfoForTable(Class<T> clazz, List<T>){}

其中T是不能调用任何方法的,想要T的类型,只能传Class<T> clazz。

那么这个T怎么用呢?你就把T认为是一个返回类型:

比如在方法中

List<T> tblInfoListFromDB = new LinkedList<T>(query.list());

for (T tblInfoAPI : tblInfoListFromAPI) {}

就是对T的使用。

下面例子是一个同步案例:

/**
* 将信息更新到数据库(同步)

* @param clazz
*            实体类对应的class
* @param compareField
*            从API获取的对象与数据库中的对象要比较的字段,首字母大写,只能比较字符串
* @param primaryKeyField
*            实体对象的主键字段,首字母大写
* @param primaryKeyClass
*            主键字段对应的class
* @param tblInfoListFromAPI
*            从API获取的对象集合
* @throws H3cException
*/

public static <T> void synInfoForTable(Class<T> clazz, String compareField, String primaryKeyField,
Class<?> primaryKeyClass, List<T> tblInfoListFromAPI, Integer cloudSign, String... userId)
throws Exception {
Session session = HBUtil.openNewSession();
Transaction t = null;
try {
t = session.beginTransaction();
StringBuilder hql = new StringBuilder("from ");
hql.append(clazz.getSimpleName());
hql.append(" where cloudId IS NOT NULL AND deleted = :deleted AND cloudSign = :cloudSign");
if (userId.length > 0) {// 如果要根据用户同步,那么在查询时先查询出该用户的资源
hql.append(" AND userId = :userId");
}
Query query = session.createQuery(hql.toString());
query.setInteger("deleted", 0);// 只取未删除的
query.setInteger("cloudSign", cloudSign);
if (userId.length > 0) {
query.setString("userId", userId[0]);
}


@SuppressWarnings("unchecked")
List<T> tblInfoListFromDB = new LinkedList<T>(query.list());
Method compareMethod = clazz.getMethod("get" + compareField);
Method getPrimaryKeyMethod = clazz.getMethod("get" + primaryKeyField);
Method setPrimaryKeyMethod = clazz.getMethod("set" + primaryKeyField, primaryKeyClass);
for (T tblInfoAPI : tblInfoListFromAPI) {// 使用增强循环
boolean flag = true;
String compareAPI = (String) compareMethod.invoke(tblInfoAPI);
for (T tblInfoDB : tblInfoListFromDB) {
String compareDB = (String) compareMethod.invoke(tblInfoDB);
if (compareAPI.equals(compareDB)) { // db方后面的原因是可能为空
if (!tblInfoAPI.equals(tblInfoDB)) {// 如果对象有变化,就要更新,否则不更新
// 为了防止主键被置为空,所以最后还要将原先的主键值保留下来,并赋值回去
// 这步如果之前已经赋值过,就没必要做了
Object primaryKeyValue = getPrimaryKeyMethod.invoke(tblInfoDB);
CopyIgnoreProperty.copy(tblInfoAPI, tblInfoDB);
if (getPrimaryKeyMethod.invoke(tblInfoDB) == null) {
setPrimaryKeyMethod.invoke(tblInfoDB, primaryKeyValue);
}
session.update(tblInfoDB);
}
// 从集合中移除存在,是为了下面移除不存在的
tblInfoListFromDB.remove(tblInfoDB);
flag = false;
break;
}
}
if (flag) {// true为api新增的
// 如果主键是String类型(不会自动增长)的,且如果没有被赋值,那么就给他赋值
// 字符串,36长度的
if ((getPrimaryKeyMethod.invoke(tblInfoAPI) == null) && (primaryKeyClass == String.class)) {
setPrimaryKeyMethod.invoke(tblInfoAPI, UUIDHexUtil.generate36bit());
}
session.save(tblInfoAPI);
}
}
// 因为前面tblVmInfoListFromDB已经把存在的都移除了,剩下的都是不存在了的
for (T tblInfoDB : tblInfoListFromDB) {
session.delete(tblInfoDB);
}
// 只要commit没有执行,就不会保存数据
t.commit();
} catch (Exception e) {
if (t != null) {
t.rollback();
}
throw new Exception("数据库同步异常:" + e.getMessage(), e);// 调用者会说明是什么异常
} finally {
session.close();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值