去oracle行動
最近公司要發展海外項目,所以要將現有的系統全部平移過去,另外數據庫也要從原來的oracle變為mysql。公司的數據庫交互層面使用的是mybatis,而oracle與mysql也有一些語法上的不同。所以在項目中的sql要改動,但是多個項目中涉及到的sql非常多,如果僅憑人工一條一條辨別的話,工作量有點大。所以就萌發出了直接將數據源變為mysql,利用反射批量執行mapper中的方法,然后如果有參數的話,就設置為默認的初始值,然后記錄下來成功的數據和失敗的數據,這樣就可以根據失敗原因進行修改。
能夠節省很大的時間。
執行效果
代碼介紹
總體思路就三步
- 通過反射獲得要執行的mapper類的所有方法
- 獲得方法中的參數,并賦值
- 執行
1
2
|
autotestmapper autotestmapper = new autotestmapper( "存放mapper全路徑名" ); autotestmapper.opensqlsession(sqlsessionfactory); |
在構造函數中傳入全路徑名后,進行解析,解析出包名和所有的文件名并存儲起來
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public autotestmapper(string path) throws ioexception, classnotfoundexception { string mappercontent = getfilecontent(path); string pathpattern = "import [a-z,a-z,/.]+;" ; string[] patharr = matchmethod(pathpattern, mappercontent).split( ";" ); for ( int i = 0 ; i < patharr.length; i++) { patharr[i] = patharr[i].replaceall( "import " , "" ); class cls = class .forname(patharr[i]); if (!cls.isinterface()) { type_array.add(cls); } } //獲得全路徑名的前綴 string packpattern = "package [a-z,a-z,/.]+;" ; string[] packpatharr = matchmethod(packpattern, mappercontent).split( ";" ); string packpath = packpatharr[ 0 ].replaceall( "package " , "" ).replaceall( ";" , "" ); this .pack_path = packpath; } |
然后調用opensqlsession的方法,傳入sqlsessionfactory參數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
list<map< class , object>> list = new arraylist<>(); list<string> invokesuccess = new arraylist<>(); list<string> invokefail = new arraylist<>(); for (string filename : file_name) { class cls = class .forname(pack_path + "." + filename); //添加mapper if (!sqlsessionfactory.getconfiguration().hasmapper(cls)){ sqlsessionfactory.getconfiguration().addmapper(cls); } //獲得mapper object mapper = sqlsessionfactory.opensession().getmapper(cls); //反射執行mapper的方法 map<string, list<string>> resultmap = autotestinvoke(cls, mapper); invokesuccess.addall(resultmap.get(success_flg)); invokefail.addall(resultmap.get(fail_flg)); } |
然后通過mybatyis提供的方法getmapper()傳入類名獲得所要mapper類。核心方法就是autotestinvoke()方法了
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
|
private map<string, list<string>> autotestinvoke( class c, object o) { method[] declaredmethods = c.getdeclaredmethods(); string filename = c.getname().substring(c.getname().lastindexof( "." )); list<string> invokesuccess = new arraylist<>(); list<string> invokefail = new arraylist<>(); map<string, list<string>> resultmap = new hashmap<>(); //給參數賦初始值 for (method method : declaredmethods) { list<object> list = new arraylist<>(); for ( class cls : method.getparametertypes()) { object par = new object(); if (type_array.contains(cls)) { if (cls.equals(string. class )) { par = "1" ; } else { try { par = cls.newinstance(); assignment(cls, par); } catch (instantiationexception e) { if (cls.isprimitive()) { cls = primitiveclazz.get(cls.getname()); } try { par = cls.getdeclaredconstructor(string. class ).newinstance( "1" ); } catch (nosuchmethodexception e1){ system.out.println(cls.getname()+e); } } } } else if ( "java.util.map" .equals(cls.getname())){ par = getmapdata(c.getname()+ "." +method.getname()); } list.add(par); } try { method.invoke(o, list.toarray()); invokesuccess.add( "success: " + filename + "." + method.getname()); } catch (exception e) { invokefail.add( "error:" + method.getname() + " error info:" + e); } } resultmap.put(success_flg, invokesuccess); resultmap.put(fail_flg, invokefail); return resultmap; } |
這里面完成為參數賦初始值,和執行的邏輯。
使用說明
導入jar包
maven
1
2
3
4
5
|
<dependency> <groupid>com.github.modouxiansheng</groupid> <artifactid>convenientutil</artifactid> <version> 1.3 -release</version> </dependency> |
gradle
1
|
compile 'com.github.modouxiansheng:convenientutil:1.1-release' |
創建mybatis-config.xml文件
在項目的resource文件夾下創建mybatis-config.xml文件,里面內容如下,里面value值為想要測的數據庫的連接信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!doctype configuration public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <environments default = "dev" > <environment id= "dev" > <transactionmanager type= "jdbc" ></transactionmanager> <datasource type= "unpooled" > <property name= "driver" value= "" /> <property name= "url" value= "" /> <property name= "username" value= "" /> <property name= "password" value= "" /> </datasource> </environment> </environments> </configuration> |
在測試類中編寫代碼
在測試類中編寫如下代碼
1
2
3
4
5
|
reader resourceasreader = resources.getresourceasreader( "mybatis-config.xml" ); sqlsessionfactory sqlsessionfactory = new sqlsessionfactorybuilder().build(resourceasreader); resourceasreader.close(); autotestmapper autotestmapper = new autotestmapper( "想要測試的mapper文件夾全路徑名" ); autotestmapper.opensqlsession(sqlsessionfactory); |
查看輸出的信息
然后會打印出執行成功的sql,執行失敗的sql。如果失敗的話會有原因。
success: tsessetmanualmapper.updateflgdelautointimepay
success: tsessetmanualmapper.getautosetmanualordlistcount
success: tsessetmanualmapper.updateautosetmanualord
success: tsessetmanualmapper.queryautosetmanualorddetail
success: tsessetmanualmapper.querysetmanualordlistcount
success: shortmessagemapper.querypayinssminfo
-------------------
|error: |tsessetmanualmapper.queryautosetmanualordlist| every derived table must have its own alias|
|error: |tsessetmanualmapper.querysetmanualordlist| every derived table must have its own alias|
這樣就能夠根據錯誤信息進行更改了。
github地址:https://github.com/modouxiansheng/convenientuti
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://juejin.im/post/5c0108fdf265da613e21f997