nhmicro技術框架應用說明(事務、aop、分庫分表、讀寫分離)

事務控制

通過@Transactional註解控制事務

在groovy方法上加上@Transactional註解,則通過GroovyExecUtil.execGroovyRetObj調用觸發此方法時,方法內的邏輯處理即可加入事務控制。

注:使用此事務控制方法,需要將com.nh.micro.template.GroovyTMAopImpl配置到aop責任鏈中。

 

通過execGroovyRetObjByDbTranNest方法啓動事務

也可以通過MicroServiceTemplateSupport中的execGroovyRetObjByDbTranNest方法啓動事務
public Object execGroovyRetObjByDbTranNest(String groovyName, String methodName, Integer nestDef, Object... paramArray)

參數爲:

groovyName,爲groovy腳本名稱

methodName,爲groovy方法名稱

nestDef,爲事務傳播級別

paramArray,爲代理的groovy腳本名稱、方法所需參數

 

獲取Mybatis的dao或其他spring管理的bean

調用MicroContextHolder的getContext方法獲取ApplicationContext對象,通過它的getbean方法獲取Mybatis的dao或其他spring的bean

getContext是靜態無參方法:

public static ApplicationContext getContext()

針對已經大量生成Mybatis的dao的場景,通過此方法可以在Groovy腳本中獲取Mybatis的dao進行數據庫操作。

 

Groovy腳本支持Aop切面編寫

技術框架支持針對Groovy腳本調用的責任鏈模式的切面handler管理。執行GroovyExecUtil.execGroovyRetObj方法時會依次觸發責任鏈中的handler。可以自行開發日誌記錄或其他技術處理handler,並配置到責任鏈中。

編寫一個handler需要繼承GroovyAopInter接口,並實現invokeMethod(GroovyObject groovyObject, String GroovyName,    String methodName, Object... param)方法,注意在handler執行過程中調用execNextHandler(GroovyObjectgroovyObject, String GroovyName, String methodName, Object... param)觸發責任鏈中下一個handler。

配置責任鏈:

<beanclass="com.nh.micro.rule.engine.core.GroovyAopChain"init-method="init">

<propertyname="handlerList">

   <list>

<beanclass="com.nh.micro.template.GroovyTMAopImpl"></bean>

   </list>

</property>

</bean>

 

 

實現讀寫分離和分庫

通過@ChangeDataSource註解設置目標數據源,結合MicroDynamicDataSource配置多數據源動態路由實現讀寫分離和分庫功能

 

 

//在groovy腳本中可配置使用@ChangeDataSource註解

class TestGroovy extends MicroServiceTemplate {
@Transactional
@ChangeDataSource(name="local_xa_dataSource")
    public Map queryTestPageList(){
        Map pageMap=new HashMap();
        pageMap.put("page", "1");
        pageMap.put("rows", "10");
        pageMap.put("sort", "id");
        pageMap.put("order", "desc");
        Map retMap=getInfoList4PageService(new HashMap(),"black",pageMap);
        return retMap;
    }
}

}

 

//Mybatis的Dao接口代碼中,也可以使用@ChangeDataSource註解決定是否切換爲其他數據源

package foo.repository;

import java.util.Map;

import com.nh.micro.datasource.ChangeDataSource;

public interface TestRep {

@ChangeDataSource(name="local_xa_dataSource")

public int updateInfo(Map paramMap);

@ChangeDataSource(name="local_xa_dataSource")

public int insertInfo(Map paramMap);

}

 

 

 

MicroDynamicDataSource動態切換數據源配置

<!-- micro動態切換數據源配置 -->

  <bean id="dynamic_xa_dataSource" class="com.nh.micro.datasource.MicroDynamicDataSource" >

  <property name="targetDataSources">   

  <map key-type="java.lang.String">

<!– 設置目標數據源爲分佈式事務數據源 --> 

  <entry key="local_xa_dataSource" value-ref=" dataSource2"></entry>    

  </map>  

  </property> 

<!-- 默認目標數據源爲主庫普通數據源 --> 

  <property name="defaultTargetDataSource" ref="dataSource"/>

  </bean>

 

 

實現分表操作

通過繼承MicroServiceTemplateSupport並在checkView方法中定製邏輯,可以針對一個視圖或虛擬的表名稱操作時,實現分表操作或針對數據庫視圖增刪改操作。

checkView(String tableName,MapparamMap,String bizId,String bizCol,String type)

參數爲:

tableName,邏輯表名稱

paramMap,參數map

bizId,業務邏輯id值

bizCol,業務邏輯id對應的數據庫字段標識

type,觸發操作類型TYPE_DEL_IDTYPE_UPDATE_IDTYPE_DEL_BIZIDTYPE_UPDATE_BIZIDTYPE_INSERTTYPE_SELECT_IDTYPE_SELECT_BIZID

 

示例代碼

real_user_view是test_user表的視圖,只顯示user_type=1的記錄

通過實現checkView方法,實現對視圖real_user_view的增刪改操作。

classcheckview_user_view extends MicroServiceTemplateSupport{

    public Integer checkView(String tableName,Map paramMap,String bizId,String bizCol,String type){

        if(type!=null && type.contains("update_")){

            Map userViewMap=getInfoByBizIdService(bizId,"real_user_view",bizCol);

            String userCode=userViewMap.get("user_code");

    updateInfoByBizIdService(userCode,"test_user","user_code",paramMap);

            return1;

        }

        if(type!=null && type.contains("del_")){

            Map userViewMap=getInfoByBizIdService(bizId,"real_user_view",bizCol);

            String userCode=userViewMap.get("user_code");

            delInfoByBizIdService(userCode,"test_user","user_code");

            return1;

        }

        if(type!=null && type.contains("insert")){

            paramMap.put("user_type","1");

            createInfoService(paramMap,"test_user");

            return1;

        }

    }

}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章