zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    PHP 大小写转换、首字母大写、每个单词首字母大写转换相关函数
    【论文学习4】BiSample: Bidirectional Sampling for Handling Missing Data with Local Differential Privacy
    【论文学习3】Local Differential Privacy for Deep Learning
    【论文学习2】 Differential Privacy Reinforcement Learning
    深度学习中的优化算法
    Spatial crowdsourcing
    “pip install tensorflow ”出现错误
    python或pip'不是内部或外部命令”
    pip install torch出现错误
    打不开gitHub的解决方法
  • 原文地址:https://www.cnblogs.com/elvinle/p/12296947.html
Copyright © 2011-2022 走看看