中式Dao開源框架(MicroDao)





MicroDao爲了解決mybatis固有缺陷,進行全新封裝的dao框架,功能覆蓋mybatis,且比mybatis更靈活。

開源地址

https://github.com/jeffreyning/MicroDao



MicroDao相對mybatis的優點:
1,sql腳本支持修改後熱部署實時生效。
2,bean與數據庫字段映射關係,通過註解設置到bean中,不必在sql腳本中體現。
3,sql腳本支持類似jsp的寫法,且不必區分select、update使用不同標籤,更加靈活。
4,不需要使用插件,內置支持物理分頁。
5,不需要使用插件,內置支持針對bean的標準增刪改查功能。
6,不需要使用插件,內置支持讀寫分離,分庫分表。
7,針對mysql5.7支持動態字段。


支持mapper、template、非orm三種模式支撐業務系統
1,mapper指,通過掃描接口,運行時自動生成dao實例;
2,template指,通過繼承template標準父類,生成dao子類;
3,非orm指,直接使用microDao實例,可以執行非orm更靈活的數據庫操作。


*mapper模式技術說明*


1,編寫實體bean
使用@MicroTableName註解說明對應的表名稱
使用@MicroMappingAnno註解說明對應的字段名稱


```
package com.github.jeffreyning.test.dto;
import com.nh.micro.orm.MicroMappingAnno;
import com.nh.micro.orm.MicroTableName;


@MicroTableName(name="micro_test")
public class MicroTest {
@MicroMappingAnno(name="id")
private String id;

@MicroMappingAnno(name="meta_key")
private String metaKey;

@MicroMappingAnno(name="meta_name")
private String metaName;

@MicroMappingAnno(name="meta_type")
private String metaType;


public String getId() {
return id;
}


public void setId(String id) {
this.id = id;
}


public String getMetaKey() {
return metaKey;
}


public void setMetaKey(String metaKey) {
this.metaKey = metaKey;
}


public String getMetaName() {
return metaName;
}


public void setMetaName(String metaName) {
this.metaName = metaName;
}


public String getMetaType() {
return metaType;
}


public void setMetaType(String metaType) {
this.metaType = metaType;
}
}
```


2,編寫dao層接口


通過繼承MicroCommonMapper<T>實現對實體bean(在泛型中設置)的標準增刪改查功能
接口的方法名如updateInfoByNhs會映射爲sql腳本中段落名稱
接口參數個數和類型均無限制


關於結果映射:
查詢單條記錄是,如果接口設置的返回值爲實體bean則,則自動進行映射。
接口返回值如果是list,可以用@ListInnerClass註解設置list中實體類,不設置則按照list<Map>返回


關於分頁:
分頁的頁數每頁的記錄數,查詢出總記錄數,均通過DefaultPageInfo對象帶入帶出。
使用mapper模式時接口方法中帶有DefaultPageInfo對象時自動進行分頁處理。


關於插入時自增id返回:
使用MicroCommonMapper通用插入方法時,通過實體bean帶回自增id。
使用sql時,通過IdHolder對象帶出自增id。使用mapper模式時接口方法中傳入IdHolder按照自增id處理。


```
package com.github.jeffreyning.test.dao;
import java.util.List;
import java.util.Map;
import com.github.jeffreyning.test.dto.MicroTest;
import com.nh.micro.dao.mapper.ListInnerClass;
import com.nh.micro.dao.mapper.MicroCommonMapper;
import com.nh.micro.orm.MicroDbName;
import com.nh.micro.template.IdHolder;


public interface TestRep extends MicroCommonMapper<MicroTest>  {

public int updateInfoByNhs(MicroTest microTest);

public int insertInfoByNhs(Map paramMap, IdHolder idHolder);

@ListInnerClass(name=MicroTest.class)
public List queryInfoByUserName(String name);


public List queryInfoByUserAge(Map paramMap);
}
```


3,編寫sql腳本
腳本文件爲txt格式但必須以.nhs作爲文件名後綴(如:TestRep.nhs)
設置段落<%! <sql id="xxxx"> %> xxxxxxxx <%! </sql> %>
段落id需與接口方法名相同。
段落不區分select還是update,統一用sql標識。
邏輯判斷部分類似jsp用<% some script %>表示
與mybatis一樣參數值使用#{} ${}兩種方式引用
應用時必須以paramArray開始,paramArray是一個數組與接口參數數據對應。
set字符拼接時,首個逗號會在框架內部自動刪除,不需要做額外處理。


```
/* 查詢 */
<%! <sql id="queryInfoByUserName"> %>
select * from micro_test t left join micro_user u on  t.user_id=u.user_id where 1=1 
<% if(paramArray[0]!=null){ %>
and u.user_name like '%${paramArray[0]}%'
<% } %>
<%! </sql> %>


<%! <sql id="queryInfoByUserAge"> %>
select * from micro_test t left join micro_user u on  t.user_id=u.user_id where 1=1 
<% if(paramArray[0].get("user_age")!=null){ %>
and u.user_age >= #{paramArray[0].user_age}
<% } %>
<%! </sql> %>


/* 插入 */
<%! <sql id="insertInfoByNhs"> %>
insert into micro_test(id,meta_key) values( 
#{paramArray[0].id},#{paramArray[0].meta_key}
)
<%! </sql> %>
 
 
/* 更新 */ 
<%! <sql id="updateInfoByNhs"> %>
update micro_test set  

<% if(paramArray[0].metaKey!=null){%>
,meta_key=#{paramArray[0].metaKey}
<% } %>
<% if(paramArray[0].metaName!=null){%>
,meta_name=#{paramArray[0].metaName}
<% } %>


where id=#{paramArray[0].getId()}
<%! </sql> %>
```


4,在spring中配置掃描sql腳本和接口
配置NhsInitUtil用來加載sql腳本,其中rulePath是腳本根目錄路徑。
配置BeanScannerConfigurer用來加載mapper接口,其中scanPath是接口根目錄路徑.
MicroDao內部需要使用jdbctemplate。
配置microDbHolder是MicroDao內部用來設置並在讀寫分離時切換多個數據源(jdbctemplate)的機制,至少配置一個default數據源。




```
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="jdbc:mysql://localhost:3306/test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>


    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name = "dataSource" ref="dataSource"/>
    </bean>
    
    <bean id="microDbHolder" class="com.nh.micro.db.MicroDbHolder" lazy-init="false">
        <property name="dbHolder">
            <map>
                <entry>
                    <key>
                        <value>default</value>
                    </key>
                    <ref bean="jdbcTemplate"></ref></entry>
            </map>
        </property>
    </bean> 


      
<bean class="com.nh.micro.nhs.NhsInitUtil" init-method="initGroovyAndThread" lazy-init="false">
<property name="fileList">
<list>
<bean class="com.nh.micro.rule.engine.core.GFileBean">
<property name="ruleStamp" value="true"></property>
<property name="jarFileFlag" value="true"></property>
<property name="dirFlag" value="true"></property>
<property name="rulePath" value="/groovy/"></property>
</bean>
</list>
</property>
</bean>
<bean class="com.nh.micro.dao.mapper.scan.BeanScannerConfigurer">
<property name="scanPath" value="com.github.jeffreyning.test.dao"></property>
</bean>          
```


5,使用mapper出的dao實例操作數據庫


```
package com.github.jeffreyning.test;


import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


import com.github.jeffreyning.test.dao.TestRep;
import com.github.jeffreyning.test.dto.MicroTest;
import com.nh.micro.dao.mapper.DefaultPageInfo;
import com.nh.micro.dao.mapper.MicroPageInfo;
import com.nh.micro.template.IdHolder;


public class TestMicroDao {


/**
* @param args
* @throws Exception 
*/
public static void main(String[] args) throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
TestRep testRep=(TestRep) ac.getBean("testRep");


/*根據實體bean 創建*/
MicroTest microTest=new MicroTest();
microTest.setMetaKey("t1");
microTest.setMetaName("test1");
testRep.createInfoMapper(microTest);
String id=microTest.getId();

/*根據實體bean的example 分頁查詢*/
DefaultPageInfo pageInfo=new DefaultPageInfo();
List list=testRep.getInfoList4PageMapper(null, pageInfo);
Long total=pageInfo.getTotal();
System.out.println(list.toString());
System.out.println("total="+total);

/*根據實體bean的example 查詢*/
List alllist=testRep.getInfoListAllMapper(null, "");
System.out.println(alllist.toString());

/*根據實體bean的Id 查詢*/
MicroTest tempBean=testRep.getInfoByIdMapper(id);
System.out.println(tempBean.toString());

/*根據實體bean 更新記錄*/
tempBean.setMetaName("test12");
testRep.updateInfoMapper(tempBean);

/*根據實體bean的id 刪除記錄*/
testRep.delInfoByIdMapper(id);

/*根據sql 插入*/
Map paramMap=new HashMap();
paramMap.put("meta_key", "test123");
paramMap.put("meta_name", "123");
IdHolder idHolder=new IdHolder();
testRep.insertInfoByNhs(paramMap,idHolder);
Object idObj=idHolder.getIdVal();
System.out.println("id="+idObj.toString());

/*根據sql 更新*/
MicroTest bean1=new MicroTest();
bean1.setId(idObj.toString());
bean1.setMetaName("new name");
testRep.updateInfoByNhs(bean1);

/*根據sql 聯合查詢*/
String name="tom";
List list2=testRep.queryInfoByUserName(name);
System.out.println(list2.toString());

/*根據sql 聯合查詢*/
Map pMap=new HashMap();
pMap.put("user_age", 20);
List list3=testRep.queryInfoByUserAge(pMap);
System.out.println(list3.toString());


}


}
```






*template模式技術說明*
通過繼承MicroMapperTemplate<T>實現針對實體bean的增刪改查操作和sql操作




```
package com.github.jeffreyning.test.temp;


import com.github.jeffreyning.test.dto.MicroTest;
import com.nh.micro.dao.mapper.MicroMapperTemplate;


public class demoDao extends MicroMapperTemplate<MicroTest> {
public MicroTest getInfo(String id) throws Exception {
return getInfoByIdMapper(id);
}
}
```

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