list mybatis 接收 类型_手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄)

9fc6ac249a67c84e42f29974c48e3144.png

说明

MyBatis版本:3.5.1

相关历史文章(阅读本文之前,您可能需要先看下之前的系列?)

Spring Boot MyBatis最全教程:你值得拥有 MyBatis能脱离Spring吗 一图纵览MyBatis的工作原理 从源码看MyBatis,竟如此简单MyBatis的Mapper是什么`垃圾`  

手写MyBatis,纯手工打造开源框架(第一篇:风云再起) 

手写MyBatis,纯手工打造开源框架(第二篇:君临天下) 

前言

       通过上面我们已经可以构建了SqlSessionFactory,接下来的话就是要怎么获取一个SqlSession。

一、分析

       对于SqlSession的构建的话,需要有一个属性Configuration,这个属性在上面的SqlSessionFactory已经有了;另外对于SqlSession的真正的Sql执行是交给了Executor,Executor是真正和数据库进行交互了,所以需要将数据库配置信息传给Executor。

二、编码

2.1 Executor

       构造SqlSession需要有Executor,我们先创建一个Executor接口:

package com.kfit.mybatis.session;

import java.util.List;

import com.kfit.mybatis.config.MapperStatement;

public interface Executor {
      List query(MapperStatement ms, Object parameter);
}

       我们实现一个最基本的SimpleExecutor:

package com.kfit.mybatis.session.impl;

import java.util.List;

import com.kfit.mybatis.config.JdbcProperties;
import com.kfit.mybatis.config.MapperStatement;
import com.kfit.mybatis.session.Executor;

public class SimpleExecutor implements Executor {
    private JdbcProperties jdbcProperties;

    public SimpleExecutor(JdbcProperties jdbcProperties) {
        this.jdbcProperties = jdbcProperties;
    }

    public  List query(MapperStatement ms, Object parameter) {//具体的方法待实现return null;
    }
}

说明:

(1)这里我们实现了最基本的Simple,在MyBatis有3种情况需要处理,我们实现最简单的方式。

(2)这里我们接收了jdbcproperties为了之后直接进行数据库的连接操作,在mybatis数据库的连接关闭,提交,回滚是有一个事务类Transaction。

2.2 SqlSessionFactory

       在SqlSessionFactory中添加一个获取SqlSession的方法:

public interface SqlSessionFactory {
    public Configuration getConfiguration();
    public SqlSession openSession();
}

       在DefaultSqlSessionFactory实现openSession()方法:

    public SqlSession openSession() {
        Executor executor = new SimpleExecutor(configuration.getJdbcProperties());
        SqlSession sqlSession = new DefaultSqlSession(configuration, executor);
        return sqlSession;
    }

2.3 SimpleExecutor数据库操作

       我们这个对数据库操作的核心代码:

package com.kfit.mybatis.session.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.kfit.mybatis.config.JdbcProperties;
import com.kfit.mybatis.config.MapperStatement;
import com.kfit.mybatis.session.Executor;

public class SimpleExecutor implements Executor {
    private JdbcProperties jdbcProperties;

    public SimpleExecutor(JdbcProperties jdbcProperties) {
        this.jdbcProperties = jdbcProperties;
    }

    public  List query(MapperStatement ms, Object parameter) {List ret = new ArrayList();// 具体的方法待实现try {// 加载驱动
            Class.forName(jdbcProperties.getDriver());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;try {// 获取连接
            connection = DriverManager.getConnection(jdbcProperties.getUrl(), jdbcProperties.getUsername(),
                    jdbcProperties.getPassword());// 预编译sql语句
            preparedStatement = connection.prepareStatement(ms.getSql());// 处理sql语句中的占位符
            parameterize(preparedStatement, parameter);// 执行sql语句
            resultSet = preparedStatement.executeQuery();// 处理结果
            handlerResultSet(resultSet, ret, ms.getResultType());
        } catch (SQLException e) {
            e.printStackTrace();
        }return ret;
    }
    private void parameterize(PreparedStatement preparedStatement, Object parameter) throws SQLException {if (parameter instanceof String) {
            preparedStatement.setString(1, (String) parameter);
        } else if (parameter instanceof Long) {
            preparedStatement.setLong(1, (Long) parameter);
        } else if (parameter instanceof Integer) {
            preparedStatement.setInt(1, (Integer) parameter);
        }
    }
    private  void handlerResultSet(ResultSet resultSet, List ret, String className) {
        Class clazz = null;try {
            clazz = (Class) Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }try {while (resultSet.next()) {// 通过反射实例化对象Object entity = clazz.newInstance();// 使用反射工具将resultSet中的数据填充到entity中// id,name,sex,age// 获取实体类的所有属性,返回Field数组
                Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {
                    field.setAccessible(true);String fname = field.getName();Type type = field.getGenericType();if (type.toString().equals("class java.lang.String")) {String column = resultSet.getString(fname);
                        field.set(entity, column);
                    }else if (type.toString().equals("long")) {
                        Long column = resultSet.getLong(fname);
                        field.set(entity, column);
                    }
                }
                ret.add((E) entity);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

说明:

(1)在MyBatis中这个代码是分好几个类进行处理的,这里为了讲解方便,统一放在一个类中。

(2)数据库的连接操作:这里使用jdbc连接数据库获取到connection进行操作。

(3)使用泛型处理返回的结果(handlerResultSet)。

2.4 SqlSession的方法

       到这里,我们就可以编写SqlSession的方法了,这里定义两个方法SelectOne和SelectList();

public interface SqlSession {
      T selectOne(String statement, Object parameter); List selectList(String statement); List selectList(String statement, Object parameter);
}

       对应的DefaultSqlSession:

package com.kfit.mybatis.session.impl;


import java.util.List;

import com.kfit.mybatis.config.Configuration;
import com.kfit.mybatis.session.Executor;
import com.kfit.mybatis.session.SqlSession;

public class DefaultSqlSession implements SqlSession {
    private Configuration configuration;
    private Executor executor;
    public DefaultSqlSession(Configuration configuration,Executor executor) {
        this.configuration= configuration;
        this.executor = executor;
    }


    public  List selectList(String statement) {return executor.query(configuration.getMapperStatement(statement),null);
    }public  List selectList(String statement,Object parameter) {return executor.query(configuration.getMapperStatement(statement), parameter);
    }public  T selectOne(String statement,Object parameter) {
        List list = executor.query(configuration.getMapperStatement(statement),parameter);if(list.size()>0) {return list.get(0);
        }return null;
    }
}

说明:DefaultSqlSession的具体处理交给了Executor,所以这里的具体的实现就比较简单了。

2.5 测试下

       在main方法来进行测试一下吧:

    public static void main(String[] args) {
        String resource = "mybatis-config.xml";
        InputStream inputStream = App.class.getClassLoader().getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        System.out.println(sqlSessionFactory);
        System.out.println(sqlSessionFactory.getConfiguration().getJdbcProperties().getUrl());

        SqlSession sqlSession = sqlSessionFactory.openSession();


        Demo demo = null;
        List demos = null;//使用sqlSession直接查询
        demo = sqlSession.selectOne("com.kfit.mybatis.demo.mapper.DemoMapper.getById",1L);
        System.out.println(demo);
        demos = sqlSession.selectList("com.kfit.mybatis.demo.mapper.DemoMapper.getAll");
        System.out.println(demos);
    }

       这个方法和之前写mybatis的使用方式上是一模一样的,运行看下效果吧:

Demo[id=1, name=张三1]

[Demo [id=1, name=张三1], Demo [id=9, name=张三], Demo [id=10, name=张三], Demo [id=11, name=张三], Demo [id=12, name=张三], Demo [id=13, name=张三]]

       看到如此帅气的结果,这是爽歪歪,厉害了我的哥。本篇就先介绍到这里,下一篇我们将会介绍无敌的Mapper实现。

我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。

à悟空学院:http://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「」进行查看!

SpringBoot视频:http://t.cn/R3QepWG

Spring Cloud视频:http://t.cn/R3QeRZc

SpringBoot Shiro视频:http://t.cn/R3QDMbh

SpringBoot交流平台:http://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/R1pSojf

SpringSecurity5.0视频:http://t.cn/EwlLjHh

Sharding-JDBC分库分表实战:http://t.cn/E4lpD6e

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值