欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何批量测试Mybatis项目中的Sql是否正确详解

程序员文章站 2024-03-04 21:31:24
去oracle行动 最近公司要发展海外项目,所以要将现有的系统全部平移过去,另外数据库也要从原来的oracle变为mysql。公司的数据库交互层面使用的是mybati...

去oracle行动

最近公司要发展海外项目,所以要将现有的系统全部平移过去,另外数据库也要从原来的oracle变为mysql。公司的数据库交互层面使用的是mybatis,而oracle与mysql也有一些语法上的不同。所以在项目中的sql要改动,但是多个项目中涉及到的sql非常多,如果仅凭人工一条一条辨别的话,工作量有点大。所以就萌发出了直接将数据源变为mysql,利用反射批量执行mapper中的方法,然后如果有参数的话,就设置为默认的初始值,然后记录下来成功的数据和失败的数据,这样就可以根据失败原因进行修改。

能够节省很大的时间。

执行效果

如何批量测试Mybatis项目中的Sql是否正确详解

代码介绍

总体思路就三步

  • 通过反射获得要执行的mapper类的所有方法
  • 获得方法中的参数,并赋值
  • 执行
autotestmapper autotestmapper = new autotestmapper("存放mapper全路径名");
autotestmapper.opensqlsession(sqlsessionfactory);

在构造函数中传入全路径名后,进行解析,解析出包名和所有的文件名并存储起来

 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参数

 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()方法了

 	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

<dependency>
 <groupid>com.github.modouxiansheng</groupid>
 <artifactid>convenientutil</artifactid>
 <version>1.3-release</version>
</dependency>

gradle

compile 'com.github.modouxiansheng:convenientutil:1.1-release'

创建mybatis-config.xml文件

在项目的resource文件夹下创建mybatis-config.xml文件,里面内容如下,里面value值为想要测的数据库的连接信息

<!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>

在测试类中编写代码

在测试类中编写如下代码

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/convenientutil (本地下载

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。