• mybatis源码分析(一)


    最近打算读读mybatis的源码来提高自己写bug的水平,hahaha

    找到网站下载源码:https://github.com/mybatis/mybatis-3

    使用idea进行关联,并且配置好环境之后。

    配合中文文档进行搭建:

    1.导入jdbc包,我用的 lombok

      <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.16.18</version>
          <scope>provided</scope>
        </dependency>
    <!--没有mysql依赖-->
        <!-- 数据库连接池、驱动 -->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.8</version>
        </dependency>

    2.创建数据库连接的xml文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="mybatisUserMapper.xml"/>
        </mappers>
    </configuration>

    3.创建java对象

    package java7115;
    
    import lombok.*;
    
    @Data
    @Builder//链式调用<--
    @RequiredArgsConstructor
    @AllArgsConstructor
    @ToString
    public class User {
    private  Integer id;
    private  String username;
    private  String password;
    private  String  remarks;
    private  String true_name;
    }

    4.编写mybatis的sql

    <?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="java7115">
        <select id="selectUser" resultType="java7115.User">
        select * from User where id = #{id}
      </select>
    </mapper>

    5.

    为了能显示sql增加日志

    log4j.properties

    #
    #    Copyright 2009-2016 the original author or authors.
    #
    #    Licensed under the Apache License, Version 2.0 (the "License");
    #    you may not use this file except in compliance with the License.
    #    You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #    Unless required by applicable law or agreed to in writing, software
    #    distributed under the License is distributed on an "AS IS" BASIS,
    #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #    See the License for the specific language governing permissions and
    #    limitations under the License.
    #
    
    ### Global logging configuration
    log4j.rootLogger=debug, stdout
    
    ### Uncomment for MyBatis logging
    log4j.logger.org.apache.ibatis=ERROR
    
    log4j.logger.org.apache.ibatis.session.AutoMappingUnknownColumnBehavior=WARN, lastEventSavedAppender
    
    ### Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
    
    log4j.appender.lastEventSavedAppender=org.apache.ibatis.session.AutoMappingUnknownColumnBehaviorTest$LastEventSavedAppender

    main方法测试

    package org.apache.ibatis;
    
    import java7115.User;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class Main {
        public static void main(String[] args) throws IOException {
    
           String resource = "mybatis-config.xml";
            //读取配置文件
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //创建连接工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //得到session实例
            SqlSession session = sqlSessionFactory.openSession();
            try {
                //根据命名空间找方法
                User blog = (User) session.selectOne("java7115.selectUser", 1);
                System.out.println(blog);
            } finally {
                session.close();
            }
        }
    }

    输出结果:

    DEBUG [main] - ==> Preparing: select * from User where id = ?
    DEBUG [main] - ==> Parameters: 1(Integer)
    DEBUG [main] - <== Total: 1
    User(id=1, username=admin, password=123, remarks=管理员, true_name=王大陆)

     

    这个是我当前目录图片

    通过第一步mybatis的简单构建得知myabatis的使用简单易用,深得程序员的喜爱

    SqlSessionFactory创建方式一共有三种方式,
    第一种就是上面的通过读取xml文件来获取。
    接下来是第二种方式:通过代码来实现:
    dao接口:
    package java7115.dao;
    
    import java7115.User;
    
    import java.util.List;
    
    /**
     * Mapper接口开发需要遵循以下规范:
     * 1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。
     * 2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
     * 3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
     * 4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
     */
    public interface UserMapper {
       List<User> selectUser(Integer id);
    }

    UserMapper.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="java7115.dao.UserMapper">
        <select id="selectUser" resultType="java7115.User">
        select * from User where id = #{id}
      </select>
    </mapper>

    目录图:

    测试构建:
     /**
         * 第二种
         *
         * @throws IOException
         */
        @Test
        public void test02() throws IOException {
            String driver = "com.mysql.jdbc.Driver";
            String url = "jdbc:mysql://127.0.0.1:3306/mybatis";
            String username = "root";
            String password = "root";
            //创建使用缓存池的数据源
            /*
             * <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driverClassName}"/>
                    <property name="url" value="${jdbc.url}"/>
                    <property name="username" value="${jdbc.username}"/>
                    <property name="password" value="${jdbc.password}"/>
                </dataSource>
             */
            DataSource dataSource = new PooledDataSource(driver, url, username, password);
    
            //创建事务
            /*
            增删改需要创建事务
             * <transactionManager type="JDBC" />
             */
            TransactionFactory transactionFactory = new JdbcTransactionFactory();
    /**
     * Environment:{id,事务,数据源,都不能为null,只要使用都要有值}
     */
            Environment environment = new Environment("development", transactionFactory, dataSource);
    
            Configuration configuration = new Configuration(environment);
            //加入资源
            /*
             * <mapper resource="ssm/BlogMapper.xml"/>
             */
            //注册别名
            configuration.getTypeAliasRegistry().registerAlias("user", User.class);
            //加入映射器对象
            configuration.addMapper(UserMapper.class);
    //构建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
            SqlSession session = sqlSessionFactory.openSession();
         /*--之前那种方式  --
          User o = (User) session.selectOne("java7115.dao.UserMapper.selectUser", 1);
             System.out.println(o);*/
            //获取mapper接口代理对象
            UserMapper userMapper = session.getMapper(UserMapper.class);
            List<User> users = userMapper.selectUser(1);
            System.out.println(users.toString());
            session.commit();
            session.close();
        }

    第三种方式是与spring集成:

        /**
         *  第三种 :在spring的配置文件applicationContext.xml中配置
         *  如果使用则直接注入,获取SqlSessionFactory实例即可。
         */
      /*  <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
           <property name="dataSource" ref="dataSource" />
           <property name="configLocation" value="classpath*:conf/configuration.xml"/>
    </bean>
        */
    mybatis除了xml开发 还可以使用注解方式开发:
    除了以上内容不变之外
    sql编写的位置由xml修改到接口
    //数据库和java类型 映射
      @ConstructorArgs({
          @Arg(column = "AUTHOR_ID", javaType = int.class)
      })
      //返回数据别名
      @Results({
          @Result(property = "username", column = "AUTHOR_USERNAME"),
          @Result(property = "password", column = "AUTHOR_PASSWORD"),
          @Result(property = "email", column = "AUTHOR_EMAIL"),
          @Result(property = "bio", column = "AUTHOR_BIO")
      })
      @Select({
          "SELECT ",
          "  ID as AUTHOR_ID,",
          "  USERNAME as AUTHOR_USERNAME,",
          "  PASSWORD as AUTHOR_PASSWORD,",
          "  EMAIL as AUTHOR_EMAIL,",
          "  BIO as AUTHOR_BIO",
          "FROM AUTHOR WHERE ID = #{id}"})
      Author selectAuthor(int id);
      @Select({ "SELECT * FROM blog"})
      @MapKey("id")//通过唯一键返回对象
      Map<Integer,Blog> selectBlogsAsMapById();

    发现mybatis写法越来越诡异了:

    mapper写的:

    @SelectProvider(type = BoundBlogSql.class, method = "selectBlogsSql") List<Blog> selectBlogsUsingProvider(); ---------------------------------------------------------------------------------- public class BoundBlogSql { public String selectBlogsSql() { return new SQL() { { SELECT("*"); FROM("BLOG"); } }.toString(); } }

     这个我比较喜欢:将全部数据查询出来

      @Select("SELECT * FROM " +
          "blog WHERE id = #{id}")
      @ConstructorArgs({
          @Arg(column = "id", javaType = int.class, id = true),
          @Arg(column = "title", javaType = String.class),
          @Arg(column = "author_id", javaType = Author.class, select = "org.apache.ibatis.binding.BoundAuthorMapper.selectAuthor"),
          @Arg(column = "id", javaType = List.class, select = "selectPostsForBlog")
              //这个传入select的id,最好传全路径不然不好找
      })
      Blog selectBlogUsingConstructor(int id);

     看看有什么不同:

      @Select("SELECT * FROM blog " +
              "WHERE id = #{id} AND title = #{params.nonExistentParam,jdbcType=VARCHAR}")
      Blog selectBlogByNonExistentNestedParam(@Param("id") int id, @Param("params") Map<String, Object> params);
    
      @Select("SELECT * FROM blog WHERE id = #{id}")
      Blog selectBlogByNullParam(Integer id);
    
      //======================================================
    
      @Select("SELECT * FROM blog " +
          "WHERE id = #{0} AND title = #{1}")
      Blog selectBlogByDefault30ParamNames(int id, String title);
    
      @Select("SELECT * FROM blog " +
          "WHERE id = #{param1} AND title = #{param2}")
      Blog selectBlogByDefault31ParamNames(int id, String title);


  • 相关阅读:
    Ubuntu 查看网关地址方法
    cf451C-Predict Outcome of the Game
    C语言运算符优先级
    文件的概念以及VC里的一些文件操作API简介
    关于空指针NULL、野指针、通用指针
    由字符串常量引发的思考
    数字三角形问题
    cdoj第13th校赛初赛F
    cdoj第13th校赛初赛H
    cdoj第13th校赛初赛L
  • 原文地址:https://www.cnblogs.com/q1359720840/p/10496783.html
Copyright © 2020-2023  润新知