自定义持久层框架
2021-06-29 00:15:39 4 举报
AI智能生成
自定义的持久层框架
作者其他创作
大纲/内容
SqlSessionFactory
DefaultSqlSessionFactory
Configuration
SqlSession
DefaultSqlSession
Configuration
Executor
SimpleExecutor
自定义持久层框架实现功能的流程
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
InputStream resourceAsStream = Resources.class.getClassLoader().getResourceAsStream(path);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
// 第一: 使用dom4j解析配置文件, 将解析出来的内容封装到Configuration中<br> XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder();<br> Configuration configuration = xmlConfigBuilder.parseConfig(in);
// 第二: 创建sqlSessionFactory对象<br> DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);<br>
SqlSession sqlSession = sqlSessionFactory.openSession();
return new DefaultSqlSession(configuration);<br>
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//使用jdk动态代理来为dao接口生成代理对象并返回<br> Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {<br> public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br><br> //获取方法名, 也就是id<br> String methodName = method.getName();<br><br> //获取方法对应的类的全限定名<br> String className = method.getDeclaringClass().getName();<br><br> String statementId = className + "." + methodName;<br><br> //获得返回值类型<br> Type genericReturnType = method.getGenericReturnType();<br> //判断是否进行了泛型类型参数化<br> if (genericReturnType instanceof ParameterizedType){<br> List<Object> objects = selectList(statementId, args);<br> return objects;<br> }<br> return selectOne(statementId,args);<br> }<br> });
public <E> List<E> selectList(String statementid, Object... params) throws Exception {<br><br> //将要去完成simpleExecutor里的query方法的调用<br> SimpleExecutor simpleExecutor = new SimpleExecutor();<br> MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementid);<br> List<Object> list = simpleExecutor.query(configuration, mappedStatement, params);<br><br> return (List<E>) list;<br> }
<br> //1. 注册驱动, 获取连接<br> Connection connection = configuration.getDataSource().getConnection();<br><br> //2. 获取sql语句<br> String sql = mappedStatement.getSql();<br> BoundSql boundSql = getBoundSql(sql);<br><br> //3.获取预处理对象preparedStatement<br> PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());<br><br> //4. 设置参数 获取参数的全限定名, 然后获取对应的class<br> String parameterType = mappedStatement.getParameterType();<br> Class<?> parameterTypeClass = getClassType(parameterType);<br><br> List<ParameterMapping> parameterMappingList = boundSql.getParameterMappingList();<br> for (int i = 0; i < parameterMappingList.size(); i++) {<br> Field declaredField = parameterTypeClass.getDeclaredField(parameterMappingList.get(i).getContent());<br> //暴力访问<br> declaredField.setAccessible(true);<br> Object o = declaredField.get(params[0]);<br><br> preparedStatement.setObject(i + 1, o);<br><br> }<br><br> //5. 执行sql<br> ResultSet resultSet = preparedStatement.executeQuery();<br><br> //6. 封装返回结果集<br> String resultType = mappedStatement.getResultType();<br> Class<?> resultTypeClass = getResultType(resultType);<br> ArrayList<Object> objects = new ArrayList();<br><br> while (resultSet.next()) {<br> Object o = resultTypeClass.newInstance();<br> ResultSetMetaData metaData = resultSet.getMetaData();<br> for (int i = 1; i <= metaData.getColumnCount(); i++) {<br> //字段名<br> String columnName = metaData.getColumnName(i);<br> //字段值<br> Object value = resultSet.getObject(columnName);<br><br> //使用内省和反射完成封装<br> PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass); //获取类对应参数的读写方法的对象<br> Method writeMethod = propertyDescriptor.getWriteMethod();<br> writeMethod.invoke(o, value);<br> }<br> objects.add(o);<br> }<br>
List<User> users = userDao.findAll();<br>
Configuration
DataSource
数据源
mappedStatementMap
key:statementid,value:封装好的MappedStatement对象
MappedStatement<br>
id
resultType
parameterType<br>
sql
收藏
0 条评论
下一页