MyBatis 简明教程

简介

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

入门案例

下面列举一个简单例子,来阐述 MyBatis 的常用操作。

例子:假设数据库school内部有一张表students,我们希望能使用 MyBatis 来实现对student表的增删改查操作。

具体步骤如下:

  • 首先,我们先创建数据库school和表students,并插入一些预备数据:
# 创建数据库 school
create database if not exists school;
# 使用数据库 school
use school;
# 创建表 student
create table if not exists students (
    -> id int primary key auto_increment,
    -> name varchar(20) not null,
    -> sex varchar(6) default "male",
    -> cls int not null);
# 插入一些数据
insert into students(id,name,sex,cls) values(1,"小明","male",1);
insert into students values(2,"小红","female",2);
insert into students(name,sex,cls) values("小芳","female",2);
insert into students(name,cls) values("小宁",4);

经过上面操作后,students表就存储了如下内容:

MyBatis 简明教程_第1张图片
students
  • 创建一个使用 Maven 作为依赖管理的普通 Java 工程,如下图所示:
MyBatis 简明教程_第2张图片
  • 在 pom.xml 中添加依赖:必须添加的是 MyBatis 依赖和 mysql-connector 驱动依赖,同时这里我们也添加一个 log4j 依赖,用以配置日志输出:
    
        
            org.mybatis
            mybatis
            3.5.1
        

        
            mysql
            mysql-connector-java
            8.0.16
        

        
            log4j
            log4j
            1.2.17
        
    

然后在主工程resources资源目录下,创建一个配置文件:log4j.properties,进行日志信息配置:

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# 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
  • 接下来,继续在主工程resources目录下创建一个全局的 MyBatis 配置文件,该文件可任意命名,我们这里将其命名为:MyBatisConfig.xml,具体内容如下:



    
    
        
        
            
            
            
            
                
                
                
                
                
            
        
    

可以看到,上述全局配置表主要完成的是对开发环境和 MySql 连接信息的配置。

  • 要想使用 MyBatis 完成对具体某一张表的操作,我们还需要为这张表的相关操作创建相应接口和配置文件,并在全局配置表中将相关配置文件具体内容进行注入。具体操作如下:

1)创建表对应的 POJO 类:

package com.yn.bean;

import java.io.Serializable;

/**
 * @author Whyn
 * @date 7/16/2019 5:37 PM
 */
public class Student implements Serializable {
    private String name;
    private String sex;
    private int cls;

/**
 * 
 *
 * 必须创建一个默认构造函数,否则就需要构造一个映射器,比如
 *     
 *        
 *            
 *             
 *             
 *         
 *     
  */
    public Student(){

    }
    public Student(String name, String sex, int cls) {
        this.name = name;
        this.sex = sex;
        this.cls = cls;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getCls() {
        return cls;
    }

    public void setCls(int cls) {
        this.cls = cls;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", cls=" + cls +
                '}';
    }
}

2)创建对表操作的相应接口:

package com.yn.interfaces;

import com.yn.bean.Student;

import java.util.List;

public interface IStudentsDao {
    //    增:添加学生
    void add(Student student);

    //    删:删除学生
    void delete(String name);

    //    改:更改信息
    void update(String name);

    //    查:查询所有
    List selectAll();
}

3)在主工程资源目录resources下,创建对表操作的配置信息(对于每一个 Dao,都创建对应包名目录的配置文件,比如:com.yn.interfaces.IStudentsDao,则创建对应配置文件:com/yn/interfaces/IStudentsDao.xml):





    
        insert into students(name,sex,cls) values(#{name},#{sex},#{cls})
    

    
        delete from students where name=#{name}
    

    
        update students set sex=#{sex},cls=#{cls} where name=#{name}
    

    

标签中的namespace表示表对应接口类,各个数据库操作的属性id表示接口类对应的方法名。因此,由namespace + id就可以唯一确定对应的操作方法。

4)创建完对表的操作配置文件后,还需在全局配置文件中注入该配置文件,因此,全局配置表完整内容如下:




    
    
        
            
            
            
            
                
                
                
                
                
            
        
    

    
    
        
        
    

5)最后,就可以通过代码对数据库表进行操作,代码如下所示:

public class Main {

    public static void main(String[] args) throws IOException {
//        加载全局配置文件
        InputStream config = Resources.getResourceAsStream("MyBatisConfig.xml");
//        创建工厂类
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(config);
//        由工厂创建得到操作数据库表的 SqlSession 对象
        SqlSession session = factory.openSession();
//        得到表操作代理对象
        IStudentsDao studentsDaoProxy = session.getMapper(IStudentsDao.class);
//        增:添加学生
        Student student = new Student("Whyn", "male", 7);
        studentsDaoProxy.add(student);
        session.commit();

//        删:删除学生
        studentsDaoProxy.delete("Whyn");
        session.commit();

//        改:更改信息
        student = new Student("小明", "male", 8);
        studentsDaoProxy.update(student);
        session.commit();
//        查:查询所有
        List students = studentsDaoProxy.selectAll();
//        释放资源
        session.close();
        config.close();
    }
}

:此处我们使用的是 MyBatis 推荐的基于动态代理生成IUserDao代理实例进行数据库操作,当然也可以自己通过实现具体的IStudentsDao实例对数据库进行操作,其原理就是在具体实现类内部创建SqlSession实例进而操作数据库,具体做法此处就不进行展开了。

以上,就是使用 MyBatis 对数据库进行操作的基本操作过程了。

全局配置文件

下面对 MyBatis 的全局配置文件(即:MyBatisConfig.xml)中的常用配置选项进行讲解:

:以下所讲解的属性配置均位于大标签内部。

  • properties:这些属性都是外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过properties元素的子元素来传递。例如:

    
    
    
    

然后其中的属性就可以在整个配置文件中被用来替换需要动态配置的属性值。比如:


  
  
  
  

但是,properties更常用的方式是读取外部配置文件,通过属性resource/url指定外部配置文件即可,具体操作如下:
1)在resources目录下,创建一个配置文件:db.properties,内容如下:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/school?serverTimezone=GMT
jdbc.username=root
jdbc.password=password

2)然后在全局配置文件(MyBatisConfig.xml)中进行导入并配置:



    

    
        
            ...
            
                
                
                
                
                
            

        
    
    ...

:如果同一个属性property在多个地方都定义了,那么其读取顺序为:标签properties内部指定的属性 > resource/url 属性中指定的配置文件 > 方法参数。因此,方法参数的优先级最高。

  • typeAliases:类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:


    

另一种更简便的配置别名的方法是使用标签package:MyBatis 会自动搜索package标签指定包名下面的所有 Java Bean,并将别名设置为其类名:



    

:使用package标签后,如果不想使用类名作为别名,则可以在使用@Alias注解自定义别名:

@Alias("student")
public class Student{
    ...
}

最后,就可以在任何使用com.yn.bean.Student的配置文件中,更改为使用别名:



    
        insert into students(name,sex,cls) values(#{name},#{sex},#{cls})
    

    
        update students set sex=#{sex},cls=#{cls} where name=#{name}
    

    


MyBatis 中已经为我们内置了许多 Java 类型的别名,具体如下表所示:

Alias Mapped Type
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator
  • mappers:映射器配置文件内部定义了 SQL 映射语句,因此我们需要将这些映射文件告诉 MyBatis,可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。例如:


  
  
  




  
  
  




  
  
  




  

映射器配置文件

下面对 MyBatis 的配置 SQL 映射语句的映射文件(即:IStudentsDao.xml)中的常用配置选项进行讲解:

  • select: 映射查询语句,如下所示:

这个语句被称作selectPerson,接受一个int(或Integer)类型的参数,并返回一个HashMap类型的对象,其中的键是列名,值便是结果行中的对应值。

select * from students where 1=1 and name=#{name} and sex=#{sex} and class=#{cls} // IStudentsDaoTest.java @Test public void testFindStudentsByCondition() { ... Student student = new Student(); student.setSex("male"); student.setCls(4); List students = this.studentsDaoProxy.findStudentsByCondition(student); for(Student stu: students){ System.out.println(stu); } }

  • where:见名知意,该标签用于替换 where 子句。正如我们上面那个例子,如果直接使用 where 子句进行 if 判断,我们需要手动添加一个为”真“的条件,这样当 if 判断失败时,还能确保 SQL 语句的正确性,但使用 where 标签,就可以省略这冗余操作:
    
  • foreach:动态 SQL 的另一个常用操作就是对一个集合进行遍历,通常实在构建 IN 条件语句时使用。比如:
// StudentVo.java
public class StudentVo {
    private List studentIds;

    public List getStudentIds() {
        return studentIds;
    }

    public void setStudentIds(List studentIds) {
        this.studentIds = studentIds;
    }
}

// IStudentDao.java
public interface IStudentsDao {
    ...
    List findStudentsInIds(StudentVo vo);
}

// IStudentDao.xml

    ...
    



// IStudentDaoTest.java
    @Test
    public void testFindStudentsInIds() {
        List ids = Arrays.asList(1,2,3,4);
        StudentVo vo = new StudentVo();
        vo.setStudentIds(ids);
        List students = this.studentsDaoProxy.findStudentsInIds(vo);
        for(Student student : students){
            System.out.println(student);
        }
    }

foreach 标签中的collection属性用于指定集合对象,在我们上面的例子里就是StudentVo.studentIdsopen+item+separator+close组合而成我们的SQL 查询语句,上面完整的 SQL 语句如下:

select * from students where id in (1,2,3,4);

  • sql:该标签可以抽取出重复 SQL 语句,用于复用。如下所示:

    select * from students


更多动态 SQL 标签,请查看:dynamic-sql

数据库表间关联

在关系型数据中,表与表之间存在三种关系:一对一,一对多(多对一)和多对多。下面我们分别针对这三种关联关系给出具体配置。

前提:还是以上文入门案例作为示例,入门案例中已有一张表students,下面我们再创建一张表classes,并将字段stu_id作为指向表students.id的外键:

CREATE TABLE IF NOT EXISTS `classes` (
    -> `id` int(11) NOT NULL AUTO_INCREMENT,
    -> `name` VARCHAR(10) NOT NULL,
    -> `stu_id` int NOT NULL,
    -> PRIMARY KEY (`id`),
    -> KEY `stu_id` (`stu_id`),
    -> CONSTRAINT `stu_id` FOREIGN KEY (`stu_id`) REFERENCES `students` (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建完表classes后,顺便插入几条数据:

insert into classes(name,stu_id) values('一班',1);
insert into classes(name,stu_id) values('二班',2);
insert into classes(name,stu_id) values('三班',3);
insert into classes(name,stu_id) values('四班',4);

然后,修改下students表:
1)先将表students的字段cls改为class_id

alter table students change column cls class_id int not null;

2)然后将其列class_id修改为指向表classes.id的外键:

# 禁用外键约束
set foreign_key_checks=0;
# 修改列
alter table students add constraint class_id foreign key(class_id) refererences classes(id);
# 启用外键约束
set foreign_key_checks=1;

至此,现数据库中总共有2张表:studentsclasses,且students.class_id指向表classes.id,表classes.stu_id指向表students.id

最后,在 MyBatis 中以代码方式实现对表classes的操作,完整代码如下:

// com.yn.bean.Classes.java
public class Classes implements Serializable {
    private int id;
    private String name;
    private int studentId;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }

    @Override
    public String toString() {
        return "Classes{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", studentId=" + studentId +
                '}';
    }
}

// com.yn.interfaces.IClassesDao.java
public interface IClassesDao {
//    查:查询所有
    List selectAll();
}

// 全局配置文件:MyBatis.xml

    ...
    
    
        
    


// resources/com/yn/interfaces/IClassesDao.xml
...

    
        
        
        
    

    

到此,我们的准备工作已算完成了,接下来就可以开始进入 MyBatis 建立表关联操作的实操。

  • 一对一关联:一个学生对应一个班级,因此,学生表students与班级表classes的关联关系即为一对一。具体到 MyBatis 中,这种关联体现的实现步骤如下:
  1. students对应的 POJO 类为Student,每个学生对应一个班级,因此,学生和班级的一对一关联关系在 Java 代码的体现只需为类Student内部添加一个Classes成员即可:
// com.yn.bean.Student.java
public class Student implements Serializable {
    private String name;
    private String sex;
    private int classId;

//    一对一关联:一个学生对应一个班级
    private Classes cls;
    ...
    public Classes getCls() {
        return cls;
    }

    public void setCls(Classes cls) {
        this.cls = cls;
    }
    ...
  1. 然后配置映射文件使用标签association表示一对一关联:

    ...
    
        
        
        
        
        
        
            
            
            
            
            
        

    

    
    ...

到这里,我们就已经完成了一对一关联关系表的建立。

  • 一对多关联:一个班级可以有多个学生,因此班级表classes与学生表students的关系即为一对多关系。具体到 MyBatis 中,一对多的关联实现步骤如下所示:
  1. 由于一个班级有多个学生,此种一对多的关系在 Java 代码的体现就是:类Classes内部维护一个Students集合:
// com.yn.bean.Classes.java
public class Classes implements Serializable {
    private int id;
    private String name;
    private int studentId;

//    一对多关联:一个班级有多个学生
    private List students;

    public List getStudents() {
        return students;
    }

    public void setStudents(List students) {
        this.students = students;
    }
    ...
}
  1. 然后配置映射文件中使用标签collection表示一对多关联:
// resources/com/yn/interfaces/IClassesDao.xml

    
        
        
        
        
        
        
        
        
            
            
            
        
    

    


到这里,我们就已经完成了一对多关联关系的建立。

在讲解 多对多关联 前,我们先创建2张表:

  1. 老师表teachers,用于存储教师信息:
create table if not exists teachers (
    -> id int primary key auto_increment,
    -> name varchar(20) not null,
    -> sex varchar(10) default 'male'
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 插入一些数据
insert into teachers(name,sex) values('张三','male');
insert into teachers(name,sex) values('李四','female');
insert into teachers(name,sex) values('王五','male');
  1. 然后需要再创建一张中间表(因为多对多关联需要一张中间表进行连接),称为:stu_tea,其内部之包含两个字段:sidtid,分别作为指向表studnets.id和表teachers.id的外键:
create table if not exists `stu_tea` (
    -> `sid` int not null,
    ->  `tid` int not null,
    ->  primary key (`sid`,`tid`),
    -> foreign key (`sid`) references `students` (`id`),
    -> foreign key (`tid`) references `teachers` (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# 插入一些数据
insert into stu_tea (sid,tid) values (1,1),(1,3),(2,2),(4,1),(4,2);
  • 多对多关联: 一个学生可以有多个老师,一个老师也可以有多个学生。因此,老师与学生的关系是多对多关联。
  1. 首先从老师角度来说,其对应多个学生,在 Java 代码上的体现为:POJO 类Teacher内部维护一个Student集合,完整代码如下:
// com.yn.bean.Teacher.java
public class Teacher implements Serializable {
    private int id;
    private String name;
    private String sex;

//    多对多关联:一个老师对应多个学生
    private List students;
    
    public List getStudents() {
        return students;
    }

    public void setStudents(List students) {
        this.students = students;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    } 

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

// com.yn.interfaces.ITeacherDao.java
public interface ITeacherDao {

    List selectAll();
}

// 全局配置文件:resources/MyBatisConfig.xml

    ...
    
        
    


// com.yn.interfaces.ITeacherDao.xml

    
        
        
        
        
            
            
            
            
            
        
    

    


// junit test
@Test
public void selectAll() {
    List teachers = this.teacherDaoProxy.selectAll();
    for(Teacher teacher: teachers){
        System.out.println(teacher);
        for(Student s : teacher.getStudents()){
            System.out.println(s);
        }
    }
}
  1. 从学生角度来讲,其对应多个老师,在 Java 代码上的体现为:POJO 类Student内部维护一个Teacher集合:
// com.yn.bean.Student.java
public class Student implements Serializable {
    private String name;
    private String sex;
    private int classId;
//    一对一关联:一个学生对应一个班级
    private Classes cls;

//    多对多关联:一个学生对应多个老师
    private List teachers;

    public List getTeachers() {
        return teachers;
    }

    public void setTeachers(List teachers) {
        this.teachers = teachers;
    }
    ...
}

// com.yn.interfaces.IStudentsDao.xml

    ...
    
        
        
        
        
            
            
            
            
        
    

    
    ...


// junit test
@Test
public void testSelectAll() throws IOException {
    List students = this.studentsDaoProxy.selectAll();
    for (Student student : students) {
        System.out.println(student);
        for(Teacher teacher : student.getTeachers()){
            System.out.println(teacher);
        }
    }
}

到此,MyBatis 中对于数据库表间的关联关系处理已基本完成。

关联表加载模式

首先了解下两个概念:

  • 立即加载:表间关联时,加载主表时,同时加载关联表。
  • 延迟加载:也即按需加载,关联表数据只有在使用到的时候,才进行加载。

正如我们上文提到的关系型数据库中,各表间可能存在一定的关联关系。比如一对多关联时,当我们查询主表数据时,此时对于关联表而言,就存在两种操作:
1)立即加载:查询主表数据时,同时也对关联表数据进行查询。即主副表查询是同步的。
2)延迟加载:查询主表数据时,不进行关联表数据查询。后续要使用到关联表数据时,才进行查询。即主副表查询是异步的。

通常而言,对于 N对一 的关联关系,建议使用 立即加载(可认为关联表数据量小)。
对于 N对多 的关联关系,建议使用 延迟加载(可认为关联表数据量大)。

在 MyBatis 中,开启延迟加载的步骤如下:

  1. 首先在全局配置文件中开启全局延迟加载模式:
// resources/MyBatisConfig.xml


    
    
    
        
        
        
        
    
    ...

  1. 通过提供select属性,配置关联表的数据获取(延迟)方法,因为是关系型数据库,关联表的数据获取通常都是通过主表的外键作为其参数,所提提供的方法的参数即为主表外键值,其由column属性指定。

比如,按上文学生表students和班级表classes的一对一关联来说,其配置如下:
1)因为要开启延迟加载,因此主表(即表students)操作(SQL 语句)不需要考虑关联表:



2)然后,关联表(即表classes)要提供关联查询方法,因主表(即表students)是通过外键(class_id)关联副表(即表classes),因此副表需要提供selectById(int cid)方法:

// com.yn.interfaces.IStudentsDao.java
public interface IClassesDao {

//    查:查询所有
    List selectAll();

//    提供通过班级id 关联查询方法
    Classes selectById(Integer cid);
}



    
        
        
        
    

    
 

3)最后,通过select属性和column属性为主表提供副表数据获取(延迟加载)方法:



    
    
    
    
    
    
    

到此,N对一 的配置就完成了。

而对于 N对多 的配置,其与 N对一 的配置是基本一致的。
比如还是按上文班级表classes和学生表students来说,他们是一对多的关系,即一个班级对应多个学生,那么其关联关系在 MyBatis 中的配置具体如下:
1)配置班级表classes数据获取 SQL 语句:



2)配置表students依据班级id获取学生数据方法:

// com.yn.interfaces.IStudentsDao.java
public interface IStudentsDao {
    // 一个班级 cid 对应多个学生
    List selectById(Integer cid);
}



    
        
            
            
            
        
        
    

    
    ...

3)最后,为主表配置副表数据加载方法:



    
    
    
    
    

至此,N对多 的延迟加载特定已配置完成。

:我们上面在全局配置表中开启了全局延迟加载模式,所以对于所有的关联表,默认都会开启延迟加载,但是可以通过为标签association/collection添加fetchType来显示覆盖全局配置,其取值有两个:eager表示立即加载,lazy表示延迟加载。

比如,我们前面也提到过,对于 N对一 关联的数据库表,通常使用的是立即加载模式,那么我们就可以按如下配置,启动立即加载:



    
    
    

    
    

缓存

对访问频繁且不常变化的数据进行缓存,可以减少与数据库的交互,提高执行效率。

MyBatis 为我们提供了两种缓存功能:

  • 一级缓存:也成为 本地缓存,由SqlSession对象实例负责缓存。使用同一个SqlSession实例进行同一查询,后续的查询结果都是从一级缓存中获取。但该SqlSession实例销毁时,缓存随之销毁。

:对于一级缓存而言,其有如下特性:

  1. 一级缓存默认开启
  2. 一级缓存其实内部是一个Map结构,其缓存的是对象实例(相应 POJO 类实例)
  3. 但调用SqlSession的增加,修改,删除,commit(),close()等方法时,其一级缓存会被清空
  • 二级缓存:由SqlSessionFactory对象实例负责缓存。由同一个SqlSessionFactory实例生产的SqlSession对象实例共享该二级缓存。

:对于二级缓存而言,其有如下特性:

  1. 二级缓存默认不开启。手动开启方法如下:
    1)全局配置文件中开启二级缓存(可选操作,因为默认已开启):


    ...
    
        
        
    
    ...

2)在当前配置映射文件中开启二级缓存:



    
    
    ...

3)在当前数据库操作中开启二级缓存(注:POJO 类需要实现序列化接口):



    ...
    
    
    ...

  1. 二级缓存工作机制:在会话中,进行查询只会将结果保存到一级缓存中。只有当会话关闭时,才会将一级缓存的内容保存到二级缓存中(序列化)。
  2. 二级缓存缓存的是数据(即序列化),也即 SQL 操作从二级缓存获取数据后,再重新组装成对象实例(序列化)。而一级缓存直接缓存的就是对象实例。

其他

下面列举一些常用配置具体实现:

  • 主键自增回填:对于插入(insert)语句,如果数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server):比如我们上文入门案例中的使用自增字段id作为表students的主键。那么此时,可以设置 useGeneratedKeys=”true”,然后再把keyProperty设置到目标属性上,这样,当插入完成后,数据库生成的主键就会回填到该对象的主键属性上:

    insert into students(name,sex,cls) values(#{name},#{sex},#{cls})

如果数据库还支持多行插入,那么我们可以传入一个Student数组或者集合,并返回自动生成的主键:

public interface IStudentsDao {
    ...
    void addAll(List students);
    ...
}




    insert into students(name,sex,cls) values
    
        (#{stu.name},#{stu.sex},#{stu.cls})
    

  • 结果映射:通常来说,我们自定义的 Java Bean 的成员应该与数据库表的字段名称一致,这样 MyBatis 就能自动地帮我们进行数据转换。但在实际开发中,往往会出现 Java Bean 的成员名称与数据库表字段名称不一致的情况:比如,我们将上文入门案例的数据库表studentscls字段更改为class
alter table students change column cls class int not null;

现在,Student的成员cls就无法匹配数据库表studentsclass字段了,我们先查看下表students的内容:

MyBatis 简明教程_第3张图片

然后我们在运行一下获取操作:selectAll(),结果如下所示:

MyBatis 简明教程_第4张图片

可以看到,数据库的class字段获取不到了。因此,这里我们需要配置Studentcls成员到数据库表studentsclass字段的映射:比如,我们可以通过更改 Sql 语句来让数据库表students.class字段映射到Student.cls


但是,Sql 语句的配置会显得繁琐些,尤其当需要配置字段较多的时候,因此,MyBatis 已经为我们提供了相关方法(resultMap)解决这个问题,其具体配置如下所示:


    
    
        
        
        
        
    

    

其实就是配置一个resultMap,并将该resultMap放置到所需方法中即可。

你可能感兴趣的:(MyBatis 简明教程)