天天看點

mybatis-spring從1.1更新到1.2所帶來的dao層級的編寫問題

我們公司的項目使用spring+mybatis組合。是以就必須得使用mybatis-spring了。是以此處就昨日mybatis-spring從1.1更新到1.2所帶來的dao層級的編寫問題,做了一個總結。

我們可以先來看看mybatis-spring架構的1.1.1版本中關于sqlsessiondaosupport的代碼吧:

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

<code>package</code> <code>org.mybatis.spring.support;</code>

<code>import</code> <code>static</code> <code>org.springframework.util.assert.*;</code>

<code>import</code> <code>org.apache.ibatis.session.sqlsession;</code>

<code>import</code> <code>org.apache.ibatis.session.sqlsessionfactory;</code>

<code>import</code> <code>org.mybatis.spring.sqlsessiontemplate;</code>

<code>import</code> <code>org.springframework.beans.factory.annotation.autowired;</code>

<code>import</code> <code>org.springframework.dao.support.daosupport;</code>

<code>/**</code>

<code> </code><code>* convenient super class for mybatis sqlsession data access objects.</code>

<code> </code><code>* it gives you access to the template which can then be used to execute sql methods.</code>

<code> </code><code>* &lt;p&gt;</code>

<code> </code><code>* this class needs a sqlsessiontemplate or a sqlsessionfactory.</code>

<code> </code><code>* if both are set the sqlsessionfactory will be ignored.</code>

<code> </code><code>*</code>

<code> </code><code>* @see #setsqlsessionfactory</code>

<code> </code><code>* @see #setsqlsessiontemplate</code>

<code> </code><code>* @see sqlsessiontemplate</code>

<code> </code><code>* @version $id: sqlsessiondaosupport.java 4885 2012-03-12 09:58:54z simone.tripodi $</code>

<code> </code><code>*/</code>

<code>public</code> <code>abstract</code> <code>class</code> <code>sqlsessiondaosupport </code><code>extends</code> <code>daosupport {</code>

<code>  </code><code>private</code> <code>sqlsession sqlsession;</code>

<code>  </code><code>private</code> <code>boolean</code> <code>externalsqlsession;</code>

<code>  </code><code>@autowired</code><code>(required = </code><code>false</code><code>)</code>

<code>  </code><code>public</code> <code>final</code> <code>void</code> <code>setsqlsessionfactory(sqlsessionfactory sqlsessionfactory) {</code>

<code>    </code><code>if</code> <code>(!</code><code>this</code><code>.externalsqlsession) {</code>

<code>      </code><code>this</code><code>.sqlsession = </code><code>new</code> <code>sqlsessiontemplate(sqlsessionfactory);</code>

<code>    </code><code>}</code>

<code>  </code><code>}</code>

<code>  </code><code>public</code> <code>final</code> <code>void</code> <code>setsqlsessiontemplate(sqlsessiontemplate sqlsessiontemplate) {</code>

<code>    </code><code>this</code><code>.sqlsession = sqlsessiontemplate;</code>

<code>    </code><code>this</code><code>.externalsqlsession = </code><code>true</code><code>;</code>

<code>  </code><code>/**</code>

<code>   </code><code>* users should use this method to get a sqlsession to call its statement methods</code>

<code>   </code><code>* this is sqlsession is managed by spring. users should not commit/rollback/close it</code>

<code>   </code><code>* because it will be automatically done.</code>

<code>   </code><code>*</code>

<code>   </code><code>* @return spring managed thread safe sqlsession</code>

<code>   </code><code>*/</code>

<code>  </code><code>public</code> <code>final</code> <code>sqlsession getsqlsession() {</code>

<code>    </code><code>return</code> <code>this</code><code>.sqlsession;</code>

<code>   </code><code>* {@inheritdoc}</code>

<code>  </code><code>protected</code> <code>void</code> <code>checkdaoconfig() {</code>

<code>    </code><code>notnull(</code><code>this</code><code>.sqlsession, </code><code>"property 'sqlsessionfactory' or 'sqlsessiontemplate' are required"</code><code>);</code>

<code>}</code>

  從上面的源碼可以看出:在方法setsqlsessionfactory和setsqlsessiontemplate方法上面都标注有:“@autowired(required = false)”這樣的注解。

是以我們在編寫dao層級代碼的時候隻需要dao直接繼承sqlsessiondaosupport,并标注注解@repository,然後就可以使用類似的getsqlsession().selectlist("user.selectusers");這樣的方法來使用它了,而且在spring的配置檔案中的配置也比較少:

<code>&lt;tx:annotation-driven transaction-manager=</code><code>"txmanager"</code>

<code>                         </code><code>proxy-target-</code><code>class</code><code>=</code><code>"true"</code><code>/&gt;</code>

<code>   </code><code>&lt;bean id=</code><code>"txmanager"</code> <code>class</code><code>=</code><code>"org.springframework.jdbc.datasource.datasourcetransactionmanager"</code><code>&gt;</code>

<code>       </code><code>&lt;property name=</code><code>"datasource"</code> <code>ref=</code><code>"datasource"</code><code>/&gt;</code>

<code>   </code><code>&lt;/bean&gt;</code>

<code>   </code><code>&lt;bean id=</code><code>"sqlsessionfactory"</code> <code>class</code><code>=</code><code>"org.mybatis.spring.sqlsessionfactorybean"</code><code>&gt;</code>

<code>       </code><code>&lt;property name=</code><code>"configlocation"</code> <code>value=</code><code>"classpath:mybatis-config.xml"</code><code>/&gt;</code>

  

  但是更新到1.2之後,我們看看sqlsessiondaosupport的源代碼:

<code>  </code><code>public</code> <code>void</code> <code>setsqlsessionfactory(sqlsessionfactory sqlsessionfactory) {</code>

<code>  </code><code>public</code> <code>void</code> <code>setsqlsessiontemplate(sqlsessiontemplate sqlsessiontemplate) {</code>

<code>  </code><code>public</code> <code>sqlsession getsqlsession() {</code>

  從上面的源碼可以看出:在方法setsqlsessionfactory和setsqlsessiontemplate方法上面現在都沒有标注有:“@autowired(required = false)”這樣的注解。

如果一些系統直接從mybatis-spring1.1.1更新到1.2版本的時候,就會出現問題。

在1.2版本下面有幾種方式來使用:

第一種,基于注解:

<code>@repository</code>

<code>public</code> <code>class</code> <code>userdao </code><code>extends</code> <code>sqlsessiondaosupport{</code>

<code>    </code><code>public</code> <code>list&lt;user&gt; userlist() {</code>

<code>        </code><code>return</code> <code>getsqlsession().selectlist(</code><code>"user.selectusers"</code><code>);</code>

<code>    </code><code>@override</code>

<code>    </code><code>@autowired</code>

<code>    </code><code>public</code> <code>void</code> <code>setsqlsessionfactory(sqlsessionfactory sqlsessionfactory) {</code>

<code>        </code><code>super</code><code>.setsqlsessionfactory(sqlsessionfactory);</code>

  我們自己重寫set方法就可以了。在這種情況下spring的配置檔案不需要修改。這個執行個體是随意寫的,如果你的工程中dao類很多(絕大多數情況都是),這樣你就可以編寫一個basedao,然後在這個basedao中重寫這個方法,其他的dao隻需要繼承這個basedao就可以了。

第二章基于xml檔案配置:

<code>public</code> <code>class</code> <code>userdao </code><code>extends</code> <code>sqlsessiondaosupport {</code>

  但是需要在spring的配置檔案中增加這個userdao的配置:

<code>&lt;bean id=</code><code>"userdao"</code> <code>class</code><code>=</code><code>"com.xxx.paginator.dao.userdao"</code><code>&gt;</code>

<code>    </code><code>&lt;property name=</code><code>"sqlsessionfactory"</code> <code>ref=</code><code>"sqlsessionfactory"</code><code>/&gt;</code>

<code>&lt;/bean&gt;</code>

  第一種基于注解的配置,好處是不需要編寫xml,但是這種比較容易侵入業務邏輯。

     第二種基于xml配置,好處是不侵入業務邏輯,但是當dao的數量很多的時候,需要在xml中配置好多。

     是以最後具體選擇哪種,大家可以結合自己的情況。