1.5 ⾃定义框架优化
通过上述我们的⾃定义框架,我们解决了JDBC操作数据库带来的⼀些问题:例如频繁创建释放数据库连接,硬编码,⼿动封装返回结果集等问题,但是现在我们继续来分析刚刚完成的⾃定义框架代码,有没有什么问题?
问题如下:
1、dao的实现类中存在重复的代码,整个操作的过程模板重复(创建sqlsession,调⽤sqlsession⽅法,关闭 sqlsession)
2、dao的实现类中存在硬编码,调⽤sqlsession的⽅法时,参数statement的id硬编码
解决:使⽤代理模式来创建接⼝的代理对象
package com.tyf.test;
import com.tyf.mapper.IUserDao;
import com.tyf.mybatis.Resources;
import com.tyf.mybatis.SqlSession;
import com.tyf.mybatis.SqlSessionFactory;
import com.tyf.mybatis.SqlSessionFactoryBuilder;
import com.tyf.pojo.User;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
public class IPersistenceTest {
@Test
public void test() throws Exception {
// 此处经常出现读取不到文件的问题,时好时坏。最终解决
// InputStream resourceAsSteam = this.getClass().getClassLoader().getResourceAsStream("classpath:SqlMapConfig.xml");
InputStream resourceAsSteam = Resources.class.getResourceAsStream("/SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);
SqlSession sqlSession = sqlSessionFactory.openSession();
//调用
/*User user = new User();
user.setId(1);
user.setUsername("tyf");
User user2 = sqlSession.selectOne("user.selectOne", user);
System.out.println(user2);*/
/* List<User> users = sqlSession.selectList("user.selectList");
for (User user1 : users) {
System.out.println(user1);
}*/
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
List<User> all = userDao.findAll();
for (User user1 : all) {
System.out.println(user1);
}
}
}
在sqlSession中添加⽅法及实现类中方法实现
public <T> T getMapper(Class<T> mapperClass) throws Exception;
@Override
public <T> T getMapper(Class<T> mapperClass) throws Exception {
T o = (T) Proxy.newProxyInstance(mapperClass.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
String statementId = className + "." + methodName;
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
Type returnType = method.getGenericReturnType();
//List list = new ArrayList();
// 判断是否实现泛型类型参数化
if (returnType instanceof ParameterizedType) {
return selectList(statementId, args);
}
return selectOne(statementId, args);
}
});
return o;
}