mybaits的资源定位,解析,注册实际上都和springIOC容器的初始化过程大同小易。最关键的一点就是Mapper文件的映射原理。和Hibernate不同的是mybaits只从数据库映射到pojo,是单向的。
mybaits基本原理
仿照mybaits实现最简单的mapper映射
模拟已经解析完成的xml
package eproxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MapperXML {
static final String nameSapce="eproxy.UserMapper";
static Map<String,String> map=new ConcurrentHashMap<String,String>();
static{
map.put("findById", "SELECT USERNAME,SEX,ADDRESS FROM USER WHERE ID=%d");
}
}
第一步:创建SqlSession
package eproxy;
import java.lang.reflect.Proxy;
public class MySqlSession {
private final Executor executor=new SimpleExecutor();
public <T> T selectOne(String statement, Object parameter){
return executor.query(statement, parameter);
}
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> type){
return(T)Proxy.newProxyInstance(MySqlSession.class.getClassLoader(),
new Class[]{type}, new MapperProxy<T>(type,this));
}
}
第二步:创建MyProxyMapper代理类
package eproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MapperProxy<T> implements InvocationHandler {
private final Class<T> mapperinterface;
private final MySqlSession sqlSession;
public MapperProxy(Class<T> mapperinterface, MySqlSession sqlSession) {
this.mapperinterface= mapperinterface;
this.sqlSession=sqlSession;
}
//核心代码
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getDeclaringClass().getName().equals(MapperXML.nameSapce)){
String sql = MapperXML.map.get(method.getName());
System.out.println(String.format("sql[%s],paramters[%s]", sql,args[0]));
//存在硬编码
return sqlSession.selectOne(sql, args[0]);
}else{
throw new Exception("name space is not exists");
}
}
}
第三步:创建Executor
package eproxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SimpleExecutor implements Executor {
@Override
public <T> T query(String statement, Object parameter) {
User user=null;
try {
Connection con = getConection();
PreparedStatement ps = con
.prepareStatement(String.format(statement, Integer.parseInt(parameter.toString())));
ResultSet rs = ps.executeQuery();
// 硬编码
user= new User();
while (rs.next()) {
user.setUsername(rs.getString(1));
user.setSex(rs.getString(2));
user.setAddress(rs.getString(3));
}
} catch (SQLException e) {
e.printStackTrace();
}
return (T) user;
}
private Connection getConection() throws SQLException {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection = DriverManager.
getConnection("jdbc:mysql://localhost:3306/mybaits?characterEncoding=UTF8","root","admin");
return connection;
}
}