二、持久层框架设计实现及MyBatis源码分析-自定义持久层框架(二)

在前一章节,我们对自定义持久层框架有了一个基本的思路,接下来我们主要就是需要完成自定义持久层级框架的编写

首先我们先来编写使用端代码,新建一个maven项目,maven项目中pom.xml文件内容如下




    4.0.0

    study.lagou.com
    persistence-test
    1.0-SNAPSHOT

    
        UTF-8
        UTF-8
        1.8
        1.8
        1.8
    


在项目的resources文件夹下创建sqlMapConfig.xml配置文件



    
        
        
        
        
    


接着创建mapper.xml配置文件,但是我们在创建之前,先思考一个问题,在我们的一个项目当中,是不是应该会有很多个模块,不可能只有一个模块,可能有用户、商品、订单等等模块,如果我们只有一个mapper.xml文件话,所有的SQL语句都要写到这一个mapper.xml文件当中,这样做好吗?如果所有的SQL语句都写到一个mapper.xml文件,对于我们的操作和编写都是非常麻烦的,而且不易于阅读,为了使我们的mapper.xml文件当中的内容不至于太长,容易阅读和维护,所以我们推荐按照模块分别编写mapper.xml文件

接下来我们就按照不同的模块来编写不同的映射配置文件,比如当前我们有一个用户模块和商品模块,那么我们则需要编写两个映射配置文件

一个是UserMapper.xml,这个映射配置文件只用来编写用户相关的SQL语句
另外一个是ProduceMapper.xml,这个一配置文件只用来编写商品相关的SQL语句

接下来我们先以UserMapper.xml的编写来一步步演示,具体编写mapper.xml文件时需要注意的问题



    
    

    
    
    

简单的编写完以上的UserMapper.xml文件,我们可以看到在我们UserMapper.xml文件中有两条SQL语句,那么我们如何能够定位到映射配置文件中这两条SQL语句呢(具体调用时如何区分应该调用哪一条),如何区分是查询所有还是查询单个?我们无法区分,所以我们考虑给每一个SQL语句给一个标识属性(id),有了以下改进版本



    
    

    
    


如此改进完成之后,我们则可以通过selectList、和selectOne定位到具体我们需要的是哪一条SQL语句了,接着思考,我们改进完成之后还有没有其它问题呢?

如果是项目当中只有这一个模块,是没有问题的,但是如果项目当中还存在其它模块,其它模块也是这么编写的呢?我们以ProduceMapper.xml来举例说明



    
    

    
    



ProduceMapper.xml文件中也是这么写的,取的标识名也是selectList和selectOne,只是查询的表名不一样,现在通过selectList和selectOne这两个标识还能定位到唯一一条SQL语句吗?因为selectList和selectOne在项目当中存在多个了,我们不能区分开来,所以我需要再加一层标识加以识别处理==>命名空间namespace



    
    

    
    





    
    

    
    



现在我们可以约定,SQL的唯一标识,可以由namespace+"."+id来组成,这样就能唯一标识出唯一一条SQL语句了,由namespace.id组合成的唯一标识,我们将它称之为statementId

接着往下分析,现在我们能够获取到唯一一条SQL语句进行执行,但是执行完成后,返回的结果集还是需要我们手动去解析放到到具体的对象属性当中,这个手动封装返回结果集的过程较为繁琐,我需要借助于反射、内省等机制,完成返回结果集与对象属性的自动解析和封装,那么我们必须获取到对应对象的全路径才能够做操作,所以我们还需要给有返回结果集的查询语句,添加resultType属性,将返回对象的全路径放置进去,我们才能通过反射、内省等技术进行操作处理



    
    

    
    


至此,对selectList方法,我们能够完成基本的操作,但是我们接着看selectOne方法,在执行selectOne方法的时候,我们需要传入参数,才能够构建查询的SQL语句,所以在selectOne方法上我们还得添加paramterType属性,而针对多个参数的传递,还是得基于面向对象的思想进行传递,所以接下来我们再对selectOne方法进行完善



    
    

    
    



将参数对象通过paramterType属性给到自定义持久层框架,持久层框架需要做的就是通过反射,取到参数对象的属性值,取到对应的属性值之后,我们要给对应的占位符进行赋值,但是我们怎么定位到将哪个属性值赋值到哪一个占位符上面呢?显然,我们通过以“?”做为占位符的方法,无法完成对应,所以我们需要对占位符进行改进,改进成#{属性}的方式来进行处理,注意:#{}当中的属性,需要与paramterType属性对象中的属性一一对应才行,不能随便给!



    
    

    
    



我们在占位符中给的是id和username两个属性,那么paramterType对应对象中一定存在这两个属性值

package study.lagou.com.persistence.test.pojo;

/**
 * @Description: 功能描述
 * @Author houjh
 * @Email: [email protected]
 * @Date: 2021-1-27 22:13
 */
public class User {
    /**
     * 主键信息
     */
    private Integer id;
    /**
     * 用户名称
     */
    private String username;
    /**
     * 用户密码
     */
    private String password;
    /**
     * 用户昵称
     */
    private String nickname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

至此,我们编写映射配置文件算是基本上完成了,但是上一节当中,我们在分析自定义持久层框架思路的时候,分析出自定义持久层框架的第一步就是加载配置文件,我们没有必要通过getResourceAsStream(String path)方法对配置文件加载两次,而是直接在sqlMapConfig.xml存放一份映射配置文件的全路径,后面通过解析sqlMapConfig.xml文件就可以获取到mapper.xml映射配置文件的全路径,对mapper文件进行操作,所以我们再对sqlMapConfig.xml配置文件进行完善



    
        
        
        
        
    

    

至此,我们使用端代码编写完成

具体代码对应下载地址:https://gitee.com/happymima/mybatis.git

你可能感兴趣的:(二、持久层框架设计实现及MyBatis源码分析-自定义持久层框架(二))