# MyPersistence **Repository Path**: sunshinekay/my-persistence ## Basic Information - **Project Name**: MyPersistence - **Description**: 模仿Mybatis自定义一个持久层框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-06-25 - **Last Updated**: 2021-07-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## MyPersistence ##介绍 ### 模仿Mybatis自定义一个持久层框架雏形 ## 软件架构 ### 软件架构说明 分为两个项目,IPersistence为框架定义端 IPersistence-Test为使用端 ## 使用教程 ## 将IPersistence打成Jar,由IPersistence-Test使用 ##实现效果 1.配置文件实现基本连接、SQL语句 (代码、SQl分离) 2.连接池降低连接开销 3.实现ORM基本思想对象与表之间的映射 ##分支介绍 ###Level01分支 #### 编写逻辑 1. 根据配置文件路径,读取配置文件SqlMapConfig.xml、Mapper.xml成输入流(InputStream) 2. 定义两个java类 Configuration(用于存放sqlMapConfig.xml文件中内容,数据库内容 Mapper.xml内容) MappedStatement(用于存放Mapper.xml中的内容 id、传参类型、结果类型,SQl语句) 3. 解析 1 中读取的输入流到 2 的类中 定义类SqlSessionFactoryBuilder, 编写build(InputStream) 方法 A. 通过dom4j技术,将流信息写入到实体类 Configuration 及 MappedStatement(转换方法封装在XMLConfigBuilder 及 XMLMapperBuilder) B. 创建SqlSessionFactory接口(用于生产SqlSession对象) 4. 创建SqlSessionFactory的实现类DefaultSqlSessionFactory,用于创建SqlSession(创建SqlSession的实现类DefaultSession) A.openSession()方法,返回DefaultSession(); 5. SqlSession中定义对数据库的基本curd接口由DefaultSession类具体实现(通过调用Executor中query中接口实现) selectList(mappedStatementId, Params...); selectOne(mappedStatementId, Params...); 6. 定义Executor接口及其对应的实现类SimpleExecutor(执行JDBC代码 连接数据库、获取待执行SQL语句,获取预处理对象,执行SQL,处理返回结果集) query(Configuration,MappedStatement,Params...) 关键步骤java技术点 1. 根据文件路径读取文件流 ClassLoader.getResourceAsStream(path) 2. 文件流解析成类对象 dom4j 3. 反射技术 A.传入参数#{XXX} 将XXX对应到实体类中字段 B结果集封装到对应的实体类中(反射及内省PropertyDescriptor) level01存在的问题 1.level01存在问题:userDao实现类中,存在重复代码(加载配置文件、通过SqlSessionFactoryBuilder创建sqlSessionFactory,创建SqlSession) 2.selectList(mappedStatementId, Params...); mappedStatementId 的传入存在硬编码 ### Level02分支 1.在level01的基础上,在SqlSession中增加getMapper接口在DefaultSession中实现 使用JDK动态代理生成对应的MapperDao接口对象 以接口UserDao为例: sqlSession.getMapper(UserDao.class) ---> 返回的是 UserDao 的 代理类 proxyInstance 当UserDao.userList(); 执行的是 invoke 中的方法 ****为保证在动态代理中能拿到 mappedStatementId 因为invoke中拿到mappedStatementId是通过类路径+id拿到的所以mapper.xml需要达到以下两点 A. 将被代理类(UserDao)类路径配置在UserMapper.xml文件中作为namespace (强制) B. mapper.xml文件中的Id需同方法名一致(强制) 关键步骤java技术点 1. JDK动态代理 ### Master分支 1.增加了增删改接口 2.SimpleExecutor中传入参数解析增加了传参类型为基础数据类型或者其包装类型的判断(todo:可优化其他类型的处理,比如 数组、集合等)