在CRUD操作中与业务无关的SQL字段赋值的方法
<p>提高效率一直是个永恒的话题,编程中有一项也是可以提到效率的,那就是专注做一件事情,让其它没有强紧密联系的与之分开。这里分享下我们做crud时遇到的常见数据处理场景:</p>
<p>
•数据库表字段全部设计为非空,即使这个字段在业务上是可以为空的,之所以将数据库表字段全部设计为非空,这里有优点也有缺点,我们认为优点大于缺点,所以选择了它</p>
<p>
<span><strong>优点:</strong></span></p>
<p>
1.获取值时,不用判断这个字段是否为null,直接可用于逻辑运算。</p>
<p>
2.mysql dba推荐此方案,可能是有利于性能,这里我并非求证过。</p>
<p>
<span><strong>缺点:</strong></span></p>
<p>
1.业务含义没有null清楚,比如int字段默认值设置成0,0就没有null语义清晰。</p>
<p>
2.在使用orm插入数据时,需要处理非空字段值为null的问题。</p>
<p>
• 系统字段的赋值,比如创建人,创建人id,创建时间,编辑人,编辑人id,编辑时间等,这些都需要在实际插入数据库前赋值给model。这些系统字段与具体的业务一般没有太大的关联关系,只是起到标注数据被什么人在什么时间处理的,当这些非业务相关的代码充斥在代码中时,就显得有些多余,而且这类代码多了也会显示冗余,最后带来的结果就是非关键代码比例大。</p>
<p>
<img title="在CRUD操作中与业务无关的SQL字段赋值的方法" alt="在CRUD操作中与业务无关的SQL字段赋值的方法" src="https://zhuji.jb51.net/uploads/img/202305/5d7ee15aa959c6d96e0a12d0b4a2a43f.jpg"></p>
<p>
上面关于默认值与null语义问题不需要解决,因为我们认为具有默认值带来的优点远大于可空字段带来的烦恼,我们来看默认值与系统字段一般情况下如何处理:</p>
<p>
•在操作orm时,将模型所有可空的字段都手动赋值成默认值,int的赋值为0等。</p>
<p>
•在设计数据库时,将非空字段加上默认值,让数据库来处理这些未插入值的字段,如果使用mybatis的话,mapper中提到的插入操作有两个:insert,insertselective,后面这个insertselective就是处理非空字段的,即插入的模型对于不需要赋值的字段就保持null值,数据库在插入时生成的sql语句也不会包含这些字段,这样就可以利用上数据库的默认值了。如果正巧数据库的结构当初设计时没有设计默认值,又不能改的情况就比较糟糕了,情况回到上面手动赋值,可能会出现类似如下的代码:编写一个函数通过反射来解析每个字段,如果为null就修改为默认值:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_285261">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql keyword">public</code> <code class="sql keyword">static</code> <code class="sql plain"><t> void emptynullvalue(final t model) {</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">class<?> tclass = model.getclass();</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql plain">list<field> fields = arrays.aslist(tclass.getdeclaredfields());</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql keyword">for</code> <code class="sql plain">(field field : fields) {</code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain">type t = field.gettype();</code>
</div>
<div class="line number6 index5 alt1">
<code class="sql plain">field.setaccessible(</code><code class="sql keyword">true</code><code class="sql plain">);</code>
</div>
<div class="line number7 index6 alt2">
<code class="sql plain">try {</code>
</div>
<div class="line number8 index7 alt1">
<code class="sql plain">if (t == string.class && field.get(model) == </code><code class="sql color1">null</code><code class="sql plain">) {</code>
</div>
<div class="line number9 index8 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, </code><code class="sql string">""</code><code class="sql plain">);</code>
</div>
<div class="line number10 index9 alt1">
<code class="sql plain">} </code><code class="sql keyword">else</code> <code class="sql plain">if (t == bigdecimal.class && field.get(model) == </code><code class="sql color1">null</code><code class="sql plain">) {</code>
</div>
<div class="line number11 index10 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, new bigdecimal(0));</code>
</div>
<div class="line number12 index11 alt1">
<code class="sql plain">} </code><code class="sql keyword">else</code> <code class="sql plain">if (t == long.class && field.get(model) == </code><code class="sql color1">null</code><code class="sql plain">) {</code>
</div>
<div class="line number13 index12 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, new long(0));</code>
</div>
<div class="line number14 index13 alt1">
<code class="sql plain">} </code><code class="sql keyword">else</code> <code class="sql plain">if (t == </code><code class="sql keyword">integer</code><code class="sql plain">.class && field.get(model) == </code><code class="sql color1">null</code><code class="sql plain">) {</code>
</div>
<div class="line number15 index14 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, new </code><code class="sql keyword">integer</code><code class="sql plain">(0));</code>
</div>
<div class="line number16 index15 alt1">
<code class="sql plain">} </code><code class="sql keyword">else</code> <code class="sql plain">if (t == </code><code class="sql keyword">date</code><code class="sql plain">.class && field.get(model) == </code><code class="sql color1">null</code><code class="sql plain">) {</code>
</div>
<div class="line number17 index16 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, timehelper.localdatetimetodate(java.</code><code class="sql keyword">time</code><code class="sql plain">.localdatetime.</code><code class="sql keyword">of</code><code class="sql plain">(1990, 1, 1, 0, 0, 0, 0)));</code>
</div>
<div class="line number18 index17 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number19 index18 alt2">
<code class="sql plain">} catch (illegalaccessexception e) {</code>
</div>
<div class="line number20 index19 alt1">
<code class="sql plain">e.printstacktrace();</code>
</div>
<div class="line number21 index20 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number22 index21 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number23 index22 alt2">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
然后在代码调用insert前调用函数来解决:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_471205">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">modelhelper.emptynullvalue(request);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
如何处理系统字段呢,在创建编辑数据时,需要获取当前用户,然后根据逻辑分别更新创建人信息以及编辑人信息,我们专门编写一个反射机制的函数来处理系统字段:</p>
<p>
注:下面的系统字段的识别,是靠系统约定实现的,比如creator约定为创建人等,可根据不同的情况做数据兼容,如果系统设计的好,一般在一个系统下所有表的风格应该是相同的。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_817091">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
<div class="line number22 index21 alt1">
22</div>
<div class="line number23 index22 alt2">
23</div>
<div class="line number24 index23 alt1">
24</div>
<div class="line number25 index24 alt2">
25</div>
<div class="line number26 index25 alt1">
26</div>
<div class="line number27 index26 alt2">
27</div>
<div class="line number28 index27 alt1">
28</div>
<div class="line number29 index28 alt2">
29</div>
<div class="line number30 index29 alt1">
30</div>
<div class="line number31 index30 alt2">
31</div>
<div class="line number32 index31 alt1">
32</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql keyword">public</code> <code class="sql keyword">static</code> <code class="sql plain"><t> void buildcreateandmodify(t model,modifymodel modifymodel,boolean iscreate){</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">class<?> tclass = model.getclass();</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql plain">list<field> fields = arrays.aslist(tclass.getdeclaredfields());</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql keyword">for</code> <code class="sql plain">(field field : fields) {</code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain">type t = field.gettype();</code>
</div>
<div class="line number6 index5 alt1">
<code class="sql plain">field.setaccessible(</code><code class="sql keyword">true</code><code class="sql plain">);</code>
</div>
<div class="line number7 index6 alt2">
<code class="sql plain">try {</code>
</div>
<div class="line number8 index7 alt1">
<code class="sql plain">if(iscreate){</code>
</div>
<div class="line number9 index8 alt2">
<code class="sql plain">if (field.getname().equals(modifymodel.getcid())) {</code>
</div>
<div class="line number10 index9 alt1">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, modifymodel.getuserid());</code>
</div>
<div class="line number11 index10 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number12 index11 alt1">
<code class="sql plain">if (field.getname().equals(modifymodel.getcname())) {</code>
</div>
<div class="line number13 index12 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, modifymodel.getusername());</code>
</div>
<div class="line number14 index13 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number15 index14 alt2">
<code class="sql plain">if (field.getname().equals(modifymodel.getctime())) {</code>
</div>
<div class="line number16 index15 alt1">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, new </code><code class="sql keyword">date</code><code class="sql plain">());</code>
</div>
<div class="line number17 index16 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number18 index17 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number19 index18 alt2">
<code class="sql plain">if (field.getname().equals(modifymodel.getmid())) {</code>
</div>
<div class="line number20 index19 alt1">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, modifymodel.getuserid());</code>
</div>
<div class="line number21 index20 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number22 index21 alt1">
<code class="sql plain">if (field.getname().equals(modifymodel.getmname())) {</code>
</div>
<div class="line number23 index22 alt2">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, modifymodel.getusername());</code>
</div>
<div class="line number24 index23 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number25 index24 alt2">
<code class="sql plain">if (field.getname().equals(modifymodel.getmtime())) {</code>
</div>
<div class="line number26 index25 alt1">
<code class="sql plain">field.</code><code class="sql keyword">set</code><code class="sql plain">(model, new </code><code class="sql keyword">date</code><code class="sql plain">());</code>
</div>
<div class="line number27 index26 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number28 index27 alt1">
<code class="sql plain">} catch (illegalaccessexception e) {</code>
</div>
<div class="line number29 index28 alt2">
<code class="sql plain">e.printstacktrace();</code>
</div>
<div class="line number30 index29 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number31 index30 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number32 index31 alt1">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
最后在数据处理前,根据创建或者编辑去调用函数来给系统字段赋值,这类代码都混杂在业务代码中。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_49915">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">modifymodel modifymodel = new modifymodel();</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">modifymodel.setuserid(getcurrentemployee().getid());</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql plain">modifymodel.setusername(getcurrentemployee().getname());</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql plain">if (request.getid() == 0) {</code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain">modelhelper.buildcreateandmodify(request, modifymodel, </code><code class="sql keyword">true</code><code class="sql plain">);</code>
</div>
<div class="line number6 index5 alt1">
<code class="sql plain">deptservice.</code><code class="sql keyword">insert</code><code class="sql plain">(request);</code>
</div>
<div class="line number7 index6 alt2">
<code class="sql plain">} </code><code class="sql keyword">else</code> <code class="sql plain">{</code>
</div>
<div class="line number8 index7 alt1">
<code class="sql plain">modelhelper.buildcreateandmodify(request, modifymodel, </code><code class="sql keyword">false</code><code class="sql plain">);</code>
</div>
<div class="line number9 index8 alt2">
<code class="sql plain">deptservice.updatebyprimarykey(request);</code>
</div>
<div class="line number10 index9 alt1">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<img title="在CRUD操作中与业务无关的SQL字段赋值的方法" alt="在CRUD操作中与业务无关的SQL字段赋值的方法" src="https://zhuji.jb51.net/uploads/img/202305/d265642c7e96abbc0a959b2f6449583b.jpg"></p>
<p>
我们可以利用参数注入来解决。参数注入的理念就是在spring mvc接收到前台请求的参数后,进一步对接收到的参数做处理以达到预期的效果。我们来创建</p>
<p>
managemodelconfigmethodargumentresolver,它需要实现handlermethodargumentresolver,这个接口看起来比较简单,包含两个核心方法:</p>
<p>
• 判断是否是需要注入的参数,一般通过判断参数上是否有特殊的注解来实现,也可以增加一个其它的参数判断,可根据具体的业务做调整,我这里只以是否有特殊注释来判定是否需要参数注入。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_664926">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">@override</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql keyword">public</code> <code class="sql plain">boolean supportsparameter(methodparameter parameter) {</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql keyword">return</code> <code class="sql plain">parameter.hasparameterannotation(managemodelconfig.class);</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
• 参数注入,它提供了一个扩展入口,让我们有机会对接收到的参数做进一步的处理。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_975215">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">@override</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql keyword">public</code> <code class="sql plain">object resolveargument(methodparameter parameter, modelandviewcontainer mavcontainer,</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql plain">nativewebrequest webrequest, webdatabinderfactory binderfactory) throws exception {</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql plain">object managemodel =getrequestresponsebodymethodprocessor().resolveargument(parameter, mavcontainer, webrequest, binderfactory);</code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain">servletrequest servletrequest = webrequest.getnativerequest(servletrequest.class);</code>
</div>
<div class="line number6 index5 alt1">
<code class="sql plain">employee currentuser = (employee) servletrequest.getattribute(default_attribute_get_user_from_request);</code>
</div>
<div class="line number7 index6 alt2">
<code class="sql plain">if (</code><code class="sql color1">null</code> <code class="sql plain">== currentuser)</code>
</div>
<div class="line number8 index7 alt1">
<code class="sql plain">{</code>
</div>
<div class="line number9 index8 alt2">
<code class="sql keyword">return</code> <code class="sql plain">managemodel;</code>
</div>
<div class="line number10 index9 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number11 index10 alt2">
<code class="sql plain">managemodelconfig parameterannotation = parameter.getparameterannotation(managemodelconfig.class);</code>
</div>
<div class="line number12 index11 alt1">
<code class="sql plain">modelhelper.setdefaultandsystemfieldsvalue(managemodel, currentuser,parameterannotation.issetdefaultfieldsvalue());</code>
</div>
<div class="line number13 index12 alt2">
<code class="sql keyword">return</code> <code class="sql plain">managemodel;</code>
</div>
<div class="line number14 index13 alt1">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<strong>这段函数有几处核心逻辑:</strong></p>
<p>
•取得参数对象,因为我们处理的是ajax请求的参数,最简单的注入方法就是得到实际参数通过反射去处理默认字段以及系统的值。ajax请求与form表单post提交的数据绑定略有不同,可参考之前文章分享的列表页动态搜索的参数注入(列表页的动态条件搜索)。获取当前请求参数对象,我们可以借助如下两个对象配合来完成:</p>
<p>
•requestmappinghandleradapter</p>
<p>
•requestresponsebodymethodprocessor</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_486866">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">private requestmappinghandleradapter requestmappinghandleradapter=</code><code class="sql color1">null</code><code class="sql plain">;</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">private requestresponsebodymethodprocessor requestresponsebodymethodprocessor = </code><code class="sql color1">null</code><code class="sql plain">;</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql plain">private requestresponsebodymethodprocessor getrequestresponsebodymethodprocessor() {</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql plain">if(</code><code class="sql color1">null</code><code class="sql plain">==requestmappinghandleradapter)</code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain">{</code>
</div>
<div class="line number6 index5 alt1">
<code class="sql plain">requestmappinghandleradapter=new requestmappinghandleradapter();</code>
</div>
<div class="line number7 index6 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number8 index7 alt1">
<code class="sql plain">if (</code><code class="sql color1">null</code><code class="sql plain">==requestresponsebodymethodprocessor) {</code>
</div>
<div class="line number9 index8 alt2">
<code class="sql plain">list<httpmessageconverter<?>> messageconverters = requestmappinghandleradapter.getmessageconverters();</code>
</div>
<div class="line number10 index9 alt1">
<code class="sql plain">messageconverters.</code><code class="sql keyword">add</code><code class="sql plain">(new mappingjackson2httpmessageconverter());</code>
</div>
<div class="line number11 index10 alt2">
<code class="sql plain">requestresponsebodymethodprocessor = new requestresponsebodymethodprocessor(messageconverters);</code>
</div>
<div class="line number12 index11 alt1">
<code class="sql plain">}</code>
</div>
<div class="line number13 index12 alt2">
<code class="sql keyword">return</code> <code class="sql plain">requestresponsebodymethodprocessor;</code>
</div>
<div class="line number14 index13 alt1">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
通过如下代码就可以取到参数对象了,其实就是让spring mvc重新解析了一遍参数。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_828259">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">object managemodel =getrequestresponsebodymethodprocessor().resolveargument(parameter, mavcontainer, webrequest, binderfactory);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
•如何获取当前用户,我们在成功登录系统后,将当前用户的信息存储在request中,然后就可以在函数中获取当前用户,也可以采用其它方案,比如threadlocal,缓存等等。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_8460">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">servletrequest servletrequest = webrequest.getnativerequest(servletrequest.class);</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">employee currentuser = (employee) servletrequest.getattribute(default_attribute_get_user_from_request);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
•调用处理函数解决默认字段以及系统的赋值,可以根据配置来决定是否处理字段默认值。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_203093">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">managemodelconfig parameterannotation = parameter.getparameterannotation(managemodelconfig.class);</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">modelhelper.setdefaultandsystemfieldsvalue(managemodel, currentuser,parameterannotation.issetdefaultfieldsvalue());</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
最后将我们的参数注入逻辑启动起来,这里选择在xml中配置:</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_908749">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain"><mvc:annotation-driven content-negotiation-manager=</code><code class="sql string">"contentnegotiationmanager"</code><code class="sql plain">></code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain"><mvc:argument-resolvers></code>
</div>
<div class="line number3 index2 alt2">
<code class="sql plain"><bean class=</code><code class="sql string">"cn.wanmei.party.management.common.mvc.method.annotation.managemodelconfigmethodargumentresolver"</code><code class="sql plain">/></code>
</div>
<div class="line number4 index3 alt1">
<code class="sql plain"></mvc:argument-resolvers></code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain"></mvc:annotation-driven></code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<img title="在CRUD操作中与业务无关的SQL字段赋值的方法" alt="在CRUD操作中与业务无关的SQL字段赋值的方法" src="https://zhuji.jb51.net/uploads/img/202305/48d44dd47c833e6e4c71eaf2228e47f0.jpg"></p>
<p>
再看action中的调用:只需要在参数前面增加注解@managemodelconfig,如果需要处理默认值,则将启用默认值的选项设置成true即可,下面的实现部分完全看不到任何与业务无关的代码。</p>
<div class="jb51code">
<div>
<div class="syntaxhighlightersql" id="highlighter_193159">
<div class="toolbar">
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td class="gutter">
<div class="line number1 index0 alt2">
1</div>
<div class="line number2 index1 alt1">
2</div>
<div class="line number3 index2 alt2">
3</div>
<div class="line number4 index3 alt1">
4</div>
<div class="line number5 index4 alt2">
5</div>
<div class="line number6 index5 alt1">
6</div>
<div class="line number7 index6 alt2">
7</div>
<div class="line number8 index7 alt1">
8</div>
<div class="line number9 index8 alt2">
9</div>
<div class="line number10 index9 alt1">
10</div>
<div class="line number11 index10 alt2">
11</div>
<div class="line number12 index11 alt1">
12</div>
<div class="line number13 index12 alt2">
13</div>
<div class="line number14 index13 alt1">
14</div>
<div class="line number15 index14 alt2">
15</div>
<div class="line number16 index15 alt1">
16</div>
<div class="line number17 index16 alt2">
17</div>
<div class="line number18 index17 alt1">
18</div>
<div class="line number19 index18 alt2">
19</div>
<div class="line number20 index19 alt1">
20</div>
<div class="line number21 index20 alt2">
21</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2">
<code class="sql plain">@requestmapping(value = </code><code class="sql string">"/addorupdateuser"</code><code class="sql plain">)</code>
</div>
<div class="line number2 index1 alt1">
<code class="sql plain">@responsebody</code>
</div>
<div class="line number3 index2 alt2">
<code class="sql keyword">public</code> <code class="sql plain">map<string, object> addorupdateuser(@managemodelconfig(issetdefaultfieldsvalue=</code><code class="sql keyword">true</code><code class="sql plain">) employeedto request) {</code>
</div>
<div class="line number4 index3 alt1">
<code class="sql plain">map<string, object> ret = new hashmap<>();</code>
</div>
<div class="line number5 index4 alt2">
<code class="sql plain">validateutil.validateresult result= new validateutil().validatemodel(request);</code>
</div>
<div class="line number6 index5 alt1">
<code class="sql plain">boolean iscreate=request.getid() == 0;</code>
</div>
<div class="line number7 index6 alt2">
<code class="sql plain">try {</code>
</div>
<div class="line number8 index7 alt1">
<code class="sql plain">if (iscreate)</code>
</div>
<div class="line number9 index8 alt2">
<code class="sql plain">{</code>
</div>
<div class="line number10 index9 alt1">
<code class="sql plain">employeeservice.</code><code class="sql keyword">insert</code><code class="sql plain">(request);</code>
</div>
<div class="line number11 index10 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number12 index11 alt1">
<code class="sql keyword">else</code>
</div>
<div class="line number13 index12 alt2">
<code class="sql plain">{</code>
</div>
<div class="line number14 index13 alt1">
<code class="sql plain">employeeservice.updatebyprimarykey(request);</code>
</div>
<div class="line number15 index14 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number16 index15 alt1">
<code class="sql plain">ret.put(</code><code class="sql string">"data"</code><code class="sql plain">, </code><code class="sql string">"ok"</code><code class="sql plain">);</code>
</div>
<div class="line number17 index16 alt2">
<code class="sql plain">}catch (exception e){</code>
</div>
<div class="line number18 index17 alt1">
<code class="sql plain">ret.put(</code><code class="sql string">"err"</code><code class="sql plain">, e.getmessage());</code>
</div>
<div class="line number19 index18 alt2">
<code class="sql plain">}</code>
</div>
<div class="line number20 index19 alt1">
<code class="sql keyword">return</code> <code class="sql plain">ret;</code>
</div>
<div class="line number21 index20 alt2">
<code class="sql plain">}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
</div>
<p>
<img title="在CRUD操作中与业务无关的SQL字段赋值的方法" alt="在CRUD操作中与业务无关的SQL字段赋值的方法" src="https://zhuji.jb51.net/uploads/img/202305/4acb613616aff1631bcfd998ac4ff4c6.jpg"></p>
<p>
通过自定义实现handlermethodargumentresolver,来捕获ajax请求的参数,利用反射机制动态的将系统字段以及需要处理默认值的字段自动赋值,避免人工干预,起到了代码精简,逻辑干净,问题统一处理的目的。需要注意的是这些实现都是结合当前系统设计的,比如我们认为id字段>0就代表是更新操作,为空或者等于小于0就代表是创建,系统字段也是约定名称的等等。</p>
頁:
[1]