當DBFound與Springboot結合,會擦出什麼樣的火花

初識DBFound+Springboot

    Springboot+mybatis的組合,相信很多搞Java研發的工程師來說都非常熟悉,在實際項目中也是運用的非常廣泛;但它不是今天的主角,今天我們來看看Springboot+dbfound的組合,會給我們帶來哪些不一樣的感受;dbfound是筆者2011年起草的一個持久層框架,1.0版本發佈於2012年,目前最新版本2.4.1;

焦作國醫胃腸醫院評價怎麼樣:http://jz.lieju.com/zhuankeyiyuan/37325143.htm

    通常我們寫一個業務功能,比如寫一個查詢用戶表(sys_user)的接口功能;在Springboot+mybatis的組合中,我們通常要寫 UserController.java、UserService.java、UserDao.java、User.java 和 UserMapper.xml這五個文件,來實現這個功能;代碼層次分明、結構清晰,但略顯繁瑣,代碼如下:

     

    我們僅僅就是想實現一個查詢功能而已,就需要些4個java + 1個xml文件才能實現;那有沒有更簡單快捷一點的方式呢?DBFound爲快捷而生。下面我們看看用Springboot+dbfound組合,我們怎麼去實現;我們只需要寫一個xml文件(user.xml) 功能就已經完成了。如下圖,我們只需要已xml爲載體,把sql配置下,然後把xml放到springboot的容器中即可;

        

   我們通過瀏覽器打開http://localhost:8080/user.query;就可以請求到model目錄下的user.xml文件了;效果如下圖,返回結果爲一個json字符串;

       

    我們還可以通過start和limit參數,來進行分頁查詢,如查詢第10條到第20條 http://localhost:8080/user.query?limit=10&start=10 ; 我們的query對象中有兩個<filter>標籤,我們還可以傳入user_name、user_code進行匹配查詢 http://localhost:8080/user.query?limit=10&start=10&user_name=john ;

DBFound+Springboot環境搭建

    搭建dbfound+springboot環境,也非常簡單;

    在創建一個springboot2.x的maven項目後,我們在pom.xml中加入dbfound-spring-boot-starter,如下:

<dependencies>
	<dependency>
		<groupId>com.github.nfwork</groupId>
		<artifactId>dbfound-spring-boot-starter</artifactId>
		<version>2.0.2</version>
	</dependency></dependencies>

    其次在springboot的配置文件application.properties中,加入dbfound的配置,如下:

dbfound.datasource.db0.url=jdbc:mysql://127.0.0.1:3306/dbfounddbfound.datasource.db0.username=root
dbfound.datasource.db0.password=root
dbfound.datasource.db0.dialect=MySqlDialect

    最後就是編寫model文件了,user.xml;默認情況下放在classpath下面的model文件夾下,如下:

<?xml version="1.0" encoding="UTF-8"?><model xmlns="http://dbfound.googlecode.com/model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://dbfound.googlecode.com/model https://raw.githubusercontent.com/nfwork/dbfound/master/tags/model.xsd">
	<query>
		<sql>
		  <![CDATA[
			SELECT
				user_name,
				user_code,
				password
			FROM SYS_USER u
			#WHERE_CLAUSE#
		  ]]>		</sql>
		<filter name="user_code" express="user_code like ${@user_code}" />
		<filter name="user_name" express="user_name like ${@user_name}" />
	</query></model>

    model文件由<query>和<execute>兩大組建構成,query對於select語句,execute對於insert、update、delete語句;這裏就不多講了,詳情請參考之前寫的《dbfound快速開發平臺》文章中的介紹;

http://m.qd8.com.cn/yiyao/xinxi21_3710012.html

多數據源配置與事物管理

    在實際的業務系統中,我們常常用到的不止一個數據源;在Springboot+mybatis組合中,原生配置是沒辦法做到多數據源的,必須要寫代碼實現;事物管理也是需要開發者去寫大量的代碼實現;但Springboot+dbfound中,這些麻煩事框架都給我們解決了。

    首先我們在springboot配置文件application.properties中,加入多數據源配置; 注意這次我們多加了一個 provideName的屬性,來區分不同的數據源;

dbfound.datasource.db0.provideName=database01
dbfound.datasource.db0.url=jdbc:mysql://192.168.1.111:3306/dbfounddbfound.datasource.db0.username=jbjava
dbfound.datasource.db0.password=jb98
dbfound.datasource.db0.dialect=MySqlDialect

dbfound.datasource.db1.provideName=database02
dbfound.datasource.db1.url=jdbc:mysql://192.168.1.112:3306/dbfound02dbfound.datasource.db1.username=jbjava
dbfound.datasource.db1.password=jb98
dbfound.datasource.db1.dialect=MySqlDialect

    然後我們的model文件也需要做一點小的調整,需要在model標籤中,多加了一個connetionProvide屬性,與provideName一致即可:

<?xml version="1.0" encoding="UTF-8"?><model connectionProvide="database01" xmlns="http://dbfound.googlecode.com/model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://dbfound.googlecode.com/model https://raw.githubusercontent.com/nfwork/dbfound/master/tags/model.xsd">
	<query>
		<sql>
		  <![CDATA[
			SELECT
				user_name,
				user_code,
				password
			FROM SYS_USER u
			#WHERE_CLAUSE#
		 ]]>		</sql>
		<filter name="user_code" express="user_code like ${@user_code}" />
		<filter name="user_name" express="user_name like ${@user_name}" />
	</query></model>

    在數據源的配置中,我們允許一個沒有provideName的數據源,作爲缺省數據源 與 model中沒有指定connectionProvide的model文件 相互對應;我們通常建議db0不配置provideName,作爲缺省。

    事物管理方面,通過http直接訪問model的情況,訪問的execute對象默認加上了事物,當一個execute對象中執行了多條sql,會開啓事物保證一致性;

<execute name="update">
	<sqls>
		<executeSql>
			<![CDATA[
			    update table1
			 ]]>		</executeSql>
		<executeSql>
			<![CDATA[
				update table2
			 ]]>		</executeSql>
	</sqls></execute>

    對於Java代碼調用的情況下,使用@Transaction註解進行聲明即可;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.github.nfwork.dbfound.starter.ModelExecutor;import com.nfwork.dbfound.core.Context;@Servicepublic class TestService {	
	@Autowired
	ModelExecutor modelExecutor;	
	@Transactional
	public void save(Context context) {
		modelExecutor.execute(context, "user", "add");
		modelExecutor.execute(context, "user", "update");
	}

}

與SpringMVC的數據交互

    熟悉dbfound的朋友都會知道,dbfound所有的參數都保存在Context;Context作爲數據載體,model在執行的時候根據數據路徑執行匹配,下一次單獨寫一個文章來說明Context數據交互;今天的重點,如何在springmvc如何獲取Context呢?我們推薦了兩種方式,方法如下:

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.github.nfwork.dbfound.starter.ModelExecutor;import com.github.nfwork.dbfound.starter.annotation.ContextAware;import com.nfwork.dbfound.core.Context;@RestControllerpublic class TestController {	
	@Autowired
	ModelExecutor modelExecutor;	
	@RequestMapping("query1")	public Object query(@ContextAware Context context) {		return modelExecutor.query(context, "user", null);
	}	
	@RequestMapping("query2")	public Object query(String userName) {
		Context context = new Context();
		context.setParamData("user_name", userName);		return modelExecutor.query(context, "user", null);
	}

}

model的調用API

    框架提供了兩種調用model文件的方式,一種是http,另外一種的javaapi;在講api之前,我們先說明下三個重要的參數:modelName、queryName和executeName;我們通過modelName+queryName定位一個query服務,通過modelName+executeName定位一個execute服務;

    當一個user.xml放在classpath/model目錄下時,它的modelName就是user; 當一個function.xml放在classpath/model/sys目錄下面時,它的modelName就是sys/function;

    queryName和executeName在xml文件中指定;比如<query name="listAll"> 那他的queryName就是 listAll;modelName原理一樣;一個model文件中,我們允許一個無名的query和execute;

    http請求方式:

        http://localhost:8080/user.query modelName是user,queryName爲缺省;

        http://localhost:8080/user.query!listAll 時queryName爲!後面的內容,即listAll;

        http://localhost:8080/user.execute modelName是user,executeName爲缺省;

        http://localhost:8080/user.execute!add executeName爲add;

    javaapi方式:

@Servicepublic class TestService {	
	@Autowired
	ModelExecutor modelExecutor;	
	public Object query(Context context) {
		Object object = null;
		object = modelExecutor.queryList(context, "user", null); //modelName=user  queryName爲缺省 返回數據list<map>
		object = modelExecutor.queryList(context, "user", "listAll"); //modelName=user  queryName爲listAll
		object = modelExecutor.queryList(context, "user", "listAll", User.class); //modelName=user  queryName爲listAll 返回List<User>
		
		object = modelExecutor.queryOne(context, "user", "listAll"); //modelName=user  queryName爲listAll 返回 Map
		object = modelExecutor.queryOne(context, "user", "listAll", User.class); //modelName=user  queryName爲listAll 返回 User
		
		object = modelExecutor.query(context, "user", "listAll"); //modelName=user  queryName爲listAll 返回QueryResponseObejct帶總行數
		object = modelExecutor.query(context, "user", "listAll", User.class); //modelName=user  queryName爲listAll 返回QueryResponseObejct<User>帶總行數
		
		return object;
	}	
	@Transactional
	public void save(Context context) {
		modelExecutor.execute(context, "user", null); //modelName=user  executeName爲缺省
		modelExecutor.execute(context, "user", "update"); //modelName=user  executeName爲update
		
		//context保存userlist到param.userList; context.setParamData("userList", list);
		modelExecutor.batchExecute(context, "user", "update","param.userList");  //modelName=user  executeName爲update 數據執行路徑爲param.userList
	}

}


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