Mybatis学习笔记

Posted 想成为大师啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习笔记相关的知识,希望对你有一定的参考价值。

环境:

  • JDK 1.8
  • mysql 5.7(Mysql 8.0)
  • maven 3.6.1
  • IDEA

回顾:

  • JDBC
  • Mysql
  • Java基础
  • Maven
  • Junit

SSM框架:配置文件的。最好的方式:看官方文档


1、简介

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

Mybatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了Google Code,并且改名为Mybatis。2013年11月迁移到Github

如何获得Mybatis

  • Maven仓库
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.9</version>
    </dependency>
    
  • Github:https://github.com/mybatis/mybatis-3/releases
  • 中文文档:https://mybatis.org/mybatis-3/zh/index.html

持久化

  • 数据持久化:持久化就是将程序的数据在持久状态和瞬时状态转化的过程
    • 瞬时状态:类似于内存,断电即失
    • 持久状态:只要不删库,数据可以一直在
  • 数据库(JDBC),IO文件持久化
  • 生活:冷藏、罐头、…
  • 持久化的原因:有一些对象,不能让他丢掉(类似生活中的微信、支付宝余额,王者的点卷,…),主要原因:内存太贵了

持久层

  • Dao层、Service层、Controller层
    • 完成持久化工作的代码块
    • 层是界限十分明显

为什么需要Mybatis

  • 方便
  • 传统的JDBC代码太复杂了;因为简化,所以框架,自动化
  • 帮助程序猿将数据存入到数据库中
  • 不用Mybatis也可以。更容易上手

优点:

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射。
  • 提供对象关系映射标签,支持对象关系组建维护。
  • 提供xml标签,支持编写动态sql。

最重要的一点:使用的人多!!!


2、第一个Mybatis程序

思路:搭建环境 -> 导入Mybatis -> 编写代码 -> 测试

搭建环境

  • 搭建数据库
    • 建库:
      CREATE DATABASE 'mybatis';
      USE 'mybatis';
      
    • 建表:
      CREATE TABLE 'user'(
      	'id' INT(20) NOT NULL PRIMARY KEY,
      	'name' VARCHAR(30) DEFAULT NULL,
      	'pwd' VARCHAR(30) DEFAULT NULL
      )ENGINE=INNODB DEFAULT CHARSET=utf8;
      
    • 插入数据:
      INSERT INTO 'user' ('id', 'name', 'pwd') VALUES
      (1, 'root', '123456'),
      (2, 'huake', '123'),
      (3, 'zya', '123456')
      

数据库的几种引擎:

  • MyISAM:默认的MySQL插件式存储引擎,它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。注意,通过更改STORAGE_ENGINE配置变量,能够方便地更改MySQL服务器的默认存储引擎。
  • InnoDB:用于事务处理应用程序,具有众多特性,包括ACID事务支持。(提供行级锁)
  • BDB:可替代InnoDB的事务引擎,支持COMMIT、ROLLBACK和其他事务特性。
  • Memory:将所有数据保存在RAM中,在需要快速查找引用和其他类似数据的环境下,可提供极快的访问。
  • Merge:允许MySQL DBA或开发人员将一系列等同的MyISAM表以逻辑方式组合在一起,并作为1个对象引用它们。对于诸如数据仓储等VLDB环境十分适合。
  • Archive:为大量很少引用的历史、归档、或安全审计信息的存储和检索提供了完美的解决方案。
  • Federated:能够将多个分离的MySQL服务器链接起来,从多个物理服务器创建一个逻辑数据库。十分适合于分布式环境或数据集市环境。
  • Cluster/NDB:MySQL的簇式数据库引擎,尤其适合于具有高性能查找要求的应用程序,这类查找需求还要求具有最高的正常工作时间和可用性。
  • Other:其他存储引擎包括CSV(引用由逗号隔开的用作数据库表的文件),Blackhole(用于临时禁止对数据库的应用程序输入),以及Example引擎(可为快速创建定制的插件式存储引擎提供帮助)。

一般来说不使用事务的话,请使用MyISAM引擎,使用事务的话,一般使用InnoDB

新建项目:

  • 1、新建一个普通的maven项目
  • 2、删除src目录
  • 3、导入maven依赖
    <!-- 父工程 -->
    <groupId>org.example</groupId>
    <artifactId>Mybatis_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <!-- 导入依赖 -->
    <dependencies>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
    
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    
        <!-- mybatis -->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
    </dependencies>
    

创建一个模块:

  • 编写mybatis的核心配置文件

    <?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: 核心配置文件 -->
    <configuration>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&amp;serverTimezone=GMT%2B8"/>
                    <property name="username" value="root"/>
                    <property name="password" value="zya11230318"/>
                </dataSource>
            </environment>
        </environments>
    </configuration>
    
  • 编写mybatis的工具类

    package com.zya.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.*;
    import lombok.NoArgsConstructor;
    import org.springframework.beans.factory.annotation.Autowired;
    
    @AllArgsConstructor
    @NoArgsConstructor
    // 实体类
    @Data
    public class User 
    
        private int id;
        private String name;
        private String pwd;
    
    
    
  • Dao接口

    package com.zya.dao;
    
    import com.zya.pojo.User;
    
    import java.util.List;
    
    public interface UserDao 
        List<User> getUserList();
    
    
  • 接口实现类由原来的UserDaoImpl转变为一个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接口 -->
    <mapper namespace="com.zya.dao.UserDao">
    
        <!-- select: 查询语句 -->
        <!-- 绑定接口方法 -->
        <select id="getUserList" resultType="com.zya.pojo.User">
            select * from mybatis.userone;
        </select>
    </mapper>
    
  • pom.xml

    <!--在build中配置resources,来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
    

测试
注意点:org.apache.ibatis.binding.BindingException: Type interface com.zya.dao.UserDao is not known to the MapperRegistry.

import com.zya.dao.UserDao;
import com.zya.pojo.User;
import com.zya.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class MyTest 
    @Test
    public void test()
        // 第一步: 获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        // 方式一: getMapper
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();

        // 方式二 不推荐使用
//        List<User> userList = sqlSession.selectList("com.zya.dao.UserDao.getUserList");


        for (User user:userList) 
            System.out.println(user);
        
        // 关闭SqlSession
        sqlSession.close();
    

MapperRegistry是什么?

  • 核心配置文件中注册mappers
  • junit测试

可能遇到的问题:

  • 1、配置文件没有注册
  • 2、绑定接口错误
  • 3、方法名不对
  • 4、返回类型不对
  • 5、Maven导出资源问题

3、CRUD

1、namespace

  • namespace中的包名要和Dao/Mapper接口的包名一致
  • 选择、查询语句
  • id:就是对应的namespace中的方法名
  • resultType:Sql语句执行的返回值!
  • parameterType:参数类型

2、select、insert、update、delete

  • 编写接口

    package com.zya.dao;
    
    import com.zya.pojo.User;
    
    import java.util.List;
    
    public interface UserMapper 
        // 查询全部用户
        List<User> getUserList();
        // 根据id查询用户
        User getUserById(int id);
        // 插入用户
        int addUser(User user);
        // 修改用户
        int updateUser(User user);
        // 删除一个用户
        int deleteUser(int id);
    
    
  • 编写对应的mapper中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接口 -->
    <mapper namespace="com.zya.dao.UserMapper">
        <!-- select: 查询语句 -->
        <!-- 绑定接口方法 -->
        <select id="getUserList" resultType="com.zya.pojo.User">
            select * from mybatis.userone;
        </select>
        <select id="getUserById" resultType="com.zya.pojo.User" parameterType="int">
            select * from mybatis.userone where id=#id;
        </select>
        <!-- 对象中的属性, 可以直接取出来 -->
        <insert id="addUser" parameterType="com.zya.pojo.User">
            insert into mybatis.userone (id, name, pwd) values (#id, #name, #pwd)
        </insert>
        <update id="updateUser" parameterType="com.zya.pojo.User">
            update mybatis.userone set name=#name,pwd=#pwd where id=#id;
        </update>
        <delete id="deleteUser" parameterType="int">
            delete from mybatis.userone where id=#id;
        </delete>
    </mapper>
    
  • 测试

    import com.zya.dao.UserMapper;
    import com.zya.pojo.User;
    import com.zya.utils.MybatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.util.List;
    
    public class MyTest 
        @Test
        public void test()
            // 第一步: 获得SqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try 
                // 方式一: getMapper
                List<User> userList = sqlSession.getMapper(UserMapper.class).getUserList();
                // 方式二:
    //        List<User> userList = sqlSession.selectList("com.zya.dao.UserMapper.getUserList");
                for (User user:userList) 
                    System.out.println(user);
                
            catch (Exception e)
                e.printStackTrace();
            finally 
                // 关闭SqlSession
                sqlSession.close();
            
        
    
        @Test
        public void test01()
            // 第一步: 获得SqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try 
                // 方式一: getMapper
                User user = sqlSession.getMapper(UserMapper.class).getUserById(2);
                System.out.println(user);
            catch (Exception e)
                e.printStackTrace();
            finally 
                // 关闭SqlSession
                sqlSession.close();
            
        
    
        // 增删改需要提交事务
        @Test
        public void test02()
            // 第一步: 获得SqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try 
                // 方式一: getMapper
                int res = sqlSession.getMapper(UserMapper.class).addUser(new User(5, "admin", "123456"));
                // 提价事务
                sqlSession.commit();
            catch (Exception e)
                e.printStackTrace();
            finally 
                // 关闭SqlSession
                sqlSession.close();
            
        
    
        @Test
        public void test03()
            // 第一步: 获得SqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try 
                // 方式一: getMapper
                int res = sqlSession.getMapper(UserMapper.class).updateUser(new User(5, "admin", "123"));
                // 提价事务
                sqlSession.commit();
            catch (Exception e)
                e.printStackTrace();
            finally 
                // 关闭SqlSession
                sqlSession.close();
            
        
    
        @Test
        public void test04()
            // 第一步: 获得SqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try 
                // 方式一: getMapper
                int res = sqlSession.getMapper(UserMapper.class).deleteUser(5);
                // 提价事务
                sqlSession.commit();
            catch (Exception e)
                e.printStackTrace();
            finally 
                // 关闭SqlSession
                sqlSession.close();
            
        
    
    

注意点:增删改需要提交事务!!!


分析错误

  • 标签不要匹配错
  • resource绑定mapper,需要使用路径
  • 程序配置文件必须符合规范!
  • NullPointException,没有注册到资源!
  • 输出的xml文件中存在中文乱码问题
  • maven资源没有导出问题

万能Map

假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map

dao接口

public interface UserMapper 
    // 万能的Map
    int addUser2(Map<String, Object> map);

UserMapper.xml

<!--
    对象中的属性, 可以直接取出来
    传递map中的key
 -->
<insert id="addUser2" parameterType="map">
    insert into mybatis.userone (id, name, pwd) values (#userId, #userName, #userPwd);
</insert>

Test.java

@Test
public void test05()
    // 第一步: 获得SqlSession对象
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    try 
        Map<String, Object> map = new HashMap<String, Object>(java学习笔记 --- 面向对象

[笔记]Boosting和Bagging

MyBatis学习笔记11:解决字段名和属性的映射关系

Mybatis学习笔记导航

springmvc+mybatis学习笔记(汇总)

mybatis学习笔记(14)-spring和mybatis整合