序言:直接调用原生save方法会导致null属性覆盖到数据库,使用起来十分不方便。本文提供便捷方法解决此问题。
核心思路
如果现在保存某user对象,首先根据主键查询这个user的最新对象,然后将此user对象的非空属性覆盖到最新对象。
核心代码
直接修改通用jparepository的实现类,然后在启动类标记此实现类即可。
一、通用crud实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
public class simplejparepositoryimpl<t, id> extends simplejparepository<t, id> {
private final jpaentityinformation<t, ?> entityinformation; private final entitymanager em;
@autowired public simplejparepositoryimpl(jpaentityinformation<t, ?> entityinformation, entitymanager entitymanager) { super (entityinformation, entitymanager); this .entityinformation = entityinformation; this .em = entitymanager; }
/** * 通用save方法 :新增/选择性更新 */ @override @transactional public <s extends t> s save(s entity) { //获取id id entityid = (id) entityinformation.getid(entity); optional<t> optionalt; if (stringutils.isempty(entityid)) { string uuid = uuid.randomuuid().tostring(); //防止uuid重复 if (findbyid((id) uuid).ispresent()) { uuid = uuid.randomuuid().tostring(); } //若id为空 则设置为uuid new beanwrapperimpl(entity).setpropertyvalue(entityinformation.getidattribute().getname(), uuid); //标记为新增数据 optionalt = optional.empty(); } else { //若id非空 则查询最新数据 optionalt = findbyid(entityid); } //获取空属性并处理成null string[] nullproperties = getnullproperties(entity); //若根据id查询结果为空 if (!optionalt.ispresent()) { em.persist(entity); //新增 return entity; } else { //1.获取最新对象 t target = optionalt.get(); //2.将非空属性覆盖到最新对象 beanutils.copyproperties(entity, target, nullproperties); //3.更新非空属性 em.merge(target); return entity; } }
/** * 获取对象的空属性 */ private static string[] getnullproperties(object src) { //1.获取bean beanwrapper srcbean = new beanwrapperimpl(src); //2.获取bean的属性描述 propertydescriptor[] pds = srcbean.getpropertydescriptors(); //3.获取bean的空属性 set<string> properties = new hashset<>(); for (propertydescriptor propertydescriptor : pds) { string propertyname = propertydescriptor.getname(); object propertyvalue = srcbean.getpropertyvalue(propertyname); if (stringutils.isempty(propertyvalue)) { srcbean.setpropertyvalue(propertyname, null ); properties.add(propertyname); } } return properties.toarray( new string[ 0 ]); } } |
二、启动类
1 2 3 4 5 6 7 8 |
@enablejparepositories (value = "com.hehe.repository" , repositorybaseclass = simplejparepositoryimpl. class ) @springbootapplication public class jpaapplication {
public static void main(string[] args) { springapplication.run(jpaapplication. class , args); } } |
三、实体类和通用save
1 2 3 4 5 6 7 8 9 10 11 12 |
@entity @table (name = "t_user" ) @jsonignoreproperties ({ "handler" , "hibernatelazyinitializer" }) public class user { @id private string userid; private string username; private string password; //省略get/set } public interface userrepository extends jparepository<user, string> { } |
四、配置文件 application.yml
1 2 3 4 5 6 |
spring: datasource: url: jdbc:mysql: //localhost:3306/socks?usessl=false username: root password: root driver- class -name: com.mysql.jdbc.driver |
五、数据库脚本
1 2 3 4 5 6 7 8 9 |
drop table if exists t_user; create table t_user ( user_id varchar( 50 ), username varchar( 50 ), password varchar( 50 ) );
insert into t_user values ( '1' , 'admin' , 'admin' ); insert into t_user values ( '2' , 'yizhiwazi' , '123456' ); |
六、测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@restcontroller public class usercontroller {
@autowired private userrepository userrepository;
@requestmapping ( "/" ) public user get() {
userrepository.save( new user( "1" , "" , null ));
return userrepository.findbyid( "1" ).get(); } } |
整体结构图
在实际项目中,可以直接复制simplejparepositoryimpl使用,并不影响原有的其它api。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
原文链接:https://HdhCmsTestjianshu测试数据/p/4931fbc52ea1
查看更多关于详解SpringBoot实现JPA的save方法不更新null属性的详细内容...