MyBatis框架快速入门

内容列表:
快速开始一个MyBatis
基本CURD的操作
MyBatis内部对象分析
使用Dao对象

入门案例

搭建MyBatis开发环境,实现第一个案例。

使用MyBatis准备

下载MyBatis

https://github.com/mybatis/mybatis-3/releases

搭建MyBatis开发环境

创建mysql数据库和表

数据库名 ssm ;表名 student 。
在这里插入图片描述
创建数据库

CREATE DATABASE `ssm`CHARACTER SET utf8 COLLATE utf8_general_ci; 

创建数据表

CREATE TABLE `student` (
 `id` int(11) NOT NULL ,
 `name` varchar(255) DEFAULT NULL,
 `email` varchar(255) DEFAULT NULL,
 `age` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

手动插入一条数据,方便后续的查询操作
在这里插入图片描述

创建maven工程

创建一个空项目

在这里插入图片描述
在这里插入图片描述

检查设置环境

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

创建模块

在这里插入图片描述
在这里插入图片描述
设置JDK和语言级别
在这里插入图片描述

删除默认创建的App类文件

在这里插入图片描述

修改pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <!--当前项目的坐标-->
  <groupId>com.lln</groupId>
  <artifactId>learnMybatis</artifactId>
  <version>1.0</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!--依赖的列表-->
  <dependencies>
    <!--mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>

    <!--mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>

    <!--单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <!--资源插件 处理src/main/java目录中的xml文件-->
    <resources>
      <resource>
        <directory>src/main/java</directory><!--所在的目录-->
        <includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>

    <!--指定编译插件,可以不用写,因为前面指定了JDK版本-->
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>

  </build>
</project>

创建Student实体类

package com.lln.vo;

public class Student {
    //属性名和数据库表的列名保持一致
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "学生实体的信息:{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

编写 Dao 接口 StudentDao 类

package com.lln.dao;

import com.lln.vo.Student;

public interface StudentDao {

    //查询一个学生
    Student selectStudentById(Integer id);

}

编写 Dao 接口 Mapper 映射文件

创建mapper文件,写sql语句,文件名:StudentDao.xml
目前与StudentDao接口类在同一目录下

<?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:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
-->
<mapper namespace="com.lln.dao.StudentDao">
    <!--
    <select>: 表示查询数据, 标签中必须是 select 语句
    id: 要执行的sql 语句的唯一标识,自定义名称,推荐使用 dao 接口中方法名称
    resultType: 告诉mybatis,执行sql语句后,把数据赋值给哪个类型的java对象,即查询语句的返回结果数据类型,使用全限定类名
    -->
    <select id="selectStudentById" resultType="com.lln.vo.Student">
        <!--要执行的 sql 语句-->
        select id,name,email,age
        from student
        where id=1
        <!--结尾不写分号-->
    </select>
</mapper>

<!--
    1.约束文件
        约束文件作用:定义和限制当前文件中可以使用的标签和属性,以及标签出现的顺序。
    2.mapper是根标签
        namespace:命名空间,必须有值,不能为空,唯一值。
                   推荐使用Dao接口的全限定名称。
             作用:参与识别sql语句。
    3.在mapper里面可以写<insert>,<update>,<delete>,<select>等标签
        <insert>里面是insert语句,表示执行的是insert操作
-->

创建 MyBatis 主配置文件

项目 src/main 下创建 resources 资源目录,设置 resources 目录名为 resources
在这里插入图片描述
在resources目录下创建主配置文件(xml文件),名称为 mybatis.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>
    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象 type: POOLED 使用数据库的连接池-->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <!--driver:驱动的内容-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--
    指定其他mapper文件的位置
    目的是找到其他文件中的sql语句
    -->
    <mappers>
        <!--
        使用mapper的resource属性指定mapper文件的路径
        告诉 mybatis 要执行的 sql 语句的位置
        使用注意:
        resources="mapper文件的路径,使用/分割路径"
        一个mapper resource 指定一个 mapper文件
        -->
        <mapper resource="com/lln/dao/StudentDao.xml"/>
    </mappers>
</configuration>

HTML字符实体

HTML中的预留字符必须被替换为字符实体。

显示结果描述实体名称
&和号&

创建测试类 MybatisTest

package com.lln;

import com.lln.vo.Student;
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.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class MybatisTest {
    //测试mybatis执行sql查询语句
    @Test
    public void testSelectStudentById() throws IOException {
        //调用mybatis某个对象的方法,执行mapper文件中的sql语句
        //mybatis核心类:SqlSessionFactory
        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);
        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();
        //5.指定要执行的sql语句中的id
        //sql的id = namespace+"."+ <select>标签中的id属性值
        //String sqlId = "com.lln.dao.StudentDao"+"."+"selectStudentById";
        String sqlId = "com.lln.dao.StudentDao.selectStudentById";
        //6.通过SqlSession的方法,执行sql语句
        Student student = session.selectOne(sqlId);
        //7.控制台输出
        System.out.println("使用mybatis根据id查询一个学生:"+student);
        //8.关闭 SqlSession,释放资源
        session.close();
    }
}

输出结果:

使用mybatis根据id查询一个学生:学生实体的信息:{id=1, name='张三', email='123@163.com', age=18}

初次使用占位符

修改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">
<!--
 namespace:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
-->
<mapper namespace="com.lln.dao.StudentDao">
    <!--
    <select>: 表示查询数据, 标签中必须是 select 语句
    id: 要执行的sql 语句的唯一标识,自定义名称,推荐使用 dao 接口中方法名称
    resultType: 告诉mybatis,执行sql语句后,把数据赋值给哪个类型的java对象,即查询语句的返回结果数据类型,使用全限定类名
    -->
    <select id="selectStudentById" resultType="com.lln.vo.Student">
        <!--要执行的 sql 语句-->
        select id,name,email,age
        from student
--         where id=1
        where id=#{studentId}
        <!--结尾不写分号-->
        <!--#{studentId} 占位符,表示从java程序中传过来的数据-->
    </select>
</mapper>

<!--
    1.约束文件
        约束文件作用:定义和限制当前文件中可以使用的标签和属性,以及标签出现的顺序。
    2.mapper是根标签
        namespace:命名空间,必须有值,不能为空,唯一值。
                   推荐使用Dao接口的全限定名称。
             作用:参与识别sql语句。
    3.在mapper里面可以写<insert>,<update>,<delete>,<select>等标签
        <insert>里面是insert语句,表示执行的是insert操作
-->

修改测试语句

package com.lln;


import com.lln.vo.Student;
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.junit.Test;

import java.io.IOException;
import java.io.InputStream;


public class MybatisTest {
    //测试mybatis执行sql查询语句
    @Test
    public void testSelectStudentById() throws IOException {
        //调用mybatis某个对象的方法,执行mapper文件中的sql语句
        //mybatis核心类:SqlSessionFactory
        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);
        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();
        //5.指定要执行的sql语句中的id
        //sql的id = namespace+"."+ <select>标签中的id属性值
        //String sqlId = "com.lln.dao.StudentDao"+"."+"selectStudentById";
        String sqlId = "com.lln.dao.StudentDao.selectStudentById";
        //6.通过SqlSession的方法,执行sql语句
        //Student student = session.selectOne(sqlId);
        Student student = session.selectOne(sqlId,1);

        //7.控制台输出
        System.out.println("使用mybatis根据id查询一个学生:"+student);
        //8.关闭 SqlSession,释放资源
        session.close();
    }
}

配置日志功能

mybatis.xml主配置文件中添加setting设置

<?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>
    <!--设置日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池-->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <!--driver:驱动的内容-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--
    指定其他mapper文件的位置
    目的是找到其他文件中的sql语句
    -->
    <mappers>
        <!--
        使用mapper的resource属性指定mapper文件的路径
        告诉 mybatis 要执行的 sql 语句的位置
        使用注意:
        resources="mapper文件的路径,使用/分割路径"
        一个mapper resource 指定一个 mapper文件
        -->
        <mapper resource="com/lln/dao/StudentDao.xml"/>
    </mappers>
</configuration>

再次执行查询测试,输出结果:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1131316523.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
==>  Preparing: select id,name,email,age from student where id=? 
==> Parameters: 1(Integer)
<==    Columns: id, name, email, age
<==        Row: 1, 张三, 123@163.com, 18
<==      Total: 1
使用mybatis根据id查询一个学生:学生实体的信息:{id=1, name='张三', email='123@163.com', age=18}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Returned connection 1131316523 to pool.

Process finished with exit code 0

提交事务

1.自动提交:当sql语句执行完毕后,自动提交事务,数据库更新操作直接保存到数据库。

2.手动提交:在需要提交事务的位置,执行方法,提交事务或者回滚事务。

3.mybatis默认执行sql语句是手动提交事务,在insert,update,delete后需要提交事务

添加数据

接口类添加接口:

package com.lln.dao;

import com.lln.vo.Student;

public interface StudentDao {

    //查询一个学生
    Student selectStudentById(Integer id);

    //添加学生
    //返回值int:影响行数
    int insertStudent(Student student);

}

添加sql语句(mapper映射文件)

<?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:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
-->
<mapper namespace="com.lln.dao.StudentDao">
    <!--
    <select>: 表示查询数据, 标签中必须是 select 语句
    id: 要执行的sql 语句的唯一标识,自定义名称,推荐使用 dao 接口中方法名称
    resultType: 告诉mybatis,执行sql语句后,把数据赋值给哪个类型的java对象,即查询语句的返回结果数据类型,使用全限定类名
    -->
    <select id="selectStudentById" resultType="com.lln.vo.Student">
        <!--要执行的 sql 语句-->
        select id,name,email,age
        from student
        where id=#{studentId}
        <!--结尾不写分号-->
    </select>


    <!--添加操作-->
    <insert id="insertStudent">
        insert into student values(2,"李四","456@163.com",26)
    </insert>


</mapper>

<!--
    1.约束文件
        约束文件作用:定义和限制当前文件中可以使用的标签和属性,以及标签出现的顺序。
    2.mapper是根标签
        namespace:命名空间,必须有值,不能为空,唯一值。
                   推荐使用Dao接口的全限定名称。
             作用:参与识别sql语句。
    3.在mapper里面可以写<insert>,<update>,<delete>,<select>等标签
        <insert>里面是insert语句,表示执行的是insert操作
-->

测试类:

package com.lln;


import com.lln.vo.Student;
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.junit.Test;

import java.io.IOException;
import java.io.InputStream;


public class MybatisTest {
    //测试mybatis执行sql查询语句
    @Test
    public void testSelectStudentById() throws IOException {
        //调用mybatis某个对象的方法,执行mapper文件中的sql语句
        //mybatis核心类:SqlSessionFactory
        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);
        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();
        //5.指定要执行的sql语句中的id
        //sql的id = namespace+"."+ <select>标签中的id属性值
        //String sqlId = "com.lln.dao.StudentDao"+"."+"selectStudentById";
        String sqlId = "com.lln.dao.StudentDao.selectStudentById";
        //6.通过SqlSession的方法,执行sql语句
        //Student student = session.selectOne(sqlId);
        Student student = session.selectOne(sqlId,1);

        //7.控制台输出
        System.out.println("使用mybatis根据id查询一个学生:"+student);
        //8.关闭 SqlSession,释放资源
        session.close();
    }

    //测试mybatis执行sql添加语句
    @Test
    public void testInsertStudent() throws IOException {
        //调用mybatis某个对象的方法,执行mapper文件中的sql语句
        //mybatis核心类:SqlSessionFactory
        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);
        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();
        //5.指定要执行的sql语句中的id
        //sql的id = namespace+"."+ <select>标签中的id属性值
        String sqlId = "com.lln.dao.StudentDao.insertStudent";
        //6.通过SqlSession的方法,执行sql语句
        int rows = session.insert(sqlId);
        //mybatis默认执行sql语句是手动提交事务
        //在insert,update,delete后需要提交事务
        session.commit();

        //7.控制台输出
        System.out.println("使用mybatis添加一个学生,影响行数rows="+rows);
        //8.关闭 SqlSession,释放资源
        session.close();
    }
}

更新数据库查看添加结果:添加成功!
在这里插入图片描述

使用占位符添加数据

修改sql语句(mapper映射文件:StudentDao.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:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
-->
<mapper namespace="com.lln.dao.StudentDao">
    <!--
    <select>: 表示查询数据, 标签中必须是 select 语句
    id: 要执行的sql 语句的唯一标识,自定义名称,推荐使用 dao 接口中方法名称
    resultType: 告诉mybatis,执行sql语句后,把数据赋值给哪个类型的java对象,即查询语句的返回结果数据类型,使用全限定类名
    -->
    <select id="selectStudentById" resultType="com.lln.vo.Student">
        <!--要执行的 sql 语句-->
        select id,name,email,age
        from student
        where id=#{studentId}
        <!--结尾不写分号-->
    </select>


    <!--添加操作-->
    <!--
        如果传给mybatis的是一个对象,使用#{属性名}获取此属性的值。
        属性名放到#{}占位符的位置,mybatis执行此属性的getxxx()方法。
    -->
    <insert id="insertStudent">
        insert into student values(#{id},#{name},#{email},#{age})
    </insert>


</mapper>

<!--
    1.约束文件
        约束文件作用:定义和限制当前文件中可以使用的标签和属性,以及标签出现的顺序。
    2.mapper是根标签
        namespace:命名空间,必须有值,不能为空,唯一值。
                   推荐使用Dao接口的全限定名称。
             作用:参与识别sql语句。
    3.在mapper里面可以写<insert>,<update>,<delete>,<select>等标签
        <insert>里面是insert语句,表示执行的是insert操作
-->

修改测试类

package com.lln;


import com.lln.vo.Student;
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.junit.Test;

import java.io.IOException;
import java.io.InputStream;


public class MybatisTest {
    //测试mybatis执行sql查询语句
    @Test
    public void testSelectStudentById() throws IOException {
        //调用mybatis某个对象的方法,执行mapper文件中的sql语句
        //mybatis核心类:SqlSessionFactory
        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);
        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();
        //5.指定要执行的sql语句中的id
        //sql的id = namespace+"."+ <select>标签中的id属性值
        //String sqlId = "com.lln.dao.StudentDao"+"."+"selectStudentById";
        String sqlId = "com.lln.dao.StudentDao.selectStudentById";
        //6.通过SqlSession的方法,执行sql语句
        //Student student = session.selectOne(sqlId);
        Student student = session.selectOne(sqlId,1);

        //7.控制台输出
        System.out.println("使用mybatis根据id查询一个学生:"+student);
        //8.关闭 SqlSession,释放资源
        session.close();
    }

    //占位符测试mybatis执行sql添加语句
    @Test
    public void testInsertStudent() throws IOException {
        //调用mybatis某个对象的方法,执行mapper文件中的sql语句
        //mybatis核心类:SqlSessionFactory
        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);
        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();
        //5.指定要执行的sql语句中的id
        //sql的id = namespace+"."+ <select>标签中的id属性值
        String sqlId = "com.lln.dao.StudentDao.insertStudent";
        //6.通过SqlSession的方法,执行sql语句
        Student student = new Student();
        student.setId(3);
        student.setName("王五");
        student.setEmail("789@163.com");
        student.setAge(30);

        int rows = session.insert(sqlId,student);
        //mybatis默认执行sql语句是手动提交事务
        //在insert,update,delete后需要提交事务
        session.commit();

        //7.控制台输出
        System.out.println("使用mybatis添加一个学生,影响行数rows="+rows);
        //8.关闭 SqlSession,释放资源
        session.close();
    }
}

运行结果:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 205962452.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
==>  Preparing: insert into student values(?,?,?,?) 
==> Parameters: 3(Integer), 王五(String), 789@163.com(String), 30(Integer)
<==    Updates: 1
Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
使用mybatis添加一个学生,影响行数rows=1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Returned connection 205962452 to pool.

更新数据库查看添加结果:添加成功!
在这里插入图片描述

MyBatis 对象分析

Resources 类

Resources 类,顾名思义就是资源,用于读取主配置资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。

        //1.定义mybatis 主配置文件的位置,从类路径开始的相对路径
        String config = "mybatis.xml";
        //2.读取主配置文件,使用mybatis框架中的Resources类
        InputStream inputStream = Resources.getResourceAsStream(config);

SqlSessionFactoryBuilder 类

创建SqlSessionFactory 对象,需要使用 SqlSessionFactoryBuilder 对象的build()方法。由于 SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将该 SqlSessionFactoryBuilder对象创建为一个方法内的局部对象,方法结束,对象销毁。

        //3.使用SqlSessionFactoryBuilder类创建 SqlSessionFactory 对象,目的是获取 SqlSession
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactory 接口

SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),创建此对象需要更多的资源和时间,是线程安全的,所以一个应用只需要一个该对象即可。

        //4.获取 SqlSession 对象,SqlSession 能执行 sql 语句
        SqlSession session = factory.openSession();

SqlSessionFactory 接口中的方法:

openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的。

  • openSession(true):创建一个有自动提交功能的 SqlSession
  • openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
  • openSession():同 openSession(false)

SqlSession 接口

SqlSession 接口对象用于执行持久化操作。

SqlSession 提供了大量的执行sql语句的方法:
selectOne:执行sql语句,最多得到一行记录,多余是错误。
selectList:执行sql语句,返回多行数据。
selectMap:执行sql语句,得到一个Map结果。
insert:执行insert语句
update:执行update语句
delete:执行delete语句
commit:提交事务
rollback:回顾事务

创建SqlSession 需要使用 SqlSessionFactory 接口的的 openSession() 方法。

一个 SqlSession 对应着一次数据库会话,一次会话以 SqlSession 对象的创建开始,以SqlSession 对象的关闭结束。

SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。

SqlSession 在方法内部创建,使用完毕后关闭。

使用步骤:
1.在方法的内部,执行sql语句之前,先获取SqlSession对象
2.调用SqlSession的方法,执行sql语句
3.关闭SqlSession对象

创建工具类

新建一个模块

在这里插入图片描述
在这里插入图片描述

修改pom.xml文件

同上。

创建resources资源文件夹

同上。

创建实体类

同上。

package com.lln.vo;

public class Student {
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Student实体:{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

创建Dao接口

package com.lln.dao;

import com.lln.vo.Student;

import java.util.List;

public interface StudentDao {

    //根据id查询一个学生
    Student selectById(Integer id);

    //查询全部学生
    List<Student> selectStudents();

    //添加一个学生
    int insertStudent(Student student);
}

创建mapper文件的模板

在这里插入图片描述

使用mapper文件模板

在这里插入图片描述

<?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.lln.dao.StudentDao">
    <!--使用insert、update、delete、select标签写sql语句-->
    <select id="selectById" resultType="com.lln.vo.Student">
        select id,name,email,age
        from student
        where id=#{studentId}
    </select>
    <!--查询全部学生-->
    <select id="selectStudents" resultType="com.lln.vo.Student">
        select id,name,email,age
        from student
    </select>
    <!--添加一个学生-->
    <insert id="insertStudent">
        insert into student values (#{id},#{name},#{email},#{age})
    </insert>
</mapper>

创建主配置文件模板

在这里插入图片描述

使用主配置文件模板

<?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>
    <!--设置日志-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <!--配置 mybatis 环境-->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池-->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <!--driver:驱动的内容-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/lln/dao/StudentDao.xml"/>
    </mappers>
</configuration>

创建工具类MyBatisUtil

package com.lln.utils;

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;

/**
 * 工具类:创建SqlSession对象
 */
public class MyBatisUtil {
    private static SqlSessionFactory factory = null;
    static {
        String config = "mybatis.xml";
        try{
            InputStream inputStream = Resources.getResourceAsStream(config);
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //创建方法,获取SqlSession对象
    public static SqlSession getSqlSession(){
        SqlSession session = null;
        if(factory != null){
            session = factory.openSession();
        }
        return session;
    }
    
}

使用工具类

创建测试类:

package com.lln;

import com.lln.utils.MyBatisUtil;
import com.lln.vo.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class MyTest {

    @Test
    public void testSelectById(){
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.指定sqlId
        String sqlId = "com.lln.dao.StudentDao.selectById";
        //3.执行SqlSession的方法,表示执行sql语句
        Student student = session.selectOne(sqlId,1);
        //4.输出sql语句的执行结果
        System.out.println("查询的结果:"+student);
        //5.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testSelectStudents(){
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.指定sqlId
        String sqlId = "com.lln.dao.StudentDao.selectStudents";
        //3.执行SqlSession的方法,表示执行sql语句
        List<Student> students = session.selectList(sqlId);
        //4.输出sql语句的执行结果
        for(Student stu: students){
            System.out.println("查询的结果:"+stu);
        }
        //5.关闭SqlSession对象
        session.close();
    }


    @Test
    public void testInsertStudent(){
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.指定sqlId
        String sqlId = "com.lln.dao.StudentDao.insertStudent";
        //3.执行SqlSession的方法,表示执行sql语句
        Student student = new Student();
        student.setId(4);
        student.setName("刘备");
        student.setEmail("liubei@163.com");
        student.setAge(55);
        int rows = session.insert(sqlId,student);
        //4.输出sql语句的执行结果
        System.out.println("insert的行数:"+rows);
        //5.提交事务
        session.commit();
        //6.关闭SqlSession对象
        session.close();
    }

}

运行结果1:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1131316523.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
==>  Preparing: select id,name,email,age from student where id=? 
==> Parameters: 1(Integer)
<==    Columns: id, name, email, age
<==        Row: 1, 张三, 123@163.com, 18
<==      Total: 1
查询的结果:Student实体:{id=1, name='张三', email='123@163.com', age=18}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Returned connection 1131316523 to pool.

运行结果2:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1131316523.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
==>  Preparing: select id,name,email,age from student 
==> Parameters: 
<==    Columns: id, name, email, age
<==        Row: 1, 张三, 123@163.com, 18
<==        Row: 2, 李四, 456@163.com, 26
<==        Row: 3, 王五, 789@163.com, 30
<==        Row: 4, 刘备, liubei@163.com, 55
<==      Total: 4
查询的结果:Student实体:{id=1, name='张三', email='123@163.com', age=18}
查询的结果:Student实体:{id=2, name='李四', email='456@163.com', age=26}
查询的结果:Student实体:{id=3, name='王五', email='789@163.com', age=30}
查询的结果:Student实体:{id=4, name='刘备', email='liubei@163.com', age=55}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Returned connection 1131316523 to pool.

运行结果3:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 205962452.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
==>  Preparing: insert into student values (?,?,?,?) 
==> Parameters: 4(Integer), 刘备(String), liubei@163.com(String), 55(Integer)
<==    Updates: 1
insert的行数:1
Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Returned connection 205962452 to pool.

使用传统的dao执行sql

创建接口的实现类

package com.lln.dao.impl;

import com.lln.dao.StudentDao;
import com.lln.utils.MyBatisUtil;
import com.lln.vo.Student;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class StudentDaoImpl implements StudentDao {
    @Override
    public Student selectById(Integer id) {
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.指定sqlId
        String sqlId = "com.lln.dao.StudentDao.selectById";
        //3.执行SqlSession的方法,表示执行sql语句
        Student student = session.selectOne(sqlId,id);
        //4.关闭SqlSession对象
        session.close();
        return student;
    }

    @Override
    public List<Student> selectStudents() {
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.指定sqlId
        String sqlId = "com.lln.dao.StudentDao.selectStudents";
        //3.执行SqlSession的方法,表示执行sql语句
        List<Student> students = session.selectList(sqlId);
        //4.关闭SqlSession对象
        session.close();
        return students;
    }

    @Override
    public int insertStudent(Student student) {
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.指定sqlId
        String sqlId = "com.lln.dao.StudentDao.insertStudent";
        //3.执行SqlSession的方法,表示执行sql语句
        int rows = session.insert(sqlId,student);
        //4.输出sql语句的执行结果
        System.out.println("insert的行数:"+rows);
        //5.提交事务
        session.commit();
        //6.关闭SqlSession对象
        session.close();
        return rows;
    }
}

测试类

package com.lln;

import com.lln.dao.StudentDao;
import com.lln.dao.impl.StudentDaoImpl;
import com.lln.vo.Student;
import org.junit.Test;

import java.util.List;

public class MyTest2 {

    @Test
    public void testSelectOne(){
        //要使用dao的方法
        //接口类型  变量  =   new   接口的实现类();
        StudentDao dao = new StudentDaoImpl();
        Student student = dao.selectById(1);
        System.out.println("通过dao执行方法得到的对象:"+student);
    }


    @Test
    public void testSelectStudents(){
        StudentDao dao = new StudentDaoImpl();
        List<Student> students = dao.selectStudents();
        students.forEach(stu-> System.out.println("stu="+stu));
    }


    @Test
    public void testInsert(){
        StudentDao dao = new StudentDaoImpl();
        Student student = new Student();
        student.setId(5);
        student.setName("关羽");
        student.setEmail("guanyu@163.com");
        student.setAge(50);
        dao.insertStudent(student);
    }

}

运行结果

运行结果1:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1131316523.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
==>  Preparing: select id,name,email,age from student where id=? 
==> Parameters: 1(Integer)
<==    Columns: id, name, email, age
<==        Row: 1, 张三, 123@163.com, 18
<==      Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Returned connection 1131316523 to pool.
通过dao执行方法得到的对象:Student实体:{id=1, name='张三', email='123@163.com', age=18}

运行结果2:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 1131316523.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
==>  Preparing: select id,name,email,age from student 
==> Parameters: 
<==    Columns: id, name, email, age
<==        Row: 1, 张三, 123@163.com, 18
<==        Row: 2, 李四, 456@163.com, 26
<==        Row: 3, 王五, 789@163.com, 30
<==        Row: 4, 刘备, liubei@163.com, 55
<==        Row: 5, 关羽, guanyu@163.com, 50
<==      Total: 5
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@436e852b]
Returned connection 1131316523 to pool.
stu=Student实体:{id=1, name='张三', email='123@163.com', age=18}
stu=Student实体:{id=2, name='李四', email='456@163.com', age=26}
stu=Student实体:{id=3, name='王五', email='789@163.com', age=30}
stu=Student实体:{id=4, name='刘备', email='liubei@163.com', age=55}
stu=Student实体:{id=5, name='关羽', email='guanyu@163.com', age=50}

运行结果3:

Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 205962452.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
==>  Preparing: insert into student values (?,?,?,?) 
==> Parameters: 5(Integer), 关羽(String), guanyu@163.com(String), 50(Integer)
<==    Updates: 1
insert的行数:1
Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@c46bcd4]
Returned connection 205962452 to pool.

更新数据库查看添加结果:
在这里插入图片描述

MyBatis的代理说明

package com.lln;

import com.lln.dao.StudentDao;
import com.lln.dao.impl.StudentDaoImpl;
import com.lln.vo.Student;
import org.junit.Test;

import java.util.List;

public class MyTest2 {
    /**
     *测试方法中,调用dao的方法
     * Student student = dao.selectById(1);
     *
     * 1.dao:通过反射能够得到全限定类名称
     *      dao是StudentDao类型的,全限定名称com.lln.dao.StudentDao
     * 2.selectById:dao中的方法名称,方法名称就是mapper文件中的标签id
     *      通过dao.selectById()能够得到 sqlId="com.lln.dao.StudentDao.selectById";
     * 3.确定调用SqlSession的哪个方法
     *      (1).根据接口的方法返回中,如果返回时一个对象,例如student,调用SqlSession.selectOne();
     *            如果dao接口中的方法返回List,调用SqlSession的selectList();
     *       (2).根据mapper文件中的标签,如果标签是<insert>,调用SqlSession.insert()方法
     *
     * mybatis框架,发现使用dao的方法调用能确定执行sql语句的必要信息,mybatis简化dao对象的实现
     * 由mybatis框架在程序执行期间,根据dao接口,创建一个内存中的实现类对象
     * mybatis把这个技术叫做dao动态代理
     *
     * dao代理技术:由mybatis创建StudentDao接口的实现类Proxy(StudentDaoImpl),使用框架创建的StudentDaoImpl代替
     * 自己手工实现的StudentDaoImpl类的功能,不用开发人员写dao接口的实现类。
     */
    @Test
    public void testSelectOne(){
        //要使用dao的方法
        //接口类型  变量  =   new   接口的实现类();
        StudentDao dao = new StudentDaoImpl();
        Student student = dao.selectById(1);
        System.out.println("通过dao执行方法得到的对象:"+student);
    }


    @Test
    public void testSelectStudents(){
        StudentDao dao = new StudentDaoImpl();
        List<Student> students = dao.selectStudents();
        students.forEach(stu-> System.out.println("stu="+stu));
    }


    @Test
    public void testInsert(){
        StudentDao dao = new StudentDaoImpl();
        Student student = new Student();
        student.setId(5);
        student.setName("关羽");
        student.setEmail("guanyu@163.com");
        student.setAge(50);
        dao.insertStudent(student);
    }

}

使用代理的要求

  1. mapper 文件中的 namespace 必须是dao接口的全限定名称。
  2. mapper 文件中的标签 id 是 dao 接口中的方法名称。
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值