【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应用框架,可使开发者用极简的代码即可实现对数据库的访问和 ...
随机推荐
- SQL视频总结
SQL是英文Structured Query Language的缩写,意思为结构化查询语言. SQL语言的主要功能就是同各种数据库建立联系,进行沟通.SQL被作为关系型数据库管理系统的标准语言. SQ ...
- 【bzoj4419】[Shoi2013]发微博 STL-set
题目描述 刚开通的SH微博共有n个用户(1..n标号),在短短一个月的时间内,用户们活动频繁,共有m条按时间顺序的记录: ! x 表示用户x发了一条微博: + x y 表示用户x和用户y成为了好友 ...
- Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts
Codeforces Round #421 (Div. 2) D. Mister B and PR Shifts 题意:给一个长度为\(n\)的排列,每次可以向右循环移位一次,计算\(\sum_{i= ...
- 以jhtml结尾的文件
用一个实例来说明,直接上代码. LogonAction.java(一个servlet) package com.lz.web.action; import java.io.IOException; i ...
- spring in action学习笔记十五:配置DispatcherServlet和ContextLoaderListener的几种方式。
在spring in action中论述了:DispatcherServlet和ContextLoaderListener的关系,简言之就是DispatcherServlet是用于加载web层的组件的 ...
- FastDfs java客户端上传、删除文件
#配置文件 connect_timeout = 2 network_timeout = 30 charset = UTF-8 http.tracker_http_port = 9090 http.an ...
- vue中动态循环model
vue动态循环model与angular有所不同,angular直接定义一个数组,然后传入循环列表的index即可. 而vue不仅需要定义一个数组,还需要通过接口读出循环的数组长度,然后在create ...
- linu触摸屏幕
一..前提知识 1.Linux输入子系统(Input Subsystem): 在Linux中,输入子系统是由输入子系统设备驱动层.输入子系统核心层(Input Core)和输入子系统事件处理层(Eve ...
- 51Nod 1317 相似字符串对
题目链接 分析: 考虑两个串的关系:$A+C=C+B$,我们观察可以发现,$A$和$B$是循环同构的,如果$A=G+H$,那么$B=H+G$,证明略长懒得写了... 我们知道$A$串有$K^N$种,所 ...
- 关于 cgdb & gdbtui 的输入scanf()问题
使用cgdb 和 gdbtui 调试程序时, 遇到scanf函数时 it seems to enter into an infinite loop According to the info page ...