mybatis全局配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 -->
<mappers>
<mapper resource="EmployeeMapper.xml" />
</mappers>
</configuration>
mapper映射文件EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">
<!--
namespace:名称空间;指定为接口的全类名
id:唯一标识
resultType:返回值类型
#{id}:从传递过来的参数中取出id值
-->
<select id="getEmpById" resultType="com.atguigu.mybatis.bean.Employee">
select id,last_name lastName,email,gender from tbl_employee where id = #{id}
</select>
</mapper>
测试方法:
/**
* 1、获取sqlSessionFactory对象
* 解析文件的每一个信息保存在Configuration中,然后返回包含Configuration的DefaultSqlSession。
* MappedStatement:代表一个增删改查的详细信息。
* 2、获取sqlSession对象
* 返回一个SqlSession 的实现类DefaultSqlSession对象。
* 这一步会创建Executor 对象。
* 3、获取接口的代理对象(MapperProxy)
* getMapper,使用MapperProxyFactory创建一个MapperProxy的代理对象。
* 代理对象里面包含了,DefaultSqlSession(Executor )
* 4、执行增删改查方法
* @throws IOException
*/
@Test
public void test() throws IOException {
//1、获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、获取sqlSession对象
SqlSession openSession = sqlSessionFactory.openSession();
try {
//3、获取接口的代理对象
//会为接口自动创建一个代理对象,代理对象去执行增删改查方法
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
//4、执行增删改查方法
Employee employee = mapper.getEmpById(1);
System.out.println(mapper);
System.out.println(employee);
} finally {
openSession.close();
}
}
源码解析:
三、获取到接口的代理对象
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
1、DefaultSqlSession
public <T> T getMapper(Class<T> type) {
return this.configuration.getMapper(type, this);
}
2、Configuration
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return this.mapperRegistry.getMapper(type, sqlSession);
}
3、MapperRegistry
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
//获取Mapper的代理工厂MapperProxyFactory
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
//传入sqlSession创建一个MapperProxy
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
4、MapperProxyFactory
//根据传入的MapperProxy创建一个MapperProxy的代理对象
protected T newInstance(MapperProxy<T> mapperProxy) {
return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
return this.newInstance(mapperProxy);
}
5、MapperProxy
//MapperProxy实现了InvocationHandler。InvocationHandler是Jdk用来创建动态代理的
public class MapperProxy<T> implements InvocationHandler, Serializable {
private static final long serialVersionUID = -6424540398559729838L;
private final SqlSession sqlSession;
private final Class<T> mapperInterface;
private final Map<Method, MapperMethod> methodCache;
public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
this.sqlSession = sqlSession;
this.mapperInterface = mapperInterface;
this.methodCache = methodCache;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
try {
return method.invoke(this, args);
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
} else {
MapperMethod mapperMethod = this.cachedMapperMethod(method);
return mapperMethod.execute(this.sqlSession, args);
}
}
private MapperMethod cachedMapperMethod(Method method) {
MapperMethod mapperMethod = (MapperMethod)this.methodCache.get(method);
if (mapperMethod == null) {
mapperMethod = new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());
this.methodCache.put(method, mapperMethod);
}
return mapperMethod;
}
}