【spring data jpa】【mybatis】通过反射实现 更新/保存 实体的任意字段的操作
代码如下:
//代码示例:例如保存时,传入下面两个字段 String filed;
String content;
//User代表要更新的实体,user即本对象
//filed代表要更改的字段,例如user.name
//content代表要更改字段的值,例如“张三”
import org.springframework.beans.BeanUtils;
User user = new User();
//反射赋值
//反射 + javaBean机制 get set 方法
Class<? extends User> clz = user.getClass();
PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(clz, filed); //获取当前字段的javabean写方法
Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null) {
try {
writeMethod.invoke(user, "张三");
} catch (Exception e) {
syatem.out.println(e);
}
}
JPA保存即保存对象即可,因为对象的值已经存入user对象。
User newUser = goodsMsgService.insert(oldGoodsMsg);
mybatis保存对象:
@Update("update goods_msg set ${filed} = #{context} where uid = #{uid}")
public int saveFiled(@Param("filed")String filed, @Param("uid")String uid, @Param("context")String context);
如下,有一个完整的代码示例可以参考:
//将实体字段存入List
public static final List<String> AUTH_FILEDS = Arrays.asList(new String[]{
"innerFrist",
"innerNormal",
"innerDanger",
"outFrist",
"outNormal",
"outDanger",
"notAct",
"share",
"notSub",
"exceedMaxQueryTime",
"scanCodeLimit",
"innerSafetyTime",
"outerSafetyTime",
"scanCodeLimitTime"
});
//将实体属性 对应数据库字段存入 map 方便下面mybatis更新单个字段调用
public static final Map<String,String> AUTH_FILEDS_MAPPING = new HashMap<>();
static{
AUTH_FILEDS_MAPPING.put("innerFrist","inner_frist");
AUTH_FILEDS_MAPPING.put("innerNormal", "inner_normal");
AUTH_FILEDS_MAPPING.put("innerDanger", "inner_danger");
AUTH_FILEDS_MAPPING.put("outFrist", "out_frist");
AUTH_FILEDS_MAPPING.put("outNormal", "out_normal");
AUTH_FILEDS_MAPPING.put("outDanger", "out_danger");
AUTH_FILEDS_MAPPING.put("notAct", "not_act");
AUTH_FILEDS_MAPPING.put("share", "share");
AUTH_FILEDS_MAPPING.put("notSub","not_sub");
AUTH_FILEDS_MAPPING.put("exceedMaxQueryTime", "exceed_max_query_time");
AUTH_FILEDS_MAPPING.put("scanCodeLimit","scan_code_limit");
AUTH_FILEDS_MAPPING.put("innerSafetyTime","inner_safety_time");
AUTH_FILEDS_MAPPING.put("outerSafetyTime","outer_safety_time");
AUTH_FILEDS_MAPPING.put("scanCodeLimitTime","scan_code_limit_time");
}
/**
* 保存或修改(针对单一字段)
*
* ===========================非空字段===========================
* [
* 要修改的字段 : filed
* 字段内容 : context
* 是否全局 : global (1全局 0不是全局)
* 绑定的商品或分类 : guid(全局为空)
* ]
* ===========================保存逻辑===========================
* 1 检查要修改的字段是否存在
* 2 判断操作话述是否属于当前租户
* 3 判断是否是全局,不是全局guid做非空验证
* 4 如果已经存在记录则修改 如果不存在新增
*
* ===========================安全验证===========================
* guid是否属于当前租户
*
*
*/
@Override
public AjaxResult<String> saveFiled(@RequestBody SaveFiledRequestBean requestBean) {
//当前租户
TenementUser tenementUser = RequestData.TENEMENT_USER.get();
//非空
LunaResultBean.checkField(requestBean,"filed","context","global","name");
// 不是全局的非空
if (1 != requestBean.getGlobal()) {
LunaResultBean.checkField(requestBean,"guid");
}
String filed = requestBean.getFiled();
String guid = requestBean.getGuid();
String context = requestBean.getContext();
AjaxResult<String> res = new AjaxResult<String>();
boolean isAdd = true;
boolean success = true;
GoodsMsg oldGoodsMsg = null;
if(AUTH_FILEDS.contains(filed)){
if (StringUtils.isNotBlank(guid)) {
boolean check = goodsConfigUtils.check(GoodsConfigUtils.CHECK_GUID, guid);
if (check) {
// 是否需要新增
oldGoodsMsg = goodsMsgService.findByGuid(guid);
if (oldGoodsMsg != null) {
isAdd = false;
}
} else {
success = false;
}
} else {
// 判断全局是否已经存在
oldGoodsMsg = goodsMsgService.findByGlobalMsg(tenementUser.getTenementId());
if (oldGoodsMsg != null) {
isAdd = false;
}
}
//判断参数验证是否通过
if (success) {
if (isAdd) {
// 添加
oldGoodsMsg = new GoodsMsg();
oldGoodsMsg.initInsertData();
oldGoodsMsg.setUid(UUID.randomUUID().toString().replaceAll("-", ""));
oldGoodsMsg.setGuid(guid);
oldGoodsMsg.setGlobal(requestBean.getGlobal());
//反射赋值
//反射 + javaBean机制 get set 方法
Class<? extends GoodsMsg> clz = oldGoodsMsg.getClass();
PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(clz, filed);
//获取当前字段的javabean写方法
Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null) {
try {
writeMethod.invoke(oldGoodsMsg, requestBean.getContext());
} catch (Exception e) {
throw new LunaException("方法 "+ writeMethod.getName() +"无法执行",AjaxResult.ERROR_SYS_EXCPTION);
}
}
//新增
GoodsMsg insert = goodsMsgService.insert(oldGoodsMsg);
if (insert != null) {
res.initTrue("操作成功");
} else {
res.initFalse("操作失败", LunaResultBean.ERROR_BUSINESS);
}
} else {
//修改
//调用mybatis update 字段 by uid
int saveFiled = goodsMsgService.saveFiled(AUTH_FILEDS_MAPPING.get(filed), oldGoodsMsg.getUid(), context);
if(saveFiled > 0){
res.initTrue("操作成功");
} else {
res.initFalse("操作失败", LunaResultBean.ERROR_BUSINESS);
}
}
} else {
res.initFalse("请选择正确的商品或商品类型", LunaResultBean.ERROR_BUSINESS);
}
}else{
res.initFalse("无效字段 ["+ filed +"]", LunaResultBean.ERROR_BUSINESS);
}
return res;
}
【spring data jpa】【mybatis】通过反射实现 更新/保存 实体的任意字段的操作的更多相关文章
- Spring data Jpa,Mybatis,读写锁,@Lock 使用
Spring data jpa 支持注解式的读写锁(悲观锁),实际上这个东西硬编码也简单,但是基于Jpa 命名方式定义的Sql,只能用注解添加支持读写锁了, 不了解读写锁的可以点这里 mysql读写锁 ...
- 在Spring Data JPA 中使用Update Query更新实体类
对于 Spring Data JPA 使用的时间不长,只有两年时间.但是踩过坑的却不少. 使用下列代码 @Modifying @Query("update User u set u.firs ...
- Spring Data JPA查询指定列,并返回实体(改)
现有PostEntiy实力,包含各种属性,如: /** * @Auther: DingShuo * @Date: 2018/7/18 11:09 * @Description: */ @Entity ...
- 关于Spring Data JPA更新部分字段的问题
1.问题背景 个人比较喜欢Spring data JPA,这次的问题是在实体类中使用List类型作为字段,JPA也提供了操作的方法,即使用@ElementCollection注解,网上对于JPA的知识 ...
- 来说说JPA、Hibernate、Spring Data JPA之间的什么关系?
目录 JPA Hibernate Spring Data JPA 实践 来说说JPA.Hibernate.Spring Data JPA之间的什么关系 Java 持久层框架访问数据库的方式大致分为两种 ...
- spring data jpa(一)
第1章 Spring Data JPA的快速入门 1.1 需求说明 Spring Data JPA完成客户的基本CRUD操作 1.2 搭建Spring Data JPA的开发环境 1. ...
- SpringBoot学习笔记:Spring Data Jpa的使用
更多请关注公众号 Spring Data Jpa 简介 JPA JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR ...
- Spring Data JPA应用之常规CRUD操作初体验
基于对于一个陌生的技术框架,先使用后研究其实现的原则(大部分本人如此,就如小朋友学习骑自行车不会先研究自行车是怎么动起来的而是先骑会了),对于Spring JPA先通过案例实践其怎么用吧. 用之前得明 ...
- Spring Data JPA 自定义对象接收查询结果集
Spring Data JPA 简介 Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和 ...
随机推荐
- [洛谷P3978][TJOI2015]概率论
题目大意:对于一棵随机生成的$n$个结点的有根二叉树,所有不同构的形态等概率出现(这里同构当且仅当两棵二叉树根相同,并且相同节点的左儿子和右儿子都相同),求叶子节点个数的期望是多少? 题解:令$f_n ...
- 【BestCoder 1st Anniversary】
AB题都是签到题.... C 题意: 有一串数列,An=3*n*(n-1)+1 然后要从A数列中选取尽量少个数(可重复),使得Sum(An)=m 题解: 贪心地想,能拿大就拿大很明显就是错的...[哪 ...
- [bzoj4712] 洪水 [树链剖分+线段树+dp]
题面 传送门 思路 DP方程 首先,这题如果没有修改操作就是sb题,dp方程如下 $dp[u]=max(v[u],max(dp[v]))$,其中$v$是$u$的儿子 我们令$g[u]=max(dp[v ...
- Yum只更新安全补丁的方法
当大家想只给RHEL系统更新安全补丁的时候,往往会把其他一些无用的组件给更新下来,现在就给大家说下怎么只更新安全补丁而又不更新其他组件. 1.安装yum插件即可: yum install yum- ...
- 结构型设计模式之装饰模式(Decorator)
结构 意图 动态地给一个对象添加一些额外的职责.就增加功能来说,D e c o r a t o r 模式相比生成子类更为灵活. 适用性 在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职责. ...
- 【Cocos2D研究院之游戏开发】
http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发] 201211-19 Co ...
- JS打印——第三方控件打印
LODOP 官方地址:http://www.lodop.net/ 一个很好的打印控件,可以是实现纸张设置.横打竖打.打印预览.打印维护多种功能.官网的示例非常详细.能很好支持多种浏览器的打印. 在使用 ...
- ios 最新系统bug与解决——微信公众号中弹出键盘再收起时,原虚拟键盘位点击事件无效
最近ios发布新版本系统12.1,随着部分用户的系统更新,一些问题也渐渐暴露出来... 公司用户反映微信公众号出现了点击无效的bug!!测试调查发现,只有iphonex.iphone6,ihpone7 ...
- Java错误随手记
一.Eclipse启动时提示: An internal error occurred during: "Initializing Java Tooling" 1.关闭Eclipse ...
- 检查URL Protocol是否安装的项目
https://github.com/ismailhabib/custom-protocol-detection