1.简介

关于 Mybatis 框架的介绍请记住如下要点:

  • Mybatis 是互联网时代流行的 ORM 框架。
  • ORM (Object-Relation Mapping)定义:是一种编程技术,能够实现面向编程语言与关系型数据库之间的数据映射;面向编程语言:常见的如 java、python 等;关系型数据库:常见的如 mysql、oracle;
  • Mybatis 是作用于数据层(Dao),可以用来简化 JDBC 操作,实现数据的持久化;

2.入门案例

我们先通过一个实际案例,了解下搭建一个 Mybatis 框架的基本步骤,具体过程如下:

  • 第一步:在开发工具 IDEA 中创建一个 Maven 工程,在 pom.xml 文件中引入如下 jar 包;
 <!--Mybatis依赖的 jar 包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
<!--访问数据库的JDBC-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>
  • 第二步:在 mysql 数据库中创建一个表,建表语句如下所示:
create table employee
(
    emp_id int not null comment '员工编号'
        primary key,
    emp_name varchar(50) not null comment '员工姓名',
    sex varchar(10) not null comment '性别',
    dept_id int not null comment '部门编号',
    manager int null comment '经理编号',
    hire_date date not null comment '入职日期',
    job_id int not null comment '职位编号',
    salary decimal(8,2) not null comment '月薪',
    bonus decimal(8,2) null comment '奖金',
    email varchar(100) not null comment '电子邮箱'
)comment '员工表';
  •  第三步:创建与表 employee 具有映射关系的实体类 Employee;
package com.entity;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 类注释
 *
 * @author Lenovo
 * @Title: Employee
 * @ProjectName mybatisYG
 * @Description: TODO 与表  employee 对应
 * @date 2019/11/1314:58
 */
public class Employee {
    //员工编号
    private int empId;
    //员工姓名
    private String empName;
    //员工性别
    private String sex;
    //部门编号
    private int deptId;
    //部门经理编号
    private int manager;
    //入职日期
    private Date date;
    //职位编号
    private int jobId;
    //员工月薪
    private BigDecimal salary;
    //员工奖金
    private BigDecimal bonus;
    //员工邮箱
    private String email;

    @Setter
    @Getter
    @toString
}
  •  第四步:创建实体类 Employee 和表 employee 一一对应的映射文件 employeeMapper.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">
<!--namespace为映射mapper文件的全路径名,不要写.xml后缀-->
<mapper namespace="com.entity.employeeMapper">
    <select id="queryEmployeeById" resultType="com.entity.Employee" parameterType="int">
select emp_id empId,emp_name empName,sex,dept_id deptId,manager,hire_date date,
job_id jobId,salary,bonus,email from employee where emp_id =  #{empId}
    </select>
</mapper>

 对以上配置文件说明如下:

        ★★namespace:值应该为 Mapper 文件的全路径名,注意不要写 .xml后缀;

        ★★select标签: id 代表唯一区分此SQL的标记,原则上可以随意命名,resultType代表 sql 查询结果的返回值类型,parameterType 为 sql语句中 where 查询条件的数据类型,例如 int;

        ★★当表中定义的字段与映射实体类中的属性命名不一致时,必须采用别名,将数据库字段映射为实体类属性,例如 employee 表的 emp_id 被映射为实体类 Employee 的属性 empId;

        ★★注意 where 条件中的参数写法 #{},{}里面的值为实体类的属性值,例如 #{empId};

          

  • 第五步:创建 Mybatis 的配置文件 mybatis-config.xml 文件,文件建议新建在 Resources 文件夹下,配置的具体内容如下所示:

  

<?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="prod"><!--与 id 值保持一致-->
        <environment id="prod"><!--与 defaule 值保持一致-->
            <transactionManager type="JDBC"/><!--数据库事务的处理方式,默认为 JDBC-->
            <dataSource type="POOLED"><!--数据库连接池类型保持默认值 POOLED-->
                <!--配置数据库信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/><!--数据库驱动方式,需要导入 JDBC驱动的 jar 包-->
                <property name="url" value="jdbc:mysql://localhost:3306/db?serverTimezone=UTC"/><!--数据库 URL 地址-->
                <property name="username" value="root"/><!--数据库用户名-->
                <property name="password" value="root"/><!--数据库密码-->
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载映射文件,为对应的mapper.xml 文件所在的路径,中间用 / 间隔-->
        <mapper resource="com/entity/employeeMapper.xml"/>
    </mappers>
</configuration>

     ★★注意:当数据库驱动采用的是 com.mysql.cj.jdbc.Driver时,此时数据库 URL 后面必须增加 ?serverTimezone=UTC,否则报错;

  •  第六步:编写测试类,测试类内容如下:
package com.entity;

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.Reader;

/**
 * 类注释
 *
 * @author Lenovo
 * @Title: TestEmployee
 * @ProjectName mybatisYG
 * @Description: TODO 测试下简单的查询案例
 * @date 2019/11/1317:26
 */
public class TestEmployee {
    public static void main(String[] args) throws Exception {
        //第一步:加载 Mybatis-config.xml 文件,并使用 字符串输入流 Reader 进行读取;
        Reader reader = Resources.getResourceAsReader( "mybatis-config.xml" );
        //第二步:创建 SqlSession 的单例工厂
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build( reader );
        //第三步:创建访问数据库的Session--connection
        SqlSession session = sessionFactory.openSession();
        //第四步:找到 待操作的 mapper.xml文件中待执行的 sql 语句,通过 namespace和 select 标签中的id进行定位;
        String statement = "com.entity.employeeMapper.queryEmployeeById";
        //第五步:执行 SQL 语句
        Employee employee = session.selectOne( statement, 2 );
        System.out.println( "职工编号为1的员工的基本信息为::" + employee );
        //第六步:关闭会话
        session.close();

    }
}

 3.初步搭建案例错误集锦以及解决方案

  • 第一个错误:找不到实体类定义的 mapper.xml 文件,具体报错信息如下:
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/entity/employeeMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/entity/employeeMapper.xml
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:52)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:36)
    at com.entity.TestEmployee.main(TestEmployee.java:24)
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/entity/employeeMapper.xml
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:99)
    at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:50)
    ... 2 more
Caused by: java.io.IOException: Could not find resource com/entity/employeeMapper.xml
    at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114)
    at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:371)
    at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119)
    ... 4 more

错误导致原因:在于 maven 工程的 pom.xml 文件中缺少配置,使得编译的时候在 target 目录下加载不到  mapper.xml 文件;

错误解决方案:需要在 pom.xml 文件中增加如下配置;

<build>
        <!-- 定义classpath -->
        <resources>
            <!-- resources文件 -->
            <resource>
                <directory>src/main/resources</directory>
                <!-- 是否被过滤,如果被过滤则无法使用 -->
                <filtering>false</filtering>
            </resource>
            <!-- java文件夹 -->
            <resource>
                <directory>src/main/java</directory>
                <!-- 引入映射文件等 -->
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>
  • 第二个错误:采用的数据库驱动与数据库 URL 不匹配导致的报错,具体报错信息如下所示:
Caused by: com.mysql.cj.core.exceptions.InvalidConnectionAttributeException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

错误导致原因:Mysql 依据版本不同,会采用不同的驱动,包括 com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver,当采用的驱动是 com.mysql.cj.jdbc.Driver 时,此时对应的数据库 URL 地址必须指定时区;

错误解决方法:给 URL 地址加上时区;

  <property name="url" value="jdbc:mysql://localhost:3306/db?serverTimezone=UTC"/><!--数据库 URL 地址,此对应的驱动为 com.mysql.cj.jdbc.Driver-->
  <property name="url" value="jdbc:mysql://localhost:3306/db"/><!--此 URL 对应的驱动为 com.mysql.jdbc.Driver-->