NutzCN Logo
问答 关于nutz保存list数据问题
发布于 3305天前 作者 lancedou 2779 次浏览 复制 上一个帖子 下一个帖子
标签: dao

nutz现在支持保存list数据的时候,原来有的就更新没有的就插入操作吗。

13 回复

没有直接支持,自行封装一下

来自炫酷的 NutzCN

@wendal 自己封装的时候,那种用法效率会更高点,有过着方面的经验吗。

@lancedou 记录是否已经存在的判断条件是什么?

来自炫酷的 NutzCN

@wendal 判断条件就是对象的一个属性值是否相等

@admin 大人,这个链接打不开

	@SuppressWarnings("unchecked")
    public static <T> T insertOrUpdate(Dao dao, T obj) {
	    if (obj == null)
	        return null;
	    Entity<T> en = (Entity<T>) dao.getEntity(obj.getClass());
	    if (en.getPkType() == PkType.UNKNOWN)
	        throw new IllegalArgumentException("no support , without pks");
	    boolean doInsert = false;
	    switch (en.getPkType()) {
        case ID:
            Number n = (Number) en.getIdField().getValue(obj);
            if (n == null || n.intValue() == 0)
                doInsert = true;
            break;
        case NAME:
            if (null == en.getNameField().getValue(obj))
                doInsert = false;
            break;
        case COMPOSITE:
            doInsert = true;
            for(MappingField mf :en.getCompositePKFields()) {
                Object v = mf.getValue(obj);
                if (v != null) {
                    if (v instanceof Number && ((Number)v).intValue() != 0) {
                        continue;
                    }
                    doInsert = true;
                }
            }
        case UNKNOWN:
            throw Lang.impossible();
        }
	    if (doInsert) {
	        return dao.insert(obj);
	    } else{
	        dao.update(obj);
	        return obj;
	    }
	}

@admin 明白了。先试试,看效率怎么样

如果指定某个属性,这样写应该更好


/** * 更新或插入对象 * @param dao Dao实例 * @param list 需要操作的列表 * @param field 作为判定依据的属性名称 */ public static <T> void insertOrUpdate(Dao dao, List<T> list, String field) { Entity<? extends Object> en = dao.getEntity(list.get(0).getClass()); MappingField mf = en.getField(field); for (T t : list) { Object val = mf.getValue(t); // 如果对应的属性不为null,且不为0,到数据库检查一下是否存在 if (val != null && !(val instanceof Number && ((Number)val).intValue() == 0)) { // count一下就知道是否存在了 if (dao.count(t.getClass(), Cnd.where(field, "=", val)) != 0) { dao.update(t); // 存在,更新之 continue; } } dao.insert(t); } }

@wendal 这种做写法挺好

若是密集并发, 这种先取值再决定插入还是删除的做法也可能导致判断错误, 我目前的代码就遇到了。除了加锁,还有什么好方法么?

如果能利用mysql的“INSERT ... ON DUPLICATE KEY UPDATE”特性就好了, 不过这样就依赖数据库方言

@songofhawk 自定义sql?事务模板加version字段也可以

来自炫酷的 NutzCN

添加回复
请先登陆
回到顶部