序言:直接調(diào)用原生save方法會導(dǎo)致null屬性覆蓋到數(shù)據(jù)庫,使用起來十分不方便。本文提供便捷方法解決此問題。
核心思路
如果現(xiàn)在保存某user對象,首先根據(jù)主鍵查詢這個user的最新對象,然后將此user對象的非空屬性覆蓋到最新對象。
核心代碼
直接修改通用jparepository的實(shí)現(xiàn)類,然后在啟動類標(biāo)記此實(shí)現(xiàn)類即可。
一、通用crud實(shí)現(xiàn)類
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重復(fù) if (findbyid((id) uuid).ispresent()) { uuid = uuid.randomuuid().tostring(); } //若id為空 則設(shè)置為uuid new beanwrapperimpl(entity).setpropertyvalue(entityinformation.getidattribute().getname(), uuid); //標(biāo)記為新增數(shù)據(jù) optionalt = optional.empty(); } else { //若id非空 則查詢最新數(shù)據(jù) optionalt = findbyid(entityid); } //獲取空屬性并處理成null string[] nullproperties = getnullproperties(entity); //若根據(jù)id查詢結(jié)果為空 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); } } |
三、實(shí)體類和通用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 |
五、數(shù)據(jù)庫腳本
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(); } } |
整體結(jié)構(gòu)圖
在實(shí)際項(xiàng)目中,可以直接復(fù)制simplejparepositoryimpl使用,并不影響原有的其它api。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.jianshu.com/p/4931fbc52ea1