当前位置 : 主页 > 编程语言 > c++ >

mybatis自动加载类,自动加载配置,自动添加映射Xml文件

来源:互联网 收集:自由互联 发布时间:2021-07-03
自动加载类,自动加载mybatis配置,自动扫描mapper.xml文件 package com.amiu.mybatisTest.autoMybatis;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import ja
自动加载类,自动加载mybatis配置,自动扫描mapper.xml文件
package com.amiu.mybatisTest.autoMybatis;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import com.amiu.PackageUtil;
import com.amiu.mybatisTest.mapper.DBTable;
import com.amiu.mybatisTest.mapper.DaoInterface;
import com.amiu.mybatisTest.mapper.Mapper;

public class MybatisInitialization {
	
	/**
	 * propertiesReader应变为1个类,专门处理properties
	 * sqlSession应变为一个类,处理事务,和close()
	 * */
	
	//默认扫描整个项目,用junit@Test会出错,不会扫描整个项目
	//详见packagePath2FilePath()中的url.path()
	private String baseScanPackage = "";
	private SqlSessionFactory sqlSessionFactory;
	//注解,标记我们的mapper类的注解
	private Class
  scanAnnotation;

	//public MybatisInitialization(){}
	
	public MybatisInitialization(Class
  annotationClazz){
		this.scanAnnotation = annotationClazz;
	}
	
	public void setBaseScanPackage(String baseScanPackage) {
		this.baseScanPackage = baseScanPackage;
	}
	
	public SqlSessionFactory getSqlSessionFactory() {
		if(sqlSessionFactory == null){
			try {
				sqlSessionFactory = load();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return sqlSessionFactory;
	}
	
	public void setAnnotationClazz(Class
  annotationClazz) {
		this.scanAnnotation = annotationClazz;
	}

	SqlSessionFactory load() throws Exception{
		Properties props = propertiesReader("com.amiu.mybatisTest","dbConfig.properties");
		String driver = props.getProperty("driver");
		String url = props.getProperty("url");
		String username = props.getProperty("username");
		String password = props.getProperty("password");

		// 获取DataSource,DataSource接口有多个实现类,我们用的是mybatis给我们提供的PooledDataSource
		PooledDataSource pooledDataSource = new PooledDataSource(driver, url,
				username, password);
		// 若需要配置pooledDatasource,则可以用他的set方法,如
		pooledDataSource.setLoginTimeout(6000);
		DataSource dataSource = pooledDataSource;

		// 配置事务管理,这里我们使用JDBC的事务
		TransactionFactory trcFactory = new JdbcTransactionFactory();

		// 配置Environment对象,"development"是我们给起的名字
		Environment env = new Environment("development", trcFactory, dataSource);
		// 创建Configuration对象
		Configuration config = new Configuration(env);
		//
 中的内容在此处配置
		//config.setLazyLoadingEnabled(true);
		
		//扫描baseScanPackage,添加mapper
		List
 
  > mapperClazzList = scanDaoMapper(baseScanPackage);
		for (Class
   mapperClazz : mapperClazzList) {
			//添加映射接口,若有xml文件,则xml的文件应和接口文件同名
			config.addMapper(mapperClazz);
		}

		SqlSessionFactory ssFactory = new SqlSessionFactoryBuilder()
				.build(config);
		return ssFactory;
	}

	private Properties propertiesReader(String packagePath,String fileName) throws IOException,
			FileNotFoundException {
		String filePath = packagePath2FilePath(packagePath);
		Properties props = new Properties();
		props.load(new FileInputStream(filePath+ File.separator +fileName));
		return props;
	}

	//包路径转换为文件绝对路径
	public String packagePath2FilePath(String packagePath) {
		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		String filePath = packagePath.replace(".", "/");
		//包路径
		URL url = loader.getResource(filePath);
		return url.getPath();
	}
	
	/**
	 * 扫描mybatis Mapper.class
	 * @param basePackage
	 * @return
	 * @throws Exception
	 */
	List
  
   > scanDaoMapper(String basePackage) throws Exception{ List
   
    > anntationClazz = new ArrayList
    
     >(); List
     
       classOfString = PackageUtil.getClassName(basePackage, true); for (String className : classOfString) { //不处理内部类,内部类className型如ClassA&ClassB if(!className.contains("&")){ Class
       clazz = Class.forName(className); //只处理接口,我们使用mybatis时,Dao全是接口 if(clazz.isInterface() && isMarkClass(clazz)){ anntationClazz.add(clazz); } } } return anntationClazz; } /** * 这个类是否是我们标记注解scanAnnotation的类 * @param clazz * @return * @throws Exception */ private boolean isMarkClass(Class
       clazz)throws Exception{ for (Annotation annotation : clazz.getAnnotations()) { if(scanAnnotation == null)throw new Exception("请添加需扫描的注解"); if(annotation.annotationType() == scanAnnotation){ return true; } } return false; } public static void main(String[] args) { MybatisInitialization init = new MybatisInitialization(Mapper.class); //可以不设置基础扫描包,默认扫描整个项目 init.setBaseScanPackage("com.amiu"); SqlSessionFactory sqlSessionFactory = init.getSqlSessionFactory(); SqlSession sqlSession = sqlSessionFactory.openSession(); DaoInterface dao = sqlSession.getMapper(DaoInterface.class); System.out.println(dao.findById(1).getName()); } }
     
    
   
  
 
PackageUtil扫描包的工具类
package com.amiu;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.amiu.mybatisTest.autoMybatis.MybatisInitialization;
import com.amiu.mybatisTest.autoMybatis.SqlSessionHelper;
import com.amiu.mybatisTest.mapper.DBTable;
import com.amiu.mybatisTest.mapper.DaoInterface;

public class PackageUtil {

	/**
	 * 获取某包下(包括该包的所有子包)所有类
	 * 
	 * @param packageName
	 *            包名
	 * @return 类的完整名称
	 */
	public static List
 
   getClassName(String packageName) {
		return getClassName(packageName, true);
	}

	/**
	 * 获取某包下所有类
	 * 
	 * @param packageName
	 *            包名
	 * @param childPackage
	 *            是否遍历子包
	 * @return 类的完整名称
	 */
	public static List
  
    getClassName(String packageName, boolean childPackage) { List
   
     fileNames = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); String packagePath = packageName.replace(".", "/"); URL url = loader.getResource(packagePath); if (url != null) { String type = url.getProtocol(); if (type.equals("file")) { fileNames = getClassNameByFile(url.getPath(), null, childPackage); } else if (type.equals("jar")) { fileNames = getClassNameByJar(url.getPath(), childPackage); } } else { fileNames = getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage); } return fileNames; } /** * 从项目文件获取某包下所有类 * * @param filePath * 文件路径 * @param className * 类名集合 * @param childPackage * 是否遍历子包 * @return 类的完整名称 */ private static List
    
      getClassNameByFile(String filePath, List
     
       className, boolean childPackage) { List
      
        myClassName = new ArrayList
       
        (); File file = new File(filePath); File[] childFiles = file.listFiles(); for (File childFile : childFiles) { if (childFile.isDirectory()) { if (childPackage) { myClassName.addAll(getClassNameByFile(childFile.getPath(), myClassName, childPackage)); } } else { String childFilePath = childFile.getPath(); if (childFilePath.endsWith(".class")) { childFilePath = childFilePath.substring( childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf(".")); childFilePath = childFilePath.replace("\\", "."); myClassName.add(childFilePath); } } } return myClassName; } /** * 从jar获取某包下所有类 * * @param jarPath * jar文件路径 * @param childPackage * 是否遍历子包 * @return 类的完整名称 */ private static List
        
          getClassNameByJar(String jarPath, boolean childPackage) { List
         
           myClassName = new ArrayList
          
           (); String[] jarInfo = jarPath.split("!"); String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/")); String packagePath = jarInfo[1].substring(1); try { JarFile jarFile = new JarFile(jarFilePath); Enumeration
           
             entrys = jarFile.entries(); while (entrys.hasMoreElements()) { JarEntry jarEntry = entrys.nextElement(); String entryName = jarEntry.getName(); if (entryName.endsWith(".class")) { if (childPackage) { if (entryName.startsWith(packagePath)) { entryName = entryName.replace("/", ".").substring( 0, entryName.lastIndexOf(".")); myClassName.add(entryName); } } else { int index = entryName.lastIndexOf("/"); String myPackagePath; if (index != -1) { myPackagePath = entryName.substring(0, index); } else { myPackagePath = entryName; } if (myPackagePath.equals(packagePath)) { entryName = entryName.replace("/", ".").substring( 0, entryName.lastIndexOf(".")); myClassName.add(entryName); } } } } } catch (Exception e) { e.printStackTrace(); } return myClassName; } /** * 从所有jar中搜索该包,并获取该包下所有类 * * @param urls * URL集合 * @param packagePath * 包路径 * @param childPackage * 是否遍历子包 * @return 类的完整名称 */ private static List
            
              getClassNameByJars(URL[] urls, String packagePath, boolean childPackage) { List
             
               myClassName = new ArrayList
              
               (); if (urls != null) { for (int i = 0; i < urls.length; i++) { URL url = urls[i]; String urlPath = url.getPath(); // 不必搜索classes文件夹 if (urlPath.endsWith("classes/")) { continue; } String jarPath = urlPath + "!/" + packagePath; myClassName.addAll(getClassNameByJar(jarPath, childPackage)); } } return myClassName; } }
              
             
            
           
          
         
        
       
      
     
    
   
  
 
@注解Mapper,用来标记我们Mybatis Xml文件映射的接口
package com.amiu.mybatisTest.mapper;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 标记我们的mapper 
 * @author amiu
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapper {
}
我们的@Mapper就添加在Dao的接口上,这个和DaoInterface.xml做映射
package com.amiu.mybatisTest.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.MapKey;

import com.amiu.TestBean;

@Mapper
public interface DaoInterface {
	public TestBean findById(long id);

	public List
 
   findByPhone(long phone);
	
	public int insert(TestBean bean);
	
	public void deleteById(long id);
	
	public void updateById(TestBean bean);

}
 
DaoInterface.xml
 



 
	
  
	
	
  
	
	
   
   
     select last_insert_id() 
    insert into test(id,name,password,phone) values(#{id},#{name},#{password},#{phone}) 
  
	
	
  
    delete from test where id=#{id} 
  
	
	
  
    update test set name=#{name},password=#{password},phone=#{phone} where id=#{id} 
   

 
网友评论