[MyBatis]简单入门看这篇

       

目录

 1.如何学习MyBatis?

 2.如何使用MyBatis?

2.1创建数据库及其表

2.2引入MyBatis依赖并配置相关信息

2.3添加业务代码

3.实操

3.1  ---传一个参数的查询操作* #{} 和 ${} 的区别?​编辑3.2   ---传入一个参数的删除操作3.3   ---传入一个对象的修改操作​编辑3.4  ---传入一个对象的增加操作​编辑3.4.1 如何在insert的时候拿到自增id而不是受影响的行数?*模糊匹配 like  concat()


        我们都知道,一个好的程序必然是由前后端组成的,那么其前端与后端的交互如何才能获取数据呢? 那就需要后端从数据库提取数据返回给前端了,我们之前学习的MySQL数据库有JDBC可以操作,那么在JDBC中我们需要一些类比如:

1. 创建数据库连接池 DataSource
2. 通过 DataSource 获取数据库连接 Connection

3. 编写要执⾏带 ? 占位符的 SQL 语句
4. 通过 Connection 及 SQL 创建操作命令对象 Statement
5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
6. 使⽤ Statement 执⾏ SQL 语句
7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
8. 处理结果集
9. 释放资源

其实这样是非常麻烦的,假如我们要连接的数据库众多,那么每一次交互都要来上这么一套,后端程序员简直要疯...........所以MyBatis应运而生,接下来跟着小玉一起来学习吧~~~

 1.如何学习MyBatis?

MyBatis 学习只分为两部分:
配置 MyBatis 开发环境;
使⽤ MyBatis 模式和语法操作数据库。
        MyBatis 也是⼀个 ORM 框架 ORM(Object Relational Mapping),即对象关系映射。在⾯向对象编程语⾔中,将关系型数据库中的数据与对象建⽴起映射关系,进⽽⾃动的完成数据与对象
的互相转换:
数据库表(table)--> 类(class)
记录(record,⾏数据)--> 对象(object)
字段(field) --> 对象的属性(attribute)
⼀般的 ORM 框架,会将数据库模型的 每张表都映射为⼀个 Java 类。
也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表,可以实现对象和数据库表之间
的转换,接下来我们来看 MyBatis 的使⽤吧。

 2.如何使用MyBatis?

2.1创建数据库及其表

MyBatis主要是用来操作数据库的,我们先创建一张数据库的表,方便后续验证:

-- 创建数据库
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 '',
 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://ww
w.baidu.com',1);

2.2引入MyBatis依赖并配置相关信息

1.创建new project的时候,选择引入MyBatis依赖,一定要同时选择Mysql Driver因为你要告诉MyBatis你要连接的数据库是什么类型的:MySQL?Oracle?......

2. 在我们添加好maven之后,需要在application.properties中添加配置信息:

#设置数据库的相关链接信息:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=你的数据库密码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#设置mybatis配置信息:当前路径下的mybatis包下以Mapper.xml结尾的文件中实现接口
mybatis.mapper-locations=classpath:mybatis/*Mapper.xml


#打印sql语句:
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug

(你注意了!其中有个  spring.datasource.password要填你的数据库密码!!) 

2.3添加业务代码

1.那么根据图我们先创建一个实体类:

package com.example.demo.model;

import lombok.Data;

import java.time.LocalDate;

/**
 * Created with IntelliJ IDEA.
 * Description:实体类
 * User: yyx
 * Date: 2023-10-27
 * Time: 21:26
 */
@Data
public class Userinfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private LocalDate createtime;
    private LocalDate uodatetime;
    private int state;
}

(你注意了! 这里的类的类名最好跟你的数据库中表名相同,类的属性要跟该表下的字段名相同!!!最好在model包底下,因为model层掌管数据的)

添加上Lombok的注解,这样就无须手动生成getter/setter方法了~~~

下面就是重点了!!!

 2.添加mapper接口:

注意它的这个目录结构,这个UserMapper是个接口在dao层,dao掌管接口!!

(你注意了!!这个接口层只是声明方法,不需要亲自实现,真正实现方法是在.xml中实现的) 

3.  在.xml实现方法

注意它这个目录结构!!在resources底下建一个包mybatis然后生成一个以Mapper.xml结尾的文件 ! 前缀的话最好跟你的接口文件相对应,词能达意~~

原因是我们在application.properties中声明了这一点:

在*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 namespace="com.example.demo.dao.UserMapper">
</mapper>

这里只需要更改namespace即可:(用来指明这个xml是实现哪个接口的)

4.在dao层的mapper中实现service 

package com.example.demo.dao;

import com.example.demo.model.Userinfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:数据持久层的标志
 * User: yyx
 * Date: 2023-10-27
 * Time: 21:24
 */
@Mapper
public interface UserMapper {
    //Interface只写声明!!!方法的声明
    List<Userinfo> getAll();

}

这个声明是代表返回的类型是一个关于Userinfo的集合类,方法名称是getAll().

声明之后就要在.xml中实现这个方法了:(你注意了! 这个标签写在<mapper></mapper>里面)

<select id="getAll" resultType="com.example.demo.model.Userinfo">
        select * from userinfo
    </select>

查询的SQL还是需要自己来写的~~我们需要用到一个<select></select>,不需要在SQL语句后加上分号
标签里面的id属性就是你在接口里面的方法名,必须要对应上!!! 其中的resultType属性是表明返回的类型是哪个实体类(要写全限定名:包名+类名)

5.生成Test单元测试,验证是否可以对数据库进行操作

在UserMapper接口中右键单击选择Generate 然后选择Test(你注意了!有的码友可能没有Test你需要在UserMapper代码块中右键才可以,不要在空白地方右键单击!!)

注意目录结构!!

 此时我们需要写两处:
1.使用@AutoWired注入UserMapper
2.写入测试代码;

使用usermapper调用对应的方法,使用约定好的返回值接受

然后就能在日志里查看内容了,因为我们在配置文件里设置了打印日志,所以能看到日志信息:

(因为小玉这数据库里前后插入过一些数据,所以查出来好多结果,你们的话,用我给你们的SQL语句应该只有一条:id为1,username和password都叫admin....)

3.实操

3.1  <select>---传一个参数的查询操作

1.在UserMapper接口中声明方法:

int delByID(@Param("id")Integer id);

 这里需要使用一个只能修饰参数的注解@Param  其中括号里的属性尽量与字段名保持一致,避免出错,后面跟上参数类型及名称.

2.在.xml中实现方法:

<select id="getById" resultType="com.example.demo.model.Userinfo">
        select * from userinfo where id=${uid}
    </select>

其中我们需要将参数内嵌到SQL语句中:此时用到了格式化工具:#{} 这里小玉需要着重讲一下这里,因为今天刚好被一个面试官问到了!!!!

* #{} 和 ${} 的区别?

在参数匹配的时候,我们通常会使用#{}或者${}来进行占位,但是他们之间是有区别的:

#{}是预编译层面的替换,在编译的时候会先将待替换的部分编译成一个问号? 然后再日志的Params中会将参数解析,填入问号当中;


${}是直接替换,在编译的时不设置问号?,直接将参数替换在占位符上,但是这样的直接替换会引起严重的SQL注入问题!非常危险!
而#{}就没有SQL注入的问题,因为其底层是使用PreparadStatement预编译,在参数中若是发现了类似SQL的语句(如'  或=1或" 等等会进行转义,然后替换 )

3.生成Test进行测试: 

   @Test
    void getById() {
        Userinfo userinfo = userMapper.getById("1");
        System.out.println(userinfo.toString());
    }

此时注意了@Autowired只需要注入一次UserMapper就可以了,这里我们在调用getById()方法的时候就需要传入参数了,设置的id将被传入Params当中被#{}替换掉:

3.2   <delete>---传入一个参数的删除操作

1.在UserMapper中声明方法:  同样使用@Param注解

 int delByID(@Param("id")Integer id);

2.在UserMapper.xml中实现方法:

<delete id="delByID">
        delete from userinfo where id=#{id}
    </delete>

 3.生成Test测试;

 void delByID() {
        Integer id = 1;
        int i = userMapper.delByID(id);
        System.out.println("受影响的行数:"+i);

    }

(你注意了!! 这里参数返回是一个int类型代表受影响的行数,不是返回一个Userinfo对象或者是一个List<Userinfo>集合类了,这跟我们在MySQL中的逻辑是一样的,增删改操作都是返回受影响的行数的!)

4.看日志:

此时我们可以打开数据库看一下ID为1的是不是被删除了:

没了已经

3.3   <update>---传入一个对象的修改操作

1.在UserMapper中声明方法:

int update(Userinfo userinfo);

2.在UserMapper.xml中实现方法:

<update id="update">
        update userinfo set username='${username}' where id='${id}'
    </update>

这里我们使用${}占位,我们换换看看:(因为是直接替换所以当要替换的内容是String类型的时候,需要手动加上单引号 ' ' )

3.生成Test:

    @Test
    void update() {
        Userinfo userinfo = new Userinfo();
        userinfo.setId(1);
        userinfo.setUsername("超级管理员");
        int update = userMapper.update(userinfo);//我忘记调用mapper接口了
        System.out.println(update);
    }

此时我们需要注意,因为传入的是一个Userinfo对象,所以我们需要下实例化该对象,设置一下这个对象你需要修改的值,仅设置需要修改的字段即可~~(@Lombok注解会提供getter/setter方法);
必须牢记需要使用userMapper调用对应的接口声明的方法!

4.查看日志:

(小玉的id为1的信息已经被删了,假如你们是跟着小玉做的,那就请手动在MySQL中插入原来的那个信息吧~然后再修改,这里小玉修改了另外的信息,id不为1的张三同学~~~)

可以看到这里不是使用?预编译了,而是直接替换注意直接替换时String类型的问题!!!!!!!!!!!!

看一下数据库改了没:

3.4  <insert>---传入一个对象的增加操作

1.在UserMapper中声明方法;

int add(Userinfo userinfo);//返回受影响的函数

 2.在UserMapper.xml中实现方法:

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

 3.生成Test方法验证:

 @Test
    void add() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("张三");
        userinfo.setId(1);
        userinfo.setPassword("123");
        int add = userMapper.add(userinfo);
        System.out.println("受影响的行数"+ add);
    }

只要我们是以对象作为参数传递的,在Test的时候,都需要先实例化实体类,然后再设置字段,然后再使用userMapper调用方法,注意设置字段的时候,要跟你要实现的操作参数对应!!

看下数据库:

3.4.1 如何在insert的时候拿到自增id而不是受影响的行数?

在默认情况下,增删改都是以int作为返回值,代表受影响的行数的,那么如何返回该数据的自增id呢?

在UserMapper中还是老样子定义一个add2()方法,返回的是int,在xml里实现的时候,就需要下功夫了:

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

useGeneratedKeys 代表:令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动递增字段),默认值:false。

keyColumn:设置⽣成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第⼀列的时候,是必须设置的。如果⽣成列不⽌⼀个,可以⽤逗号分隔多个属性名称。

keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回
值或 insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)。如果⽣成列
不⽌⼀个,可以⽤逗号分隔多个属性名称。
@Test
    void add2() {//每次调用这个方法,主键都会加一
        Userinfo userinfo = new Userinfo();
        userinfo.setPassword("444");
        userinfo.setPhoto("");
        userinfo.setUsername("李四");
        int i = userMapper.add2(userinfo);
        System.out.println("受影响的行数+"+i+"主键:"+userinfo.getId());
    }

此时我们注意到,这个UserMapper调用add2()方法还是会返回一个int 还是代表受影响的行数,但是我们使用userinfo这个实体类的getId()方法即可返回自增主键,我们在Test中并未设置id但是却能返回一个id就代表我们的useGeneratedKeys keyColumn / keyProperty 生效了!!

*模糊匹配 like  concat()

当我们需要在表中模糊查找姓名中带有"三"这个人时,就需要用到模糊匹配,那这时候我们就需要传入一个参数,记得返回值是一个List<Userinfo>:(别忘记在@Param()之后写上参数类型和参数名!小玉老是忘记)

1.UserMapper中声明:

List<Userinfo> getLike(@Param("username")String username);

2..XML实现:

<select id="getLike" resultType="com.example.demo.model.Userinfo">
        select * from userinfo where username like concat('%',#{username},'%')
                        <!--一定要注意字段匹配  username-->
    </select>

我们在SQL中的写法应该是会是这样的:

select * from userinfo where username like '%三%';

这个三是我们希望传进来的参数,但是前面的'% %'我们可以使用concat()方法拼接:将多个字符串连接成一个字符串。 

3.生成Test检验:

@Test
    void getLike() {
        String username = "超级";
        List<Userinfo> like = userMapper.getLike(username);
        System.out.println(like);
    }


好像也没什么可讲了,我们使用mybatis主要还是要熟悉SQL语句,熟悉数据库的使用,毕竟框架还是建立在最基础的语法上的,mybatis主要就是操作一个映射层Mapper层,用来声明方法,还有一层是xxxMapper.xml,以Mapper.xml结尾的文件,用来实现方法,,这连个层级之间一一对应,对了,码友们可以下载一个MybatisX这样的插件,这样的话很方便的:

点击小鸟就会在两个问价当中来回切换,就不用你手动去找了~~~

主要就是增删改查这四个标签,还有一些面试题,大家应该可以应对自如的吧?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杨小玉_ShawYu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值