Mybatis入门篇

Mybatis入门教程

在此感谢哔哩哔哩的秦疆老师,up主:遇见狂神说,视频地址: https://www.bilibili.com/video/BV1NE411Q7Nx,于2020-04-05学习后用Typora0.9.98整理的观后感。开发环境:JDK1.8.231,MySQL5.7, maven-3.6.3, IDEA

1 mybatis入门简介

  • Mybatis是一个持久层ORM(Object Relation Map)框架。迭代历史:apache(iBatis) -> google(Mybatis) -> GitHub

  • Hibernate全自动框架,配置文件之后不需要书写SQL语句,但欠缺灵活,优化不便;

    mybatis是半自动框架,需要手动写sql及定义映射,增加了一些操作但带来了设计上的灵活性。且简单易学,本身很小且简单没有三方依赖。

  • mybatis优缺点:(1)解耦:sql与代码分离;(2)逻辑标签控制动态sql拼接;(3)查询结果集与java对象自动映射;

2 第一个mybatis程序

  1. 创建数据库
DROP DATABASE IF EXISTS `demo`;
CREATE DATABASE `demo`
    CHARACTER SET 'utf8'
    COLLATE 'utf8_general_ci';
use 'demo';
drop table if exists mybatis_user;
create table mybatis_user(
    id int(20) not null PRIMARY KEY,
    name varchar(30) default null,
    pwd varchar(30) default null
)ENGINE=INNODB DEFAULT CHARSET=utf8;
  1. 创建一个普通maven项目,引入依赖
1. 新建的工程中删除src目录,使其成空父工程,然后新建module,
2. 新建的module的pom.xml引入maven依赖
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.2</version>
</dependency>
  1. src/resource目录下编写mybatis核心配置文件:mybatis-config.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核心配置文件 注意:属性配置顺序The content of element type "configuration" must match -->
<configuration>

    <!--引用外部配置文件,外部配置文件优先级高于本标签内属性,例如以下的错误密码会被外部属性覆盖-->
    <properties resource="db.properties">
        <property name="password" value="error"/>
    </properties>

    <settings>
        <!-- 指定 MyBatis 所用日志的具体实现 -->
        <!--<setting name="logImpl" value="STDOUT_LOGGING"/>-->
        <!-- 是否开启驼峰命名自动映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 是否开启全局缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
				<!--<property name="driver" value="jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=UTC&amp;useSSL=false"/>--> 
                <!--&amp;为转义符<=>& -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <!-- mappser映射器 每个mapper.xml都需要在mybatis核心配置文件中注册 -->
    <mappers>
        <mapper resource="mybatis/kuangshen/dao/UserMapper.xml"/>
    </mappers>
</configuration>

//db.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/demo?serverTimezone=UTC&useSSL=false
username=root
password=root
  1. 封装构建sqlSessionFactory及从其中获取sqlSession公共步骤封装
public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    //1. 从XML中构建 SqlSessionFactory /或直接从Java代码构建 qlSessionFactory
    static {
        try{
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    //2. 从 SqlSessionFactory 中获取 SqlSession,SqlSession完全包含了面向数据库执行SQL命令的所有方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}
  1. 编写实体类
package mybatis.kuangshen.pojo;
public class User {
    private int id;
    private String name;
    private String pwd;
    ..set/get/toString/有参构造/无参构造
}
  1. 同一目录下编写mapper接口和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接口,id对应namespace中的方法,resultType:SQL执行返回类型, parameterType:参数类型 -->
<mapper namespace="mybatis.kuangshen.dao.UserMapper">
    <select id="getUserList" resultType="mybatis.kuangshen.pojo.User">
        select * from mybatis_user
    </select>
</mapper>
package mybatis.kuangshen.dao;
public interface UserMapper {
    List<User> getUserList();
}
  1. 注册mapper

    每一个mapp都需要在mybatis配置文件中注册,如上代码块3:

  2. 编写测试类

@Test
public static void test1() {
    //1.获取sqlsession对象
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    //2.获取mapper
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    List<User> userList = userMapper.getUserList();
    System.out.println(userList);
    //3.关闭sqlsession
    sqlSession.close();
}
  1. 常见问题
  • MapperRegistry问题:检查类型接口是否在核心配置文件中注册
  • 绑定接口错误
  • 方法名不对
  • 返回类型不对
  • initError,not find resource:maven项目中资源导出问题,< build>标签设置资源导出过滤
  • 编码问题
  • CRUD:增删改注意sqlSession.commit();

3 万能Map及模糊查询扩展

4 mybatis配置

properties(属性),settings(设置),typeAliases(类型别名),typeHandlers(类型处理器),objectFactory(对象工厂),plugins(插件),

environment(环境配置),databaseldProvider(数据库厂商标识),mappers(映射器)

1.3.1 配置之属性优化

5 mybatis缓存cache

  • 缓存[cache]:存在在内存中的临时数据,将用户经常查询的数据放在缓存中,用户查询时不再从磁盘查询而是直接从缓存获取,提高性能。

  • 使用目的:减少和数据库的交互次数,减少系统开销,提高性能。

  • 缓存顺序:先看二级缓存中有没有 -> 再看一级缓存中有没有 -> 查询数据库

  • mybatis默认定义了两级缓存:一级缓存和二级缓存。

    • 默认情况下,只开启了一级缓存(且无法关闭),(sqlsession级别缓存,也称本地缓存);

    • 二级缓存需要手动开启和配置,是基于namespace级别的缓存;

    • 为了提高扩展性,mybatis定义了缓存接口Cache,我们可以通过Cache接口来定义二级缓存。

5.1 mybatis一级缓存(本地缓存)

  • 一级缓存也叫本地缓存(sqlsession级别),与数据库同一次会话期间查询到的数据会放在本地缓存中,若再获取相同数据会直接从缓存中拿;

  • 一级缓存默认是开启的,在一次sqlsession中有效(也就是拿到连接到关闭这个区间段);

  • 缓存失效情况:

    • 查询不同东西;
    • 增删改操作可能会改变原数据,所以必定会刷新缓存
    • 查询不同Mapper.xml
    • 手动清理缓存,如:sqlsession.clearCache();//手动清理缓存
  • 编写mybatis一级缓存案例:

    1. 开启日志(mybatis配置文件中)

      <settings>
          <!-- 指定 MyBatis 所用日志的具体实现 -->
          <setting name="logImpl" value="STDOUT_LOGGING"/>
      </settings>
      
    2. 编写Test

      @Test
      public static void test1() {
          //1.获取sqlsession对象
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          //2.获取mapper
          UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
          System.out.println("===========第一次查询===========");
          List<User> userList1 = userMapper.getUserList();
          System.out.println(userList1);
          System.out.println("===========第二次查询===========");
          List<User> userList2 = userMapper.getUserList();
          System.out.println(userList2);
          System.out.println("比较两个结果是否同一对象:"+ (userList1==userList2) );
          //3.关闭sqlsession
          sqlSession.close();
      }
      
      控制台输出如下/**
      Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
      Class not found: org.jboss.vfs.VFS
      JBoss 6 VFS API is not available in this environment.
      Class not found: org.jboss.vfs.VirtualFile
      VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
      Using VFS adapter org.apache.ibatis.io.DefaultVFS
      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 868737467.
      Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@33c7e1bb]
      ==>  Preparing: select * from mybatis_user 
      ==> Parameters: 
      <==    Columns: id, name, pwd
      <==        Row: 1, name1, pwd1
      <==        Row: 2, name2, pwd2
      <==        Row: 3, name3, pwd3
      <==        Row: 4, name4, pwd4
      <==      Total: 4
      [User{id=1, name='name1', pwd='pwd1'}, User{id=2, name='name2', pwd='pwd2'}, User{id=3, name='name3', pwd='pwd3'}, User{id=4, name='name4', pwd='pwd4'}]
      ===========第二次查询===========
      [User{id=1, name='name1', pwd='pwd1'}, User{id=2, name='name2', pwd='pwd2'}, User{id=3, name='name3', pwd='pwd3'}, User{id=4, name='name4', pwd='pwd4'}]
      比较两个结果是否同一对象:true
      Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@33c7e1bb]
      Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@33c7e1bb]
      Returned connection 868737467 to pool.
      */
      

上一篇:Mybatis(Map)


下一篇:QT 右键弹出菜单