好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解SpringBoot实现JPA的save方法不更新null属性

序言:直接调用原生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属性的详细内容...

  阅读:88次