遇见狂神说JAVA笔记 --- Mybatis 学习

Posted 小智RE0

tags:

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

传送门==>B站遇见狂神说–Mybatis教程


感谢狂神,学习视频真的是通俗易懂♥♥♥

笔记和练习只是跟着视频整理的;有的知识点并没有整理进来

ML


1.什么是 Mybatis

首先学习Mybatis; 可以使用到的参考Mybatis中文文档
https://mybatis.org/mybatis-3/zh/index.html
MyBatis中文文档

MyBatis 持久层框架,支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作
MyBatis 可以通过简单的 XML注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

简单来说就是封装了一些方法;之前写项目的某些步骤可以省略.

历史由来

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis2013年11月迁移到Github

本人使用的版本情况
jdk — 1.8版本;
mysql — 8.0.22 版本
Maven — 3.8.1 版本
Tomcat — 9.0.48 版本


1.1如何获取/下载Mybatis

(1)可以在GitHub下载
GitHub官网==>https://github.com/

搜索Mybatis即可

https://github.com/search?q=Mybatis

(2) 可以在Maven仓库下载
maven仓库官网:==>https://mvnrepository.com/

搜索Mybatis即可;

https://mvnrepository.com/search?q=Mybatis

一般选择使用人数较多的版本;比较稳定

我选择了3.4.6 版本的
Maven依赖如下所示

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

1.2 什么是持久化,持久层

也就是数据持久化;将程序的数据在 持久状态和瞬时状态之间转化;

内存有个特点就是 断电即丢失;有的重要对象或者信息,如果丢失就很危险.

数据库,JDBC,IO 文件都有持久化.

持久层就是完成持久化工作的代码块;在项目中,层与层之间的界限是比较明显的.


1.3 为什么需要Mybatis

由于传统的JDBC优点复杂;那么简化它 ;Mybatis就出现了;
可以帮助程序员将数据存到数据库.
其实主要是懂原理,再使用这些框架就比较容易;

它比较简单;导入两个jar文件;配置几个sql映射文件就能上手了;
sql写在xml里,便于统一管理


2. 入门Mybatis框架,先写个查询用户

2.1 首先是搭建环境

2.1.1先创建一个数据库;建个数据表,一会儿要对数据库进行操作;顺便存入几行数据

-- 创建数据库;
CREATE DATABASE IF NOT EXISTS `day2021_9_6_studyMybatis_db`;
-- 创建用户表;
CREATE TABLE `user`(
       `id` INT(20) NOT NULL PRIMARY KEY,
       `name` VARCHAR(10) DEFAULT NULL,
       `password` VARCHAR(10) DEFAULT NULL
       )ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入数据;
INSERT INTO `user`
VALUES
  (1, '小智', '123456'),
  (2, '杰哥', '111111'),
  (3, '阿猫', '222222'),
  (4, '点金手','666666'),
  (5, '特工', '555555');

2.1.2 新建一个普通的maven项目;

注意项目名尽量不要用中文;之前有次我创建maven项目;用中文写项目名;进去爆红了…

记得在Filesetting设置中检查maven的地址;有时候它会切到 IDEA 自带的maven地址;
(好像之前改过默认地址了…,有时候还是会自动切换到IDEA的地址)


2.1.3 把创建的项目中的src目录删掉;那么这个项目就作为父级工程


2.1.4 导入项目需要的相关依赖;

在父级工程导入依赖;子级工程也能继承使用过去.

数据库连接驱动(我使用的是自己的8.0.22对应的版本);mybatis持久层框架;测试使用的junit包

pom.xml文件

<!--数据库连接驱动;mybatis持久层框架;测试使用的junit包-->
    <dependencies>
        <!--数据库连接驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <!--Mybatis-->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--测试使用junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

2.2 创建一个模块,子级工程

在之前创建的项目处新建一个 Moudle 模块;仍然创建的是一个普通的maven项目;

那么,项目创建好了;作为子级项目,不用再去写依赖导包了,嘿嘿;

pom.xml文件还有显示它的父级

点击右边的maven;可以看到;子级项目study01继承了刚才在Study-Mybatis01中导入的包


2.2.1需要编写Mybatis的核心配置文件

在项目study01的src下的resources目录下创建文件mybatis-config.xml文件;

注意在写url的时候,后面设置的属性连接符号&需要转义;&amp;

<?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>
    <!--environments:配置的环境,可以配置多个-->
    <environments default="development">
        <environment id="development">
            <!--transactionManager:事务管理;这里默认使用JDBC-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--加载连接数据库的重要字段属性-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/day2021_9_6_studyMybatis_db?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true&amp;serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--每个mapper都需要在核心配置文件中注册-->
    <mappers>
        <mapper resource="com/xiaozhi/dao/UserMapper.xml"/>
    </mappers>
</configuration>

2.2.2 编写需要的工具类

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。
也可理解为工厂模式;

如果说每次操作都要去读取一下配置文件;是比较麻烦的,那么就写个工具类把要使用的的功能封装起来吧;每次操作去调用工具类;

utils目录下创建工具类MybatisUtils

好了,写工具类吧

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

public class MybatisUtils {
    private  static SqlSessionFactory sqlSessionFactory=null;
    //在调用工具类时就执行;
    static {
        try {
            //获取SqlSessionFactory对象;

            //获得配置文件;
            String resource = "mybatis-config.xml";
            //使用流读取资源;
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //加载资源流;
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //从 SqlSessionFactory 中获取 SqlSession;
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }  
}

2.3 编写代码吧

2.3.1 首先需要创建实体类.

一般来说,将实体类存放在创建的pojo目录或者eneity目录中;
实体类的属性对应数据库的对应数据表的对应字段;
由于要和数据库对应,那么就注意属性的数据类型要一致;可不要把数值型的字段给写成字符串类型的或者别的一些错误.
基本上这些方法足够使用了;

package com.xiaozhi.eneity;

public class User {
    private int id;
    private String name;
    private String password;

    public User() {
    }

    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    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 getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

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

2.3.2创建Dao持久层;

这里用的接口对应配置文件的方式;
先用UserDao命名吧;这个和之后要用的Mapper是一样的;

package com.xiaozhi.dao;
import com.xiaozhi.eneity.User;
import java.util.List;

public interface UserDao {
    //先定义个查询所有用户的方法;
    List<User> findAllUser();
}

需要注意的是,现在不用去写实现类去实现接口的方式,那样子比较麻烦;
比说说写个查询方法把;要获取结果集就得需要一个一个去写setXXX,getXXX对应属性;而且每次写一个方法,就得写对应的;

好了,接着回到这个简单的项目;创建个UserMapper.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">
<!--这里mapper的空间对应创建的持久层接口;-->
<mapper namespace="com.xiaozhi.dao.UserDao">
    <!--比如说,现在要写个查询语句,id就对应接口的方法;-->
    <!--resultType: 查询的结果类型-->
    <select id="findAllUser" resultType="com.xiaozhi.eneity.User">
        select * from day2021_9_6_studyMybatis_db.user
    </select>
</mapper>

2.4 测试

使用junit测试;注意要使用@Test注解.

一般情况下,这个测试代码是要在test测试类中去编写的;和开发的主程序分开;

package com.xiaozhi.dao;
import com.xiaozhi.eneity.User;
import com.xiaozhi.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class UserDaoTest {
    //测试查询所有用户的方法;
    @Test
    public void testFindAllUser(){
        //首先,回去SqlSession对象;
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //第一种方式;getmapper;
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> allUser = userDao.findAllUser();
        //遍历结果;
        for (User user : allUser) {
            System.out.println(user);
        }

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

报错提示
(1)该错误表示没有在mybatis核心配置文件中注册需要的UserMapper.xml

org.apache.ibatis.binding.BindingException: Type interface com.xiaozhi.dao.UserDao is not known to the MapperRegistry.

(2)虽然说已经回到核心配置文件mybatis-config.xml,把UserMapper.xml添加注册进去了;

<!--每个mapper都需要在核心配置文件中注册-->
<mappers>
    <mapper resource="com/xiaozhi/dao/UserMapper.xml"/>
</mappers>

但是又爆出找不到资源的错误;如下

java.lang.ExceptionInInitializerError
	at com.xiaozhi.dao.UserDaoTest.testFindAllUser(UserDaoTest.java:18)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.狂神说Mybatis课堂笔记

遇见狂神说---JavaWeb部分笔记

遇见狂神说--记录MySql部分笔记

狂神说Java笔记--多线程详解部分笔记

狂神说Java --- 记录Spring学习笔记

狂神说Java笔记--反射和注解部分笔记