MyBatis xml檔案動態生成物件,網上找的自己進行了優化。
主要針對動態分頁查詢,因為日常中查詢,可以利用其實現動態分頁操作,實現所有的select都能夠動態生成以此基礎。
{******************************方法應用******************************************************************************************************
org.apache.ibatis.session.Configuration config = new Configuration();
String mapps="是xml檔案讀取字串!";
org.apache.ibatis.session.SqlSessionFactory sqlSessionFactory = SqlSessionCache.createSqlSessionFactory(config, mapps);
Map params="map引數集合!";
javax.sql.DataSource dataSource=“資料來源”;
java.sql.Connection newconn=dataSource.getConnection();
org.apache.ibatis.session.SqlSession session = sqlSessionFactory.openSession(newconn);
session.clearCache();
Class type=MbatisDao.class;
//介面要與xml @DAO_INTERFACE保持一致
//<mapper namespace="@DAO_INTERFACE">
MbatisDao um= session.getMapper(type);
//findPageTotal 方法在介面和xml,id中要有對應 否則呼叫報錯
long total = um.findPageTotal(params);
session.close();
******************************方法應用******************************************************************************************************}
package com.*****.service.sys.jdbcApi.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
public class SqlSessionCache {
private static Logger log = Logger.getLogger(SqlSessionCache.class);
private SqlSessionFactory sqlSessionFactory;
private Resource[] mapperLocations;
private String packageSearchPath;
private HashMap<String, Long> fileMapping = new HashMap<String, Long>();// 記錄檔案是否變化
public void refreshMapper() {
try {
Configuration configuration =null;
if(this.sqlSessionFactory!=null){
configuration = this.sqlSessionFactory.getConfiguration();
}
// step.1 掃描檔案
try {
this.scanMapperXml();
} catch (IOException e) {
log.error("packageSearchPath掃描包路徑配置錯誤");
return;
}
log.debug("==============重新整理前mapper中的內容===============");
if(configuration!=null){
for (String name : configuration.getMappedStatementNames()) {
System.out.println(name);
}
}
// step.2 判斷是否有檔案發生了變化
if (this.isChanged()) {
// step.2.1 清理
this.removeConfig(configuration);
// step.2.2 重新載入
for (Resource configLocation : mapperLocations) {
try {
Map<String, XNode> sqlFragments =configuration.getSqlFragments();
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(
configLocation.getInputStream(), //記憶體級動態SQL實現就是將該流實現動態載入
configuration,//將configuration 就是通過XMLMapperBuilder完善所有項 使用特性引用傳值
configLocation.toString(),//就是為了配置鍵值對存在的,可以試試路徑方式實現
sqlFragments);
xmlMapperBuilder.parse();
log.debug("mapper檔案[" + configLocation.getFilename()+ "]快取載入成功");
} catch (IOException e) {
log.error("mapper檔案[" + configLocation.getFilename()+ "]不存在或內容格式不對");
continue;
}catch (Exception e) {
e.printStackTrace();
}
}
}
log.debug("==============重新整理後mapper中的內容===============");
if(configuration!=null){
for (String name : configuration.getMappedStatementNames()) {
System.out.println(name);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setPackageSearchPath(String packageSearchPath) {
this.packageSearchPath = packageSearchPath;
}
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* 掃描xml檔案所在的路徑
*
* @throws IOException
*/
private void scanMapperXml() throws IOException {
this.mapperLocations = new PathMatchingResourcePatternResolver().getResources(packageSearchPath);
}
/**
* 清空Configuration中幾個重要的快取
*
* @param configuration
* @throws Exception
*/
private static void removeConfig(Configuration configuration) throws Exception {
if(configuration!=null){
Class<?> classConfig = configuration.getClass();
clearMap(classConfig, configuration, "mappedStatements");
clearMap(classConfig, configuration, "caches");
clearMap(classConfig, configuration, "resultMaps");
clearMap(classConfig, configuration, "parameterMaps");
clearMap(classConfig, configuration, "keyGenerators");
clearMap(classConfig, configuration, "sqlFragments");
clearSet(classConfig, configuration, "loadedResources");
}else{
configuration=new Configuration();
}
}
@SuppressWarnings("rawtypes")
private static void clearMap(Class<?> classConfig, Configuration configuration,
String fieldName) throws Exception {
Field field = classConfig.getDeclaredField(fieldName);
field.setAccessible(true);
Map mapConfig = (Map) field.get(configuration);
if(mapConfig!=null && mapConfig.size()>0){
mapConfig.clear();
}
}
@SuppressWarnings("rawtypes")
private static void clearSet(Class<?> classConfig, Configuration configuration,
String fieldName) throws Exception {
Field field = classConfig.getDeclaredField(fieldName);
field.setAccessible(true);
Set setConfig = (Set) field.get(configuration);
if(setConfig!=null && setConfig.size()>0){
setConfig.clear();
}
}
/**
* 判斷檔案是否發生了變化
*
* @param resource
* @return
* @throws IOException
*/
private boolean isChanged() throws IOException {
boolean flag = false;
for (Resource resource : mapperLocations) {
String resourceName = resource.getFilename();
boolean addFlag = !fileMapping.containsKey(resourceName);// 此為新增標識
// 修改檔案:判斷檔案內容是否有變化
Long compareFrame = fileMapping.get(resourceName);
long lastFrame = resource.contentLength() + resource.lastModified();
boolean modifyFlag = null != compareFrame
&& compareFrame.longValue() != lastFrame;// 此為修改標識
// 新增或是修改時,儲存檔案
if (addFlag || modifyFlag) {
fileMapping.put(resourceName, Long.valueOf(lastFrame));// 檔案內容幀值
flag = true;
}
}
return flag;
}
/**
* 封裝XMLMapperBuilder動態載入(xml)建立MyBatis SqlSessionFactory
* @param mapps
* @return
*/
public static SqlSessionFactory createSqlSessionFactory(String mapps){
//第一步:實現檔案級動態SQL載入通用底層
//第二步:實現記憶體級動態SQL載入通用底層
//需要重寫mybatis相關類
/** 動態載入就是將一下的這段程式碼替換 ---stat---------
SqlSessionCache sc=new SqlSessionCache();
String pxml="com/*****/service/sys/jdbcApi/impl/MbatisDao.xml";
sc.setPackageSearchPath(pxml);
sc.setSqlSessionFactory(sessionMyBatis);
//重新載入myBatis查詢方法
sc.refreshMapper();
動態載入就是將一下的這段程式碼替換 ---end-------- */
SqlSessionFactory sessionMyBatis=null;
try{
log.debug("==============載入xml字串後 建立Factory,裝在XMLMapper===============");
String pxml="";//com/*****/service/sys/jdbcApi/impl/MbatisDao.xml
Configuration config=new Configuration();
InputStream inputStream=new ByteArrayInputStream(mapps.getBytes("UTF-8"));
sessionMyBatis=new SqlSessionFactoryBuilder().build(config);
config = sessionMyBatis.getConfiguration();
removeConfig(config);
Map<String, XNode> sqlFragments =config.getSqlFragments();
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(
inputStream,//configLocation.getInputStream(), //記憶體級動態SQL實現就是將該流實現動態載入
config,//將configuration 就是通過XMLMapperBuilder完善所有項 使用特性引用傳值
pxml,//configLocation.toString(),//就是為了配置鍵值對存在的,可以試試路徑方式實現
sqlFragments);
xmlMapperBuilder.parse();
log.debug("==============載入xml字串後 mapper中的內容資料【輸出開始】===============");
if(config!=null){
for (String name : config.getMappedStatementNames()) {
log.debug("=============>>"+name);
}
}
log.debug("==============載入xml字串後 mapper中的內容資料【輸出結束】===============");
}catch (Exception ex) {
ex.printStackTrace();
}
return sessionMyBatis;
}
/**
* 封裝XMLMapperBuilder動態載入(xml)建立MyBatis SqlSessionFactory
* @param config
* @param mapps
* @return
*/
public static SqlSessionFactory createSqlSessionFactory(Configuration config,String mapps){
//第一步:實現檔案級動態SQL載入通用底層
//第二步:實現記憶體級動態SQL載入通用底層
//需要重寫mybatis相關類
/** 動態載入就是將一下的這段程式碼替換 ---stat---------
SqlSessionCache sc=new SqlSessionCache();
String pxml="com/*****/service/sys/jdbcApi/impl/MbatisDao.xml";
sc.setPackageSearchPath(pxml);
sc.setSqlSessionFactory(sessionMyBatis);
//重新載入myBatis查詢方法
sc.refreshMapper();
動態載入就是將一下的這段程式碼替換 ---end-------- */
SqlSessionFactory sessionMyBatis=null;
try{
log.debug("==============載入xml字串後 建立Factory,裝在XMLMapper===============");
String pxml="";//com/*****/service/sys/jdbcApi/impl/MbatisDao.xml
InputStream inputStream=new ByteArrayInputStream(mapps.getBytes("UTF-8"));
sessionMyBatis=new SqlSessionFactoryBuilder().build(config);
config = sessionMyBatis.getConfiguration();
removeConfig(config);
Map<String, XNode> sqlFragments =config.getSqlFragments();
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(
inputStream,//configLocation.getInputStream(), //記憶體級動態SQL實現就是將該流實現動態載入
config,//將configuration 就是通過XMLMapperBuilder完善所有項 使用特性引用傳值
pxml,//configLocation.toString(),//就是為了配置鍵值對存在的,可以試試路徑方式實現
sqlFragments);
xmlMapperBuilder.parse();
log.debug("==============載入xml字串後 mapper中的內容資料【輸出開始】===============");
if(config!=null){
for (String name : config.getMappedStatementNames()) {
log.debug("=============>>"+name);
}
}
log.debug("==============載入xml字串後 mapper中的內容資料【輸出結束】===============");
}catch (Exception ex) {
ex.printStackTrace();
log.error("XML異常配置:"+mapps);
}
return sessionMyBatis;
}
/**
* 封裝XMLMapperBuilder動態載入(xml)建立MyBatis SqlSessionFactory
* @param mapps
* @return
*/
public static SqlSessionFactory createSqlSessionFactory(InputStream inputStream){
SqlSessionFactory sessionMyBatis=null;
try{
log.debug("==============載入xml字串後 建立Factory,裝在XMLMapper===============");
String pxml="";//com/*****/service/sys/jdbcApi/impl/MbatisDao.xml
Configuration config=new Configuration();
//InputStream inputStream=new ByteArrayInputStream(mapps.getBytes("UTF-8"));
sessionMyBatis=new SqlSessionFactoryBuilder().build(config);
config = sessionMyBatis.getConfiguration();
removeConfig(config);
Map<String, XNode> sqlFragments =config.getSqlFragments();
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(
inputStream,//configLocation.getInputStream(), //記憶體級動態SQL實現就是將該流實現動態載入
config,//就是將configuration 通過XMLMapperBuilder完善所有項 使用特性引用傳值
pxml,//configLocation.toString(),//就是為了配置鍵值對存在的,可以試試路徑方式實現
sqlFragments);
xmlMapperBuilder.parse();
log.debug("==============載入xml字串後 mapper中的內容資料【輸出開始】===============");
if(config!=null){
for (String name : config.getMappedStatementNames()) {
log.debug("=============>>"+name);
}
}
log.debug("==============載入xml字串後 mapper中的內容資料【輸出結束】===============");
}catch (Exception ex) {
ex.printStackTrace();
}
return sessionMyBatis;
}
/**
* 封裝XMLMapperBuilder動態載入(xml)建立MyBatis SqlSessionFactory
* @param mapps
* @return
*/
public static SqlSessionFactory createSqlSessionFactory(Resource configLocation){
SqlSessionFactory sessionMyBatis=null;
try{
log.debug("==============載入xml字串後 建立Factory,裝在XMLMapper===============");
String pxml="";//com/*****/service/sys/jdbcApi/impl/MbatisDao.xml
Configuration config=new Configuration();
//InputStream inputStream=new ByteArrayInputStream(mapps.getBytes("UTF-8"));
sessionMyBatis=new SqlSessionFactoryBuilder().build(config);
config = sessionMyBatis.getConfiguration();
removeConfig(config);
Map<String, XNode> sqlFragments =config.getSqlFragments();
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(
configLocation.getInputStream(), //記憶體級動態SQL實現就是將該流實現動態載入
config,//就是將configuration 通過XMLMapperBuilder完善所有項 使用特性引用傳值
configLocation.toString(),//就是為了配置鍵值對存在的,可以試試路徑方式實現
sqlFragments);
xmlMapperBuilder.parse();
log.debug("==============載入xml字串後 mapper中的內容資料【輸出開始】===============");
if(config!=null){
for (String name : config.getMappedStatementNames()) {
log.debug("=============>>"+name);
}
}
log.debug("==============載入xml字串後 mapper中的內容資料【輸出結束】===============");
}catch (Exception ex) {
ex.printStackTrace();
}
return sessionMyBatis;
}
/**
* 掃描xml檔案所在的路徑
* @param packageSearchPath
* @throws IOException
*/
public static String scanMapperXml(String packageSearchPath) throws IOException {
String mappr =null;
Resource[] mapperLocations = new PathMatchingResourcePatternResolver().getResources(packageSearchPath);
for (Resource configLocation : mapperLocations) {
InputStream in = configLocation.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i=-1;
while((i=in.read())!=-1){
baos.write(i);
}
mappr = baos.toString();
}
return mappr;
}
}