package org.nico.ourbatis.loader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.ibatis.builder.xml.XMLMapperBuilder; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSessionFactory; import org.nico.ourbatis.Ourbatis; import org.nico.ourbatis.el.Noel; import org.nico.ourbatis.el.NoelResult; import org.nico.ourbatis.entity.Table; import org.nico.ourbatis.mapping.MapperMapping; import org.nico.ourbatis.utils.ClassUtils; import org.nico.ourbatis.utils.StreamUtils; /** * We need a builder to help us implement the environment in which the processed mapper.xml * is loaded into mybatis, * @author nico * @time 2018-08-23 18:22 */ public class OurbatisLoader { private static final Log log = LogFactory.getLog(OurbatisLoader.class); /** * Template information queue */ private Map<Table, String> mappers; private MapperMapping mapper; private Noel noel; private SqlSessionFactory sqlSessionFactory; private Configuration configuration; private String baseTemplateUri; private String baseTemplateContent; private String mapperLocations; /** * Get an instance of o through which mapper can be loaded into the mybatis container * * @param sqlSessionFactory * Creates an SqlSession out of a connection or a DataSource * @param baseTemplateUri * The uri to the template, which is the relative path of the template under the classpath * @param mapperPacketUri * The path of mapper's package, example 'org.nico.ourbatis.mapper', Store the Mapper interface internally */ public OurbatisLoader(SqlSessionFactory sqlSessionFactory, String baseTemplateUri, String mapperLocations) { this.sqlSessionFactory = sqlSessionFactory; this.configuration = sqlSessionFactory.getConfiguration(); this.mappers = new LinkedHashMap<Table, String>(); this.mapper = new MapperMapping(); this.noel = new Noel(); this.baseTemplateUri = baseTemplateUri; this.mapperLocations = mapperLocations; this.baseTemplateContent = StreamUtils.convertToString(this.baseTemplateUri); log.debug("Start processing the data source session factory " + sqlSessionFactory); } /** * After a class is parsed as a template, it is added to the load queue. * When the build method is called, the template content in the queue is * loaded in turn into the Mybatis container * * @param clazz * Target class * @return This instance */ public OurbatisLoader add(Class<?> clazz) { Table entityInfo = mapper.mappingTable(clazz, mapperLocations); if(ClassUtils.forName(entityInfo.getMapperClassName()) != null) { NoelResult result = noel.el(baseTemplateContent, entityInfo); String putCallBack = mappers.putIfAbsent(entityInfo, result.getFormat()); if(putCallBack == null) { log.debug(">> Loading " + clazz.getName()); } } return this; } /** * Add all the class files under the package by scanning the package path * * @param packet * Package path * @return This instance */ public OurbatisLoader add(String packet) { try { List<Class<?>> classes = ClassUtils.getClasses(packet); if(classes != null && ! classes.isEmpty()) { classes.forEach(clazz -> { add(clazz); }); } } catch (IOException e) { e.printStackTrace(); } return this; } /** * Calling this method will load the template information from the queue into the Mybatis container in turn */ public void build() { if (!this.mappers.isEmpty()) { boolean openPrint = Ourbatis.print != null; this.mappers.forEach((entityInfo, mapper) -> { try { if (openPrint) { StreamUtils.write(Ourbatis.print, entityInfo.getDomainClassName(), ".xml", mapper); log.debug(">> Writing " + entityInfo.getDomainClassName()); } } catch (Exception arg6) { arg6.printStackTrace(); } log.debug(">> Building " + entityInfo.getDomainClassName()); ByteArrayInputStream mapperStream = new ByteArrayInputStream(mapper.getBytes()); XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperStream, this.configuration, mapperStream.toString(), this.configuration.getSqlFragments()); xmlMapperBuilder.parse(); }); } } public Map<Table, String> getMappers() { return mappers; } public void setMappers(Map<Table, String> mappers) { this.mappers = mappers; } public SqlSessionFactory getSqlSessionFactory() { return sqlSessionFactory; } public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } }