自动加载类,自动加载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
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}
