MyBatis入门详解

 本MyBatis~

目录

1.mybatis相关介绍

1.1什么是mybatis

1.2为什么要学mybatis

2.mybatis实战操作

2.1项目创建

2.1.1准备数据表

2.1.2创建一个mybatis项目

2.2使用mybatis进行增删查改操作

2.2.1查询操作

2.2.2使用springboot进行单元测试介绍

2.2.3修改操作

2.2.4删除操作

2.2.5增添操作


1.mybatis相关介绍

1.1什么是mybatis

MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。

1.2为什么要学mybatis

因为对于后端开发来说,程序主要是由后端程序和数据库两部分来组成的。而这两个部分要进行通讯,就需要有连接数据库的工具,前面我们已经学过了JDBC,但正是因为JDBC相对于MyBatis太过繁琐,所以我们就要开始学习MyBatis。

2.mybatis实战操作

2.1项目创建

2.1.1准备数据表

①创建一个如下的数据库和数据表:

-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;

-- 使用数据数据
use mycnblog;

-- 创建表[用户表]
drop table if exists  userinfo;
create table userinfo(
    id int primary key auto_increment,
    username varchar(100) not null,
    password varchar(32) not null,
    photo varchar(500) default 'default.png',
    createtime datetime default now(),
    updatetime datetime default now(),
    `state` int default 1
) default charset 'utf8mb4';

-- 创建文章表
drop table if exists  articleinfo;
create table articleinfo(
    id int primary key auto_increment,
    title varchar(100) not null,
    content text not null,
    createtime datetime default now(),
    updatetime datetime default now(),
    uid int not null,
    rcount int not null default 1,
    `state` int default 1
)default charset 'utf8mb4';

-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(
  	vid int primary key,
  	`title` varchar(250),
  	`url` varchar(1000),
		createtime datetime default now(),
		updatetime datetime default now(),
  	uid int
)default charset 'utf8mb4';

-- 添加一个用户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES 
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);

-- 文章添加测试数据
insert into articleinfo(title,content,uid)
    values('Java','Java正文',1);
    
-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://www.baidu.com',1);

②将其放在mysql中:

2.1.2创建一个mybatis项目

①添加MyBatis相关依赖

(1)新项目添加MyBatis依赖

1.基于spring项目进行创建:

(a)

(b) 

(c)

 (d)

 (2)老项目添加MyBatis:

我们在pom.xml中点击鼠标右键,然后如下图所示操作

 ②配置数据库连接字符串和MyBatis(保存的xml目录)

(1)配置数据库的连接信息

1.主配置文件(application.yml)

#生产环境的配置文件
spring:
  profiles:
    active: dev

2.开发环境配置文件(application-dev.yml)

#开发环境的配置文件
#无论是生产环境和开发环境都要配置以下四项
# 配置数据库的连接
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8
    username: root   # 用户名(默认是root)
    password: 123456 # 自己的密码
    driver-class-name: com.mysql.cj.jdbc.Driver # mysql的驱动名称

3.当前运行环境配置文件(application-prod.yml)

这里先不做配置

(2)配置MyBatis的xml保存路径

xml属于资源文件,放于resource目录下。因此我们在resource目录下新建一个mybatis目录文件。

 代码:

# 配置当前运行的环境(配置文件)
spring:
  profiles:
    active: dev # 使用开发环境的配置文件
# 配置 MyBatis 的 XML 的保存路径
# 在resource底下新建一个文件夹,用来放 XML
mybatis:
  mapper-locations: classpath:mybatis/**Mapper.xml

③使用Mybatis的操作模式操作数据库:

创建controller,service,model,mapper的package在com.example.demo的目录下,方便在其中创建对应的类

(1)在model里创建实体类UserInfo(这里最好和数据中的同名,这样便于看)代码如下:

//这是一个实体类,对象的名字最好和数据库表名保持一致,看起来清楚
package com.example.demo.model;
import lombok.Data;
import org.springframework.stereotype.Controller;
@Data
@Controller
public class UserInfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private String createtime;
    private String updatetime;
    private String state;
}

(2)在mapper中创建UserMapper(这样写比较规范,因为会引入@Mapper,当然也可以不这么写)

代码如下:(即定义普通的接口)

package com.example.demo.mapper;
import com.example.demo.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
//实现xml和interface之间的交互
@Mapper//从普通的接口变成了mybatis的interface;可以通过xml实现,而普通的xml是要通过java才能实现的
public interface UserMapper {
    //根据用户id来查询用户
    //@param是参数在xml中叫id,相当于重命名,但是使用中,只能用修改后的名字
    public UserInfo getUserById(@Param("id") Integer id);
}

(3)创建xml实现上面的接口

注意:我们在前面配置的时候,就写了xml的存放路径需要在mybatis的目录下,并且命名为**Mapper.xml(而在这里为了方便我们更好的知道这里的xml对应的是哪个接口,所以我们将其前面命名一致为UserMapper)

1.mybatis的固定xml格式:(每新建一个项目都会用到的,但是namepace需要根据自己的情况来填写)

<?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 设置是实现的 接口的包名和类名 !包名从java源代码底下的目录开始-->
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userInfo where id=${id}
    </select>
</mapper>

注意:(在查询操作的时候,这两个参数都是需要的,查询语句,有结果集的时候,都要映射到Java的对象,映射方式有很多种,但是必须指定一种,这里我们指定的就是resultType)

 我们写的时候,就是interface中写方法申明,在xml中写具体实现就OK了。

④对以上查询操作进行测试:

(我们利用service中的类调用mapper,而controller里的类去调用service)

(1)service相关代码:

package com.example.demo.service;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.UserInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserService {
    @Resource
    private UserMapper userMapper;//因为是mybatis接口,所以可以用
    public UserInfo getUserById(Integer id){
        return userMapper.getUserById(id);
    }
}

(2)Controller相关代码:

package com.example.demo.controller;
import com.example.demo.model.UserInfo;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/getUserById")
    public UserInfo getUserById(Integer id){
        if (id==null)return null;
        return userService.getUserById(id);
    }
}

输出结果:

对应数据库中内容进行查看:

 一致的,查询成功

⑤MyBatis的执行过程:

 这也就是为什么我们在④中需要引入controller下的类,以及service下的类,已经他们返回的代码的意义所在。

注意:为了更容易的排查sql中的问题,我们在开发环境中application-dev.yml设置日志进行打印(这个也是固定的写法)

# 开启 MyBatis SQL 打印
logging:
  level:
    com:
      example:
        demo: debug
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

写后我们运行程序成功,就可以在控制台上看到:

2.2使用mybatis进行增删查改操作

2.2.1查询操作

①在Mapper接口中声明一个方法:(注意!!!Mapper接口中,必须得有@Mapper注解,否则是不能够与xml产生映射的)

② 在xml中执行查询操作:使用预处理符#{}或者替换符${}来将程序传入的参数替换到sql语句中:

 ③查询结果:

2.2.2使用springboot进行单元测试介绍

①什么是单元测试?

1、可以非常简单、直观、快速的测试某个功能是否正确。
2、使用单元测试可以帮我们在打包的时候,发现一些问题,因为在打包之前,所以的单元测试必须通过,否则不能打包成功。
3、使用单元测试,在测试功能的时候,可以不污染连接的数据库,也就是可以不对数据库进行任何改变的情况下,测试功能的正确性。
②为什么使用单元测试?

因为其可以不污染数据库,因此我们可以在添加进去前进行测试

③如何创建单元测试?

(1)框架支持(在我们创建spring boot项目时会自动进行添加,所以这个地方不做过多说明)

(2)我们在需要测试方法的所在类中,右键点击Generate,Test,然后对测试的内容进行勾选。(下面我们以测试UserMapper类中的getUserById为例)

a.

b.

c.

(3)进入测试页面后,我们先选择添加配置单元测试类的注解:@SpringBootTest注解

(4)在测试方法上添加@Test注解

(5)注入Mapper对象,调用里面操作数据库的方法,进行单元测试。

a.直接输出结果方式进行测试: 

 (注意:在一个测试中是可以有多个测试方法,且每个测试方法都可以独立地进行启动)

 输出结果如下:

b.通过断言来进行测试:(断言常用方法如下)

示例:(我们以assert不为null来进行判断,如果不为null,就会返回√,否则则表示测试用例不通过) 

这就表示测试例成功。

失败显示如下:(很显然id=1的是不为null 的)

 (6)使用@Transactional注解可以防止污染数据库

使用这个注解后,是不会修改数据库里的内容的,因此当我们进行增删查改的时候,可以先这样进行测试看到底有没有问题,再进行后续操作。这个在下面的操作中也会进行演示。

2.2.3修改操作

①在Mapper接口中声明一个方法:(注意!!!Mapper接口中,必须得有@Mapper注解,否则是不能够与xml产生映射的)

  //根据id来修改用户名称,且返回值为影响的行数
    public Integer updateName(@Param("id")Integer id,@Param("username")String name);

② 在xml中执行查询操作:使用预处理符#{}或者替换符${}来将程序传入的参数替换到sql语句中:

    <update id="updataName">
       update userinfo set username=#{username} where id=#{id}
    </update>

 ③测试代码:

  @Test
    @Transactional
    void updateName() {
        int result = userMapper.updateName(1, "李四");
        Assertions.assertSame(1,result);
    }

测试结果:

我们可以发现测试是通过了的,但是由于我们加了@Transactional这个注解的话,数据库是不会进行实际的修改的,我们可以查一下:

④我们去掉测试代码中的 @Transactional,来看一下是否会更改数据库的值

仍然是通过了测试,这个时候,我们来查询一下数据库:

 ⑤我们也可以通过类似于上述查询的方式,在url中对数据库的内容进行修改:

在UserService,UserController中分别添加如下内容:

(我们返回的仍然是受影响的行数) 

 输出结果:

此时,我们查看数据库,看username是否已经被改成了lisi。 

 

2.2.4删除操作

①声明方法:

  //根据id删除某一个用户的信息,返回受影响行数
    public Integer deleteUser(@Param("id")Integer id);

②在xml中编写sql:

    <delete id="deleteUser">
        delete from userInfo where id=#{id};
    </delete>

③测试代码:

    @Test
    @Transactional
    void deleteUser(){
        int result=userMapper.deleteUser(1);
        Assertions.assertSame(1,result);
    }

④输出结果:

测试成功,因为本身这个数据表就只有一行数据,这里就不真正删除啦 

2.2.5增添操作

增加的操作会相对复杂一点。我们声明方法中的形参传入一个UserInfo对象

①返回一个参数

(1)声明方法:

    //插入一行数据,返回受影响的行数
    public Integer add(UserInfo userInfo);

(2)在xml中编写sql:

 <insert id="add">
        insert into userinfo(username, password, photo) values (#{username}, #{password},#{photo});
    </insert>

(3)测试代码:

    @Test
    void add(){
        UserInfo userInfo=new UserInfo();
        userInfo.setId(2);
        userInfo.setUsername("张三");
        userInfo.setPhoto("abc.png");
        userInfo.setPassword("123456");
        int result=userMapper.add(userInfo);
        Assertions.assertSame(1,result);
    }

(4)输出结果:

测试成功,此时只返回了一个参数

 我们来查看该表现在的内容:

 ②返回多个参数:

比如返回受影响的行数和自增id的值,这个时候我们就需要对xml的insert标签进行配置。

(1)声明:

 public Integer addId(UserInfo userInfo);

(2)xml中:(注意!!!insert标签中还需要设置useGeneratedKeys="true"表示为自增主键,keyProperty="id"表示哪一个是自增主键)

 <insert id="addId" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into userinfo(username, password, photo) values (#{username}, #{password},#{photo});
    </insert>

(3)测试代码:

    @Test
    void addId() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("王五");
        userInfo.setPassword("123456");
        userInfo.setPhoto("default.png");
        System.out.println("插入之前的id=" + userInfo.getId());
        int result = userMapper.addId(userInfo);
        System.out.println("插入之后的id=" + userInfo.getId());
        Assertions.assertSame(1,result);
    }

(4)输出结果:

测试成功 

 查看现在的数据表:

最后尝试通过名字来改id,上面我们看到张三的id为3,我们来试一试能不能改为2:

①声明方法:

 public Integer updateidByname(Integer id,String username);

②在xml中修改:

  <update id="updateidByname">
        update userInfo set id=#{id} where username=#{username};
    </update>

③测试代码:

  @Test
    void updateidByname(){
        int result = userMapper.updateidByname(2, "张三");
        Assertions.assertSame(1,result);
    }

④输出结果:

测试成功

本期MyBatis到此结束,这一期的内容可以支撑我们做SSM项目了,下期,我们将延伸一下。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张洋洋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值