MyBatis学习一:入门

文章目录

      • MyBatis简介
      • MyBatis入门
        • 1、安装mybatis
        • 2、从 XML 中构建 SqlSessionFactory
        • 3、从 SqlSessionFactory 中获取 SqlSession
        • 4、探究已映射的 SQL 语句
        • 5、作用域(Scope)和生命周期
      • 实战:创建mybatis程序
        • 1、创建maven项目
        • 2、创建mybatis环境
        • 3、编写代码
        • 4、可能出现的问题

MyBatis简介

MyBatis logo

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • 中文文档:https://mybatis.org/mybatis-3/zh/index.html

MyBatis入门

1、安装mybatis

使用 Maven 来构建项目,在 pom.xml 文件中添加mybatis的jar包依赖

<dependency>
  <groupId>org.mybatisgroupId>
  <artifactId>mybatisartifactId>
  <version>3.5.5version>
dependency>

2、从 XML 中构建 SqlSessionFactory

  • 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
  • SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
  • SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
    • 使用类路径下的资源文件进行配置。
    • 也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。
    • MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  • XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)


<configuration>
  <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="org/mybatis/example/BlogMapper.xml"/>
  mappers>
configuration>
  • 注意 XML 头部的声明,它用来验证 XML 文档的正确性。
  • environment 元素体中包含了事务管理和连接池的配置。
  • mappers 元素则包含了一组映射器(mapper),这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息。

3、从 SqlSessionFactory 中获取 SqlSession

  • 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
  • 使用和指定语句的参数和返回值相匹配的接口(比如 BlogMapper.class)
  • SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
try (SqlSession session = sqlSessionFactory.openSession()) {
     
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
}

4、探究已映射的 SQL 语句

  • 语句可以通过 XML 定义
    • 在一个 XML 映射文件中,可以定义无数个映射语句,
    • 该命名就可以直接映射到在命名空间中同名的映射器类


<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  select>
mapper>
  • 使用 Java 注解来配置
    • 使用注解来映射简单语句会使代码显得更加简洁,
    • 但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让你本就复杂的 SQL 语句更加混乱不堪
package org.mybatis.example;
public interface BlogMapper {
     
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}
  • 将已映射的 select 语句匹配到对应名称、参数和返回类型的方法。
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);

5、作用域(Scope)和生命周期

  • SqlSessionFactoryBuilder

    • 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
    • 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
    • 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。
  • SqlSessionFactory

    • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
    • 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。
    • 因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
  • SqlSession

    • 每个线程都应该有它自己的 SqlSession 实例。

    • SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。

    • 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。

    • 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。

      • 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。

        try (SqlSession session = sqlSessionFactory.openSession()) {
                   
          // 你的应用逻辑代码
        }
        
  • 映射器实例

    • 映射器是一些绑定映射语句的接口。

    • 映射器接口的实例是从 SqlSession 中获得的。

    • 虽然从技术层面上来讲,任何映射器实例的最大作用域与请求它们的 SqlSession 相同。但方法作用域才是映射器实例的最合适的作用域

    • 也就是说,映射器实例应该在调用它们的方法中被获取,使用完毕之后即可丢弃。 映射器实例并不需要被显式地关闭。尽管在整个请求作用域保留映射器实例不会有什么问题,但是你很快会发现,在这个作用域上管理太多像 SqlSession 的资源会让你忙不过来。 因此,最好将映射器放在方法作用域内。

      try (SqlSession session = sqlSessionFactory.openSession()) {
               
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        // 你的应用逻辑代码
      }
      

实战:创建mybatis程序

1、创建maven项目

1.1 使用IDEA创建一个maven项目

MyBatis学习一:入门_第1张图片

2、创建mybatis环境

2.1 在maven项目的pom.xml文件中引入mybatis和mysql的依赖

<dependencies>
    
    <dependency>
        <groupId>org.mybatisgroupId>
        <artifactId>mybatisartifactId>
        <version>3.5.5version>
    dependency>
    
    
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.49version>
    dependency>
dependencies>

2.2 建立子模块,并在resources文件夹下创建mybatis-config.xml配置文件




<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://192.168.153.129:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            dataSource>
        environment>
    environments>
    
    <mappers>
        <mapper resource="mapper/user/UserMapper.xml"/>
    mappers>
configuration>

2.3 创建MybatisUtils的工具类

package com.example.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;

/**
 * @description: mybatis的工具类
 */
public class MybatisUtils {
     

    /**
     * 定义sqlSessionFactory对象
     */
    private static SqlSessionFactory sqlSessionFactory;

    static {
     
        try {
     
            // 使用mybatis获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
     
            e.printStackTrace();
        }
    }

    /**
     * 通过sqlSessionFactory获取SqlSession实例
     *
     * @return SqlSession
     */
    public static SqlSession getSqlSession() {
     
        return sqlSessionFactory.openSession();
    }
}

3、编写代码

3.1 在数据库中创建mybatis数据库和user表

# 创建mybatis数据库
CREATE DATABASE `mybatis`;

# 使用mybatis数据库
USE `mybatis`;

# 创建user表
CREATE TABLE `user` (
	`id` INT (20) NOT NULL PRIMARY KEY,
	`name` VARCHAR (50) DEFAULT NULL,
	`password` VARCHAR (255) DEFAULT NULL 
) ENGINE = INNODB DEFAULT CHARSET = utf8;

# 插入数据
INSERT INTO `user` ( `id`, `name`, `password` )
VALUES
	( 1, '张三', '123456' ),
	( 2, '李四', '123456' ),
	( 3, '王五', '123456' )

3.2 在domain包下,建立用户实体类

package com.example.user.domain;

/**
 * @description: 用户实体类
 */
public class User {
     

    /** 用户ID */
    private Integer id;
    /** 用户名称 */
    private String name;
    /** 用户密码 */
    private String password;

	// getter,setter
}

3.3 在mapper包下,创建用户持久层接口

package com.example.user.mapper;

import com.example.user.domain.User;

import java.util.List;

/**
 * @description: 用户持久层接口
 */
public interface UserMapper {
     

    /**
     * 获取用户列表集合
     *
     * @return List 用户集合
     */
    List<User> listUsers();
}

3.4 在resources的mapper包下创建用户持久层接口的XML文件




<mapper namespace="com.example.user.mapper.UserMapper">
    <select id="listUsers" resultType="com.example.user.domain.User">
        select * from mybatis.user
    select>
mapper>

3.5 在test包中创建测试类

package com.example.user;

import com.example.user.domain.User;
import com.example.user.mapper.UserMapper;
import com.example.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * @description: 用户测试类
 */
public class UserMapperTest {
     

    @Test
    public void testListUsers() {
     

        // 1、获取sqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        // 2、getMapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.listUsers();
        for (User user : users) {
     
            System.out.println(user.toString());
        }

        // 3、关闭sqlSession
        sqlSession.close();
    }
}

输出结果

User{
     id=1, name='张三', password='123456'}
User{
     id=2, name='李四', password='123456'}
User{
     id=3, name='王五', password='123456'}

4、可能出现的问题

问题一:因为接口的配置文件中出现了注释,导致乱码的原因

org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/ghh/dao/UserDao.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance.  Cause: com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。

解决方法:在pom.xml中加入

<properties>
	<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>

问题二:找不到resources资源文件下的xml文件

Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/shao/mapping/userMapper.xml

原因:maven由于它的约定大于配置,配置文件无法被导出或者生效

解决方法:在build中配置resources,来防止资源导出失败

<build>
    <resources>
        <resource>
            <directory>src/main/resourcesdirectory>
            <includes>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>truefiltering>
        resource>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>truefiltering>
        resource>
    resources>
build>

问题三:找不到mapper的注册中心

org.apache.ibatis.binding.BindingException: Type interface com.example.user.mapper.UserMapper is not known to the MapperRegistry.

原因:没有在mybatis的配置中心注册mapper

解决方法:在pom.xml中加入mapper

<mappers>
    <mapper resource="mapper/user/UserMapper.xml"/>
mappers>

你可能感兴趣的:(mybatis,mybatis,mysql)