自己实现Mybatis底层机制-02
7.任务阶段4&5
阶段4任务:开发Mapper接口和Mapper.xml
阶段5任务:开发和Mapper接口相映射的MapperBean
(1)Mapper接口
package com.li.mapper;
import com.li.entity.Monster;
/**
* @author 李
* @version 1.0
* MonsterMapper:声明对数据库的crud方法
*/
public interface MonsterMapper {
//查询方法
public Monster getMonsterById(Integer id);
}
(2)Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="com.li.mapper.MonsterMapper">
<!--实现配置接口方法getMonsterById-->
<select id="getMonsterById" resultType="com.li.entity.Monster">
select * from monster where id = ?
</select>
</mapper>
(3)Function.java,用于记录Mapper.xml文件实现的方法信息
package com.li.limybatis.config;
import lombok.Getter;
import lombok.Setter;
/**
* @author 李
* @version 1.0
* Function:记录对应 Mapper.xml的方法信息
*/
@Getter
@Setter
@ToString
public class Function {
private String sqlType;//sql类型,如select,update,insert,delete
private String funcName;//方法名
private String sql;//执行的sql语句
private Object resultType;//返回类型
private String parameterType;//参数类型
}
(4)MapperBean.java,作用是读取Mapper接口对应的Mapper.xml,将该xml文件方法信息封装到MapperBean中。
package com.li.limybatis.config;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* @author 李
* @version 1.0
* MapperBean:将我们的Mapper信息,进行封装
*/
@Setter
@Getter
@ToString
public class MapperBean {
private String interfaceName;//接口名
//接口下的所有方法
public List<Function> functions;
}
8.任务阶段6
阶段6任务:在MyConfiguration中读取xxMapper.xml,能够创建MapperBean对象
(1)修改 MyConfiguration.java,添加 readMapper() 方法
/**
* 读取xxMapper.xml,创建MapperBean对象
* @param path xml的路径+文件名,从类的加载路径开始计算,若xml文件放在resource目录下,直接传入文件名即可
* @return 返回MapperBean对象
*/
public MapperBean readMapper(String path) {
MapperBean mapperBean = new MapperBean();
try {
//获取到mapper.xml文件对应的InputStream
InputStream stream = loader.getResourceAsStream(path);
SAXReader reader = new SAXReader();
//获取到xml文件对应的document
Document document = reader.read(stream);
//得到xml的根节点
Element root = document.getRootElement();
//获取到 namespace
String namespace = root.attributeva lue("namespace").trim();
//设置mapperBean的属性interfaceName
mapperBean.setInterfaceName(namespace);
//遍历获取root的子节点-生成 Function
Iterator rootIterator = root.elementIterator();
//保存接口下的所有方法信息
List<Function> list = new ArrayList<>();
while (rootIterator.hasNext()) {
//取出一个子元素
/**
* <select id="getMonsterById" resultType="com.li.entity.Monster">
* select * from monster where id = ?
* </select>
*/
Element e = (Element) rootIterator.next();
Function function = new Function();
String sqlType = e.getName().trim();
String funcName = e.attributeva lue("id").trim();
//这里的resultType是返回类型的全路径-全类名
String resultType = e.attributeva lue("resultType").trim();
String sql = e.getText().trim();
//将信息封装到 function对象中
function.setSql(sql);
function.setFuncName(funcName);
function.setSqlType(sqlType);
//这里的function.resultType应该为Object类型
//因此使用反射生成对象,再放入function中
Object instance = Class.forName(resultType).newInstance();
function.setResultType(instance);
//将封装好的function对象放到list中
list.add(function);
}