加入收藏 | 设为首页 | 会员中心 | 我要投稿 鹰潭站长网 (https://www.0701zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

手动实现mysql简单功能

发布时间:2022-12-06 15:04:10 所属栏目:MySql教程 来源:未知
导读: mysql 手写
分使用端与架构端
创建配置文件,数据库连接配置、sqlmapper配置文件
sql语句信息mapper
sqlMapConfig.xml : 存放数据源信息,引入mapper.xml (存放)
Mapper.xml : sql语句的

mysql 手写

分使用端与架构端

创建配置文件,数据库连接配置、sqlmapper配置文件

sql语句信息mapper

sqlMapConfig.xml : 存放数据源信息,引入mapper.xml (存放)

Mapper.xml : sql语句的配置文件信息

1.读取配置文件

读取完成以后以流的形式存在,我们不能将读取到的配置信息以流的形式存放在内存中,不好操作,可 以创建javaBean来存储

(1)Configuration : 存放数据库基本信息、Map 唯一标识:namespace + "." + id

(2)MappedStatement:sql语句、statement类型、输入参数java类型、输出 参数java类型

2.解析配置文件

创建sqlSessionFactoryBuilder类: 方法:sqlSessionFactory build(): 第一:使用dom4j解析配置文件,将解析出来的内容封装到Configuration和MappedStatement中 第二:创建SqlSessionFactory的实现类DefaultSqlSession

3.创建SqlSessionFactory: 方法:openSession() : 获取sqlSession接口的实现类实例对象

4.创建sqlSession接口及实现类:主要封装crud方法 方法:selectList(String statementId,Object param):查询所有 selectOne(String statementId,Object param):查询单个 具体实现:封装JDBC完成对数据库表的查询操作

代码步骤

框架层

加载配置文件:根据配置文件路径,加载字节流到内存

创建两个javaBean(容器对象) 存放的是对配置文件解析出来的内容

Configuration:核心配置类,放sqlMapConfig.xml的内容

MappedStatement 映射配置类 放mapper.xml内容

解析配置文件:dom4j

创建SqlSessionFactoryBuilder。方法:build(InputStream in)

一 使用dom4j解析配置文件,装载到容器对象

二 创建SqlSessionFactory对象;生成sqlSession (工厂模式)

DefaultSqlSessionFactory实现SqlSessionFactory

生产sqlSession

创建SqlSession接口及实现类 DefaultSession

定义对数据库的curd操作:selectList() selectOne() update() delete()

创建Executor接口及实现类SimpleExecutor实现类

通用的query(Configuration ,MappedStatement,Object… param) 执行的就是JDBC操作代码

代码执行流程

先加载配置文件

SqlSessionFactoryBuilder通过配置文件流构建SqlSessionFactory对象 得到工厂对象

由工厂对象创建SqlSession

最后由SqlSession提供增删查改方法语句

还提供getMapper方法(代理的dao层实现)

sqlSession底层使用SimpleExecutor提供的query方法,其底层使用jdbc操作数据库代码结构图

mysql 命令\\s作用 desc_mysql作用_mysql中视图的作用

核心加载类结构图

代码实现sqlSessionFactoryBuilder.java主要用于创建SqlSessionFactory工厂mysql作用,其中做了两件事:

一 使用dom4j解析配置文件输入流并得到Configuration对象,

二 通过配置对象创建默认工厂类实例DefautSqlSessionFactory用于生产SqlSession的

```java

public class SqlSessionFactoryBuilder {

public SqlSessionFactory build(InputStream in ) throws PropertyVetoException, DocumentException {
       // 第一:使用dom4j解析配置文件,将解析出来的内容封装到Configuration中
       XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder();
       Configuration configuration = xmlConfigBuilder.parseConfig(in);
       // 第二:创建sqlSessionFactory对象:工厂类:生产sqlSession:会话对象
       SqlSessionFactory sqlSessionFactory = new DefautSqlSessionFactory(configuration);
       return sqlSessionFactory;
   }

} ```

Configuration.java 中主要存储xml解析出来的配置信息,包含数据库链接信息和sql语句信息

```java public class Configuration {

// 数据库连接池
   DataSource dataSource;
   Map mappedStatementMap = new HashMap();
   public DataSource getDataSource() {
       return dataSource;
   }
   public void setDataSource(DataSource dataSource) {
       this.dataSource = dataSource;
   }
   public Map getMappedStatementMap() {
       return mappedStatementMap;
   }
   public void setMappedStatementMap(Map mappedStatementMap) {
       this.mappedStatementMap = mappedStatementMap;
   }

} ```

默认工厂类DefautSqlSessionFactory.java 提供一个openSession()方法,该方法用于获取SqlSession对象

```java public class DefautSqlSessionFactory implements SqlSessionFactory {private Configuration configuration ;

public DefautSqlSessionFactory(Configuration configuration) {

       this.configuration = configuration;
   }
   @Override
   public SqlSession openSession() {
       SqlSession sqlSession = new DefaultSqlSession(configuration);
       return sqlSession;
   }

} ```

持久化核心实现类:DefaultSqlSession.java以上准备工作完成后,由session路由到指定sql语句并执行

```java public class DefaultSqlSession implements SqlSession {

private Configuration configuration;
   public DefaultSqlSession(Configuration configuration) {
       this.configuration = configuration;
   }
   public  List selectList(String statementid, Object... params) throws Exception {
       Executor executor = new SimpleExecutor();
       MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementid);
       List query = executor.query(configuration, mappedStatement, params);
       return (List) query;
   }
   public  T selectOne(String statementid, Object... params) throws Exception {
       List objects = selectList(statementid, params);
       if (objects == null || objects.size() != 1) {
           throw new RuntimeException("查询结果为空或结果过多");
       }
       return (T) objects.get(0);
   }

} ```

session通过执行器Executor来执行底层查询,SimpleExecutor.java文件如下:

先解析配置文件的sql得到BoundSql对象,boundSql中存储了转成?的sql以及按顺序排列的参数字段名list

通过反射注入参数

```java public class SimpleExecutor implements Executor {

/**
    * 使用jdbc进行数据库查询操作
    * 1. 获取jdbc的相关对象
    * 2. 解析sql语句,用?代替参数#{},同时解析#{}内部参数名并存储
    * 3. 根据参数名匹配参数值并设置
    * 4. 执行并返回
    * 
    * @param configuration 配置器
    * @param mappedStatement mapper配置,sql语句映射等
    * @param params 参数
    * @param 
    * @return
    * @throws Exception
    */
   public  List query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
       // 底层执行器使用jdbc进行数据库查寻操作
       // 1. 注册驱动,获取连接
       Connection connection = configuration.getDataSource().getConnection();
       // 2. 获取sql语句 : select * from user where id = #{id} and username = #{username}
       //转换sql语句: select * from user where id = ? and username = ? ,转换的过程中,还需要对#{}里面的值进行解析存储
       String sql = mappedStatement.getSql();
       BoundSql boundSql = getBoundSql(sql);
       // 3.获取预处理对象:preparedStatement
       PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());
       // 4. 设置参数
       //获取到了参数的全路径
       String paramterType = mappedStatement.getParamterType();
       Class<?> paramtertypeClass = getClassType(paramterType);
       List parameterMappingList = boundSql.getParameterMappingList();
       for (int i = 0; i 
           preparedStatement.setObject(i+1,o);
       }
       // 5. 执行sql
       ResultSet resultSet = preparedStatement.executeQuery();
       String resultType = mappedStatement.getResultType();
       Class<?> resultTypeClass = getClassType(resultType);
       ArrayList objects = new ArrayList<>();
       // 6. 封装返回结果集
       while (resultSet.next()){
           Object o =resultTypeClass.newInstance();
           //元数据
           ResultSetMetaData metaData = resultSet.getMetaData();
           for (int i = 1; i <= metaData.getColumnCount(); i++) {
               // 字段名
               String columnName = metaData.getColumnName(i);
               // 字段的值
               Object value = resultSet.getObject(columnName);
               //使用反射或者内省,根据数据库表和实体的对应关系,完成封装
               PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
               Method writeMethod = propertyDescriptor.getWriteMethod();
               writeMethod.invoke(o,value);
           }
           objects.add(o);
       }
       return (List) objects;
   }
   private Class<?> getClassType(String paramterType) throws ClassNotFoundException {
       if(paramterType!=null){
           Class<?> aClass = Class.forName(paramterType);
           return aClass;
       }
       return null;
   }
   /**
    * 完成对#{}的解析工作:1.将#{}使用?进行代替,2.解析出#{}里面的值进行存储
    * @param sql
    * @return
    */
   private BoundSql getBoundSql(String sql) {
       //标记处理类:配置标记解析器来完成对占位符的解析处理工作
       ParameterMappingTokenHandler parameterMappingTokenHandler = new ParameterMappingTokenHandler();
       GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", parameterMappingTokenHandler);
       //解析出来的sql
       String parseSql = genericTokenParser.parse(sql);
       //#{}里面解析出来的参数名称
       List parameterMappings = parameterMappingTokenHandler.getParameterMappings();
       BoundSql boundSql = new BoundSql(parseSql,parameterMappings);
       return boundSql;
   }

} ```

session中每个方法执行的时候还存在代码重复和硬编码问题,为了解决该问题,可以创建getMapper来获取dao层的代理实现对象

定义dao层接口:IUserDao.java,提供两个查询方法

```java public interface IUserDao {List findAll() throws Exception;

User findByCondition(User query) throws Exception;

}

```

```xml


   

```

```java @Override public T getMapper(Class

(编辑:鹰潭站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!