• mybatis


    一. 测试代码

    //实体类
    public class User   {
        private Integer id;
        private String name;
        private Integer age;
        private String email;
        private SexEnum sex;
        //getter / setter
    }
    
    public enum SexEnum {
    
        Male("Male", "男"),
    
        Female("Female", "女");
    
        private String code;
    
        private String desc;    
    
        SexEnum(String code, String desc){
            this.code = code;
            this.desc = desc;
        }   
    }
    
    //Repository
    @Repository
    public interface UserMapper  {
    
        public User getById(Integer id);
    
        public List<User> getByAge(Integer age);
    
        public int insert(User user);
    }
    
    @SpringBootApplication
    @MapperScan("com.study.demo.mybatis.mapper")
    public class MybatisApplication {
        public static void main(String[] args) {
            SpringApplication.run(MybatisApplication.class, args);
        }    
    }
    
    @Test
    public void getById(){
        System.out.println("getById 开始执行...");
        User user = userMapper.getById(1);
        System.out.println(user);
        System.out.println("getById 结束执行...");
    }

    mapper.xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.study.demo.mybatis.mapper.UserMapper">
        <insert id="insert">
            insert into user (name,age,email,sex) values(#{name}, #{age}, #{email}, #{sex})
        </insert>
    
        <select id="getById" resultType="com.study.demo.mybatis.vo.User">
            select * from user where id = #{id}
        </select>
    
        <select id="getByAge" resultType="com.study.demo.mybatis.vo.User">
            select * from user where age = #{age}
        </select>
    </mapper>

    配置文件:

    spring:
        datasource:
            #type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost:3306/deco?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
            username: root
            password: 123456
    
    mybatis:
        mapper-locations: classpath:mapper/**Mapper.xml


    @MapperScan("com.study.demo.mybatis.mapper")
    主要做了两件事情:

    1. 根据 "com.study.demo.mybatis.mapper" 配置进行mapper.java文件扫描.

      此处扫描到的就是 SchoolMapper.java 和 UserMapper.java 两个文件

    2. 为扫描到的文件进行 BeanDefinition 注册

    //关键代码: 
    private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) { GenericBeanDefinition definition; for (BeanDefinitionHolder holder : beanDefinitions) { definition = (GenericBeanDefinition) holder.getBeanDefinition(); if (logger.isDebugEnabled()) { logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + definition.getBeanClassName() + "' mapperInterface"); } // the mapper interface is the original class of the bean // but, the actual class of the bean is MapperFactoryBean definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); // issue #59 definition.setBeanClass(this.mapperFactoryBean.getClass()); ...... }

    在进入此方法之前,  beanDefinitions 已经通过扫描得到, 

    beanName beanClass
    schoolMapper com.study.demo.mybatis.mapper.SchoolMapper
    userMapper com.study.demo.mybatis.mapper.UserMapper

    进入方法后, 会执行以下代码, 对 beanClass 进行重新赋值:

    definition.setBeanClass(this.mapperFactoryBean.getClass());

    这里的 mapperFactoryBean 是 ClassPathMapperScanner 的一个私有属性:

    private MapperFactoryBean<?> mapperFactoryBean = new MapperFactoryBean<Object>();

    也就是说, 后面对 beanName = userMapper 进行创建的时候, 会使用到  MapperFactoryBean

    二. MapperFactoryBean

    public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
    
      private Class<T> mapperInterface;
    
      private boolean addToConfig = true;
    
      public MapperFactoryBean() {
        //intentionally empty 
      }
      
      public MapperFactoryBean(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
      }
    
      /**
       * {@inheritDoc}
       */
      @Override
      protected void checkDaoConfig() {
        super.checkDaoConfig();
    
        notNull(this.mapperInterface, "Property 'mapperInterface' is required");
    
        Configuration configuration = getSqlSession().getConfiguration();
        if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
          try {
            configuration.addMapper(this.mapperInterface);
          } catch (Exception e) {
            logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", e);
            throw new IllegalArgumentException(e);
          } finally {
            ErrorContext.instance().reset();
          }
        }
      }
    
      /**
       * {@inheritDoc}
       */
      @Override
      public T getObject() throws Exception {
        return getSqlSession().getMapper(this.mapperInterface);
      }
    
      /**
       * {@inheritDoc}
       */
      @Override
      public Class<T> getObjectType() {
        return this.mapperInterface;
      }
    
      /**
       * {@inheritDoc}
       */
      @Override
      public boolean isSingleton() {
        return true;
      }
    
      //------------- mutators --------------
    
      /**
       * Sets the mapper interface of the MyBatis mapper
       *
       * @param mapperInterface class of the interface
       */
      public void setMapperInterface(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
      }
    
      /**
       * Return the mapper interface of the MyBatis mapper
       *
       * @return class of the interface
       */
      public Class<T> getMapperInterface() {
        return mapperInterface;
      }
    
      /**
       * If addToConfig is false the mapper will not be added to MyBatis. This means
       * it must have been included in mybatis-config.xml.
       * <p/>
       * If it is true, the mapper will be added to MyBatis in the case it is not already
       * registered.
       * <p/>
       * By default addToCofig is true.
       *
       * @param addToConfig
       */
      public void setAddToConfig(boolean addToConfig) {
        this.addToConfig = addToConfig;
      }
    
      /**
       * Return the flag for addition into MyBatis config.
       *
       * @return true if the mapper will be added to MyBatis in the case it is not already
       * registered.
       */
      public boolean isAddToConfig() {
        return addToConfig;
      }
    }

    从代码上看, 实现了 FactoryBean 接口,  他是一个 工厂bean.

    在创建 userMapper 的时候, 就会调用 MapperFactoryBean 的 getObject() 方法.

     md版本: https://files.cnblogs.com/files/elvinle/mybatis.zip

  • 相关阅读:
    Awesome Adb——一份超全超详细的 ADB 用法大全
    adb devices unauthorized的解决办法
    Vim用法AAAAA
    Security arrangements for extended USB protocol stack of a USB host system
    六 Python基础 字符串和编码
    四 Python基础
    三 Python解释器
    二安装Python
    Python教程(一)Python简介
    Python基本语法[二]
  • 原文地址:https://www.cnblogs.com/elvinle/p/12296947.html
Copyright © 2020-2023  润新知