1、准备环境

项目结构

maven依赖

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.3</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
</dependencies>

mybatis-config.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>
    <properties resource="jdbc.properties"></properties>
    <settings>
        <setting name="logImpl" value="LOG4J"/></settings>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com.whf/UserMapper.xml"/>
    </mappers>
</configuration>

jdbc.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo
username=root
password=admin

log4j.properties

log4j.rootLogger=debug, stdout, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

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="com.whf.mapper.UserMapper">
    <select id="selectById" resultType="com.whf.entity.User">
        select * from user where id = #{id}
    </select>
</mapper>

UserMapper

public interface UserMapper {

    User selectById(Integer id);
    
    @Select("select * from user")
    List<User> selectAll();

}

User

public class User {

    private String name;
    private Integer age;

    public String getName() {
        return name;
}

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

数据库

测试类 MybatisDemo

public class MybatisDemo {

    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new     
        SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selectById(3);
        System.out.println(user);
        List<User> users = mapper.selectAll();
        System.out.println(users);
    }

}

运行main方法,获得输出结果

DEBUG [main] (JdbcTransaction.java:136) - Opening JDBC Connection
DEBUG [main] (PooledDataSource.java:424) - Created connection 258931371.
DEBUG [main] (JdbcTransaction.java:100) - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@f6efaab]
DEBUG [main] (BaseJdbcLogger.java:143) - ==>  Preparing: select * from user where id = ? 
DEBUG [main] (BaseJdbcLogger.java:143) - ==> Parameters: 3(Integer)
DEBUG [main] (BaseJdbcLogger.java:143) - <==      Total: 1
User{name='fc26d', age=18}
DEBUG [main] (BaseJdbcLogger.java:143) - ==>  Preparing: select * from user 
DEBUG [main] (BaseJdbcLogger.java:143) - ==> Parameters: 
DEBUG [main] (BaseJdbcLogger.java:143) - <==      Total: 8
[User{name='86b30', age=18}, User{name='20d79', age=18}, User{name='fc26d', age=18}, User{name='a711a', age=18}, User{name='1274f', age=18}, User{name='6774b', age=18}, User{name='b19c9', age=18}, User{name='68f29', age=18}]

看输出说明成功用mybatis查询数据库,先简单分析下main方法,下一篇再开始深入分析源码

1)SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactory 主要作用就是初始化mybatis,扫描xml文件并且读取配置文件,最终转化为java对象(Configuration),最终SqlSessionFactory 持有Configuration对象,每个应用只有一个SqlSessionFactory和Configuration对象

2)SqlSession session = sqlSessionFactory.openSession();

SqlSession 是操作sql的对象,操作sql肯定会考虑到事务,所以SqlSession会创建事务。

如何操作sql? => CRUD ,所以会有执行器去执行sql, 也就是Executor对象,执行器有三种类型

public enum ExecutorType {
  SIMPLE, // 简单类型
   REUSE, // 重用类型 
   BATCH  // 批量处理类型
}

3)UserMapper mapper = session.getMapper(UserMapper.class);

获取UserMapper 对象,由于UserMapper定义的是接口,没有实现类,所以想要调用方法操作数据库,所以这个对象肯定是代理对象了。mybatis底层使用的是jdk动态代理。

4)User user = mapper.selectById(3);

动态代理调用方法一般都是进入InvocationHandler的invoke方法,到时直接分析invoke方法即可。看mybatis是如何执行sql的

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐