目录

mybatis入门

官方入门演示

HelloWorld

数据准备

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-- 创建员工表
create table tbl_employee(
	id INT(11) PRIMARY KEY auto_increment,
	last_name VARCHAR(255),
	gender char(1),
	email VARCHAR(255)
);

-- 准备数据
insert into tbl_employee(last_name, gender, email) values('tom', 0, 'tom@gmail.com');

引入maven依赖

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<dependencies>
        <!-- mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <!-- mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.29</version>
        </dependency>
 			 <!-- 引入日志包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.7</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.7</version>
        </dependency>
    </dependencies>

java代码

  1. employee.java

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    package com.eh.eden.mybatis.orm.bean;
       
    import lombok.Data;
       
    @Data
    public class Employee {
       
        private Integer id;
        private String lastName;
        private String gender;
        private String email;
    }
    
  2. 日志配置文件 logback.xml

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scanPeriod="60 seconds" debug="false">
       
        <property name="APP_NAME" value="java8"/>
        <property name="LOG_HOME" value="/tmp/com.eh"/>
       
        <contextName>${APP_NAME}</contextName>
       
        <timestamp key="dt" datePattern="yyyyMMdd HH:mm:ss"/>
       
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
       
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>${dt} [%thread] %highlight(%-5level) %cyan(%logger{50}) - %msg%n</pattern>
            </encoder>
            <withJansi>true</withJansi>
        </appender>
       
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${LOG_HOME}/${APP_NAME}.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${LOG_HOME}/${APP_NAME}.%d.log</FileNamePattern>
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <MaxFileSize>10MB</MaxFileSize>
            </triggeringPolicy>
        </appender>
       
        <!--myibatis log configure-->
        <logger name="org.apache.ibatis" level="TRACE" />
        <logger name="java.sql.Connection" level="DEBUG"/>
        <logger name="java.sql.Statement" level="DEBUG"/>
        <logger name="java.sql.PreparedStatement" level="DEBUG"/>
       
        <root level="TRACE">
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="FILE"/>
        </root>
    </configuration>
    
  3. mybatis配置文件 mybatis-config.xml

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    <?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文件 必须放在最前面,否则会报错 -->
        <properties resource="db.properties"></properties>
       
        <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="EmployeeMapper.xml"/>
        </mappers>
    </configuration>
    
  4. db.properties

    1
    2
    3
    4
    5
    
    driver=com.mysql.jdbc.Driver
    # 防止乱码
    url=jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true
    username=root
    password=333
    
  5. sql映射文件 EmployeeMapper.xml

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    <?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.eh.eden.mybatis.orm.EmployeeMapper">
       
       
        <!--
            id: 唯一标识
            resultType: 返回值类型
            #{id}: 从传递过来的参数中取出id值
        -->
        <select id="selectEmp" resultType="com.eh.eden.mybatis.orm.bean.Employee">
            select id, last_name lastName, gender, email from tbl_employee where id = #{id}
        </select>
       
    </mapper>
    
  6. 测试

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    package com.eh.eden.mybatis.orm.dao;
       
    import com.eh.eden.mybatis.orm.bean.Employee;
    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 org.testng.annotations.Test;
       
    import java.io.IOException;
    import java.io.InputStream;
       
    public class EmployeeServiceTest {
       
        @Test
        public void test() throws IOException {
            // 1. 根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
       
            // 2. 从 SqlSessionFactory 中获取 SqlSession,能直接执行已经映射的sql语句
            try (SqlSession session = sqlSessionFactory.openSession()) {
                Employee employee = session.selectOne("com.eh.eden.mybatis.orm.EmployeeMapper.selectEmp", 1);
                System.out.println(employee);
            }
        }
    }
       
    // 输出
    [TestNG] Running:
      /Users/david/Library/Caches/IntelliJIdea2019.1/temp-testng-customsuite.xml
    Employee(id=1, lastName=tom, gender=0, email=tom@gmail.com)
    

接口式编程

  1. 增加接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    package com.eh.eden.mybatis.orm.dao;
       
    import com.eh.eden.mybatis.orm.bean.Employee;
       
    public interface EmployeeMapper {
       
        Employee getEmployeeById(Integer id);
       
    }
    
  2. 修改sql映射文件

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    <?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.eh.eden.mybatis.orm.dao.EmployeeMapper">
       
        <!--
            id: 唯一标识
            resultType: 返回值类型
            #{id}: 从传递过来的参数中取出id值
        -->
        <select id="getEmployeeById" resultType="com.eh.eden.mybatis.orm.bean.Employee">
            select id, last_name lastName, gender, email from tbl_employee where id = #{id}
        </select>
       
    </mapper>
    

    namespace 改成接口全限定名

    id改成方法名

  3. 测试

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
    package com.eh.eden.mybatis.orm.dao;
       
    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 org.testng.annotations.Test;
       
    import java.io.IOException;
    import java.io.InputStream;
       
    public class EmployeeMapperTest {
       
        public SqlSessionFactory getSqlSessionFactory() throws IOException {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            return new SqlSessionFactoryBuilder().build(inputStream);
        }
       
        @Test
        public void test() throws IOException {
            // 1. 获取SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
       
            // 2. 从 SqlSessionFactory 中获取 SqlSession,能直接执行已经映射的sql语句
            try (SqlSession session = sqlSessionFactory.openSession()) {
                // 3. 获取接口实现类对象
                // mybatis会为接口自动创建一个代理对象,代理对象去执行增删改查方法
                EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
                System.out.println(employeeMapper.getEmployeeById(1));
            }
        }
    }
    // 输出
    [TestNG] Running:
      /Users/david/Library/Caches/IntelliJIdea2019.1/temp-testng-customsuite.xml
    Employee(id=1, lastName=tom, gender=0, email=tom@gmail.com)
    

总结

  1. 接口式编程

    原生:Dao->DaoImpl

    接口式编程:xxMapper->xxMaper.xml

  2. SqlSession代表和数据库的一次会话,用完必须关闭

  3. SqlSession和connection一样都是非线程安全,每次使用都应该获取新的对象

  4. mapper接口没有实现类,但是mybati会为这个接口生成一个代理对象

    将接口和xml进行绑定

    EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);

  5. 两个重要的配置文件

    1. mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等系统运行环境信息
    2. sql映射文件:保存了每一个sql语句的映射信息