去年、以下を書いたけれど、、
XMLMapperBuilder を使ってみる。 - Oboe吹きプログラマの黙示録
Java インターフェースクラスで書く Mapper の指定になってしまっている。
クラスローダーが読み込める全ての classpath から、XMLを見つけて parse する方法として書いてみる。
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.session.Configuration; /** * ConfigurationTool */ public class ConfigurationTool{ public int mapperScan(Configuration config) { return findXML().stream().mapToInt(f->{ try(InputStream input = new FileInputStream(f)){ new XMLMapperBuilder(input, config, f.getAbsolutePath(), config.getSqlFragments()).parse(); return 1; }catch(Exception e){ return 0; } }).sum(); } public List<File> findXML(){ File file = new File(Thread.currentThread().getContextClassLoader().getResource("./").getPath()); return searchMapFiles(file, new ArrayList<>(), f->f.getName().endsWith(".xml")); } private List<File> searchMapFiles(File file, List<File> list, Predicate<File> p){ if (p.test(file)) list.add(file); if (file.isDirectory()){ for(File f:file.listFiles()){ searchMapFiles(f, list, p); } } return list; } }
使用例
UnpooledDataSource dataSource = new UnpooledDataSource(); dataSource.setDriver("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/testDB"); dataSource.setUsername("root"); dataSource.setPassword("passwd"); Environment environment = new Environment("deployment", new JdbcTransactionFactory(), dataSource); Configuration config = new Configuration(environment); // snake Case → camel Case config.setMapUnderscoreToCamelCase(true); ConfigurationTool tool = new ConfigurationTool(); int count = tool.mapperScan(config);
これで、Configuration config は、読込める全てのSQL Map XMLを解析する。
int count には、読み込んだXMLファイル数が返ってくる。
どんな MapperStatement が認識されたかは、Configuration を調べればよい。
// mapper 識別子 ID と mapper のリソースを確認 config.getMappedStatements().stream().forEach(m->{ System.out.println("id="+m.getId() +" "+m.getResource()); }); // mapper レジストリに格納された mapper Java インターフェースクラス名を確認 config.getMapperRegistry().getMappers().forEach(c->{ System.out.println(c.getName()); });
上の m.getResource() は、
mapper Java インターフェースクラスによるものであれば、
~.java (best guess)
XML に記述されたものであれば、
XMLファイルパス (末尾文字列が、".xml" )
のString である。
だから、SQLMap XML だけのリストをここから作るには、、
List<File> files = config.getMappedStatements().stream() .map(m->m.getResource().toString()) .filter(e->e.endsWith(".xml")) .distinct().map(p->new File(p)) .collect(Collectors.toList());
で、File の List を作れる。