MyBatis入门看这一篇就够了,简单详细清楚,图文结合一看就会

概述

  1. 是什么

通过程序来操作数据库
是一个数据持久层框架(ORM框架,即对象关系映射),支持自定义SQL,存储过程以及映射(将关系型数据库中的数据与对象建⽴起映射关系,进⽽⾃动的完成数据与对象的互相转换)。
MyBatis通过简单的XML或者注解来配置和映射原始类型。
简单来说,MyBatis就是更简单完成程序和数据库交互的工具,即使程序操作数据库更加简单方便

  1. 实现
  • 数据库中的 映射为 程序中的
  • 数据库中的记录(数据) 映射为 程序中的对象
  • 数据库中的字段 映射为 程序中的属性

框架会将数据库的每张表都映射成一个Java类,而MyBatis就可以将数据库当做对象和类来进行操做

  1. ORM

ORM(Object Relational Mapping)即对象关系映射. 其中,对象指的是程序中的对象(Java对象),关系指的是数据库中的关系模型(以二维表结构来表示实体与实体之间的联系),对象关系映射就是在Java对象和数据库的关系模型之间建立一种对应关系。例如数据库中的User表,对应在程序中就是User类,其中User类中的属性和User表的字段是一一对应的。每当你new一个User对象,都会在数据库中对应一个该User的数据。例如下面:
在这里插入图片描述
在这里插入图片描述

实例

创建SpringBoot项目,在里面添加MyBatis框架

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/e81cd644f982461d82fb74f8d6484194.png在这里插入图片描述

在这里插入图片描述

初始化 链接MySQL

在这里插入图片描述
在这里插入图片描述
在application.properties 中链接数据库
在这里插入图片描述

#设置数据库相关连接配置
spring.datasource.url= jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=z0329
driver-class-name=com.mysql.cj.jdbc.Driver
#mybatis 配置信息  设置mybatis xml 存放路径和命名格式
mybatis.mapper-locations= classpath:mybatis/*Mapper.xml
# 配置 MyBatis 执行时打印 SQL
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug

在这里插入图片描述

创建接口

里面用来声明增删改查方法,给其它类调用
在这里插入图片描述

在这里插入图片描述

创建xml

在mybatis目录里面创建对应的xml文件
xml文件用来配置映射
在这里插入图片描述

<!-- 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 namespace="com.example.demo.mapper.UserMapper">
<!-- 注意此处namespace是用来标明当前xml实现或者映射的那个接口的-->
</mapper>

创建所需实体类

在这里插入图片描述

@Data
public class Userinfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private Date createTime;
    private Date updateTime;
    //注意此处的属性要和数据库里面一样
}

增删改查操作

select

  • 声明方法
    在这里插入图片描述
  • 映射配置文件(在UserMapper.xml中)
<select id="getAll" resultType="com.example.demo.model.Userinfo">
        select * from Userinfo
    </select>
  • 测试(Generate -> Test)
    在这里插入图片描述
@SpringBootTest   //不能省略,告诉当前测试程序,当前项目是运行在Spring Boot 容器中
class UserMapperTest {

    @Autowired  //注入
    private UserMapper userMapper;

   
    @Test
    void getAll() {
        List<Userinfo> list = userMapper.getAll();
        System.out.println(list);
    }
  }

在这里插入图片描述
在这里插入图片描述
注:若根据id查找是相似的,例如:

  • 声明方法
@Mapper  //数据持久层的标志
public interface UserMapper {
	Userinfo getUserById(@Param("id") Integer id);   //根据id查找
}
  • 映射配置文件
   <select id="getUserById" resultType="com.example.demo.model.Userinfo">
        <!-- 下面花括号里面 id 是和@Param 一致的-->
        <!-- @Param的作用就是给参数命名-->
        select * from userinfo where id= ${id}
    </select>
  • 测试
@Test
    void getUserById() {
        Userinfo userinfo = userMapper.getUserById(1);
        System.out.println(userinfo);
    }

在这里插入图片描述

insert

  • 声明方法
@Mapper  //数据持久层的标志
public interface UserMapper {
 	int add(Userinfo userinfo);       //添加数据
 	int insert(Userinfo userinfo);  // 添加数据(id自增)
 }
  • 映射配置文件
<insert id="add">
        insert into userinfo(username,password,photo) values(#{username},#{password},#{photo})
    </insert>

第二种(设置id自增):

<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        <!-- useGeneratedKeys: 是否开启自增-->
        <!-- keyColumn: 自增哪个字段     Column(字段)-->
        <!-- keyProperty: 将数据库中自增的id赋值给此属性(即后面使用userinfo.getId()方法获取该自增id)-->
        insert into userinfo(username,password,photo) values(#{username},#{password},#{photo})
    </insert>
  • 测试
    @Test
    void insert() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("发发");
        userinfo.setPassword("123");
        userinfo.setPhoto("");
        int result = userMapper.insert(userinfo);
        System.out.println("受影响行数:  "+ result + "   ID:" + userinfo.getId());
    }

在这里插入图片描述
在这里插入图片描述

delete

  • 声明方法
@Mapper  //数据持久层的标志
public interface UserMapper {
 	int delByID(@Param("id") Integer id);   //根据id删除数据
 }

-映射配置文件

<delete id="delByID">
        delete from userinfo where id=#{id}
    </delete>
  • 测试
    @Test
    void delByID() {
        int id = 10;
        int result = userMapper.delByID(id);
        System.out.println("修改行数:" + result);
    }

update

  • 声明方法
@Mapper  //数据持久层的标志
public interface UserMapper {
 	int update(Userinfo userinfo);  //数据更改
 }
  • 映射配置文件
<update id="update">
        update userinfo set username=#{username} where id=#{id}
    </update>
  • 测试
    @Test
    void update() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("小帅");
        userinfo.setId(1);
        int result = userMapper.update(userinfo);
        System.out.println("受影响行数: " + result);
    }

动态SQL

概述

上述SQL都是固定死的,在注册页面时,有的数据(字段)是必填的,例如账户名,密码等,而有些字段不是必填的,例如性别,出生年月日等。这种情况下该如何判断用户填了什么字段,而对于程序实现来说,什么字段该有,什么字段该无,这都是灵活的,尽靠上述程序是无法实现的。于是动态SQL就出现了
动态SQl:使用不同标签来对字段有无进行自动判别,保证数据能正确传入到数据库中。换言之,就是对SQl语句中字段的数据或条件进行动态按需去除或添加

if标签

  • 声明方法
@Mapper  //数据持久层的标志
public interface UserMapper {
	int add2(Userinfo userinfo);  //if标签
}
  • 映射文件配置
    <insert id="add2">
        insert into userinfo(username,password
        <if test="photo != null">
            ,photo
        </if>
        ) values (#{username},#{password}
        <if test="photo != null">
            ,#{photo}
        </if>
        )
    </insert>

其含义是对photo字段进行动态判别,若用户输入该字段就会将该字段数据添加到数据库中,反之就只会添加username,password字段数据

  • 测试
    void add2() {   //if标签  动态插入数据
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("九九");
        userinfo.setPassword("456");
        //userinfo.setPhoto("www.cn");
        int result = userMapper.add2(userinfo);
        System.out.println("影响行数: " + result);
    }

此时无photo字段,执行如下:
在这里插入图片描述

存在后:在这里插入图片描述
这就是动态SQl

trim标签

  • 声明方法
@Mapper  
public interface UserMapper {
	int add3(Userinfo userinfo); //trim标签
}
  • 映射文件配置
    <!-- 使用trim标签-->
    <!-- 其中prefix表示给前面添加,suffix给后面添加,suffixOverrides表示当字段后面有 (,号) 时,会将 (,号) 删除,没有则任何事不做.prefixOverrides是删除字段前面-->
    <insert id="add3">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="username != null">
                username,
            </if>
            <if test="password != null">
                password,
            </if>
            <if test="photo != null">
                photo,
            </if>

        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="username != null">
                #{username},
            </if>
            <if test="password != null">
                #{password},
            </if>
            <if test="photo != null">
                #{photo},
            </if>
        </trim>
    </insert>
  • 测试
    @Test
    void add3(){   //trim标签  动态插入数据
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("小猴");
        userinfo.setPassword("777");
        //userinfo.setPhoto("www.cn");
        int result = userMapper.add3(userinfo);
        System.out.println("影响行数: " + result);
    }

在这里插入图片描述

where标签

  • 声明方法
@Mapper  
public interface UserMapper {
	List<Userinfo> getListByWhere(Userinfo userinfo); //where标签
}
  • 映射文件配置
<!-- where标签-->
    <!-- 只能用在where查询里面-->
    <!-- 当有条件时才会生成where,当没有条件时就不会生成where语句(即就是普通查询)-->
    <!-- where标签会自动删除and或者or。其中若不满足第一个if标签,那么直接就会和and拼接,就会出错,此时where就会自动删除and,就不会出错了-->
    <select id="getListByWhere" resultType="com.example.demo.model.Userinfo">
        select * from userinfo
        <where>
            <if test="id > 0">
                id = #{id}
            </if>
            <if test="username != null">
                or username = #{username}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
        </where>
    </select>
  • 测试
@Test
    void getListByWhere() {  //where标签  根据id username password 进行条件查询
        Userinfo userinfo = new Userinfo();
        //userinfo.setId(12);
        userinfo.setUsername("小猴");
        List<Userinfo> list = userMapper.getListByWhere(userinfo);
        System.out.println(list);
    }

此时根据username查询:
在这里插入图片描述

@Test
    void getListByWhere() {  //where标签  根据id username password 进行条件查询
        Userinfo userinfo = new Userinfo();
        //userinfo.setId(12);
        userinfo.setUsername("小猴");
        userinfo.setPassword("123");
        List<Userinfo> list = userMapper.getListByWhere(userinfo);
        System.out.println(list);
    }

此时根据username和password查询:
在这里插入图片描述

set标签

  • 声明方法
@Mapper  
public interface UserMapper {
	int update2(Userinfo userinfo);  //set标签
}
  • 映射文件配置
<!-- set标签自动检测去除逗号-->
    <update id="update2">
        update userinfo
        <set>
            <if test="username != null">
                username = #{username},
            </if>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="photo != null">
                photo = #{photo},
            </if>
        </set>
        where id = #{id}
    </update>
  • 测试
 @Test
    void update2() {  //set标签  根据Id对数据库中信息修改更新
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("超级飞侠");
        userinfo.setId(1);
        int result = userMapper.update2(userinfo);
        System.out.println("影响行数: " + result);
    }

在这里插入图片描述
将SQL语句中password字段和photo字段动态去除

foreach标签

  • 声明方法
@Mapper  
public interface UserMapper {
	int delByIds(List<Integer> ids);  //foreach标签(批量删除)
}
  • 映射文件配置
<!-- collection: UserMapper里面的值  绑定⽅法参数中的集合-->
    <!-- separator:每次遍历之间间隔的字符串-->
    <!-- item:遍历时的每⼀个对象-->
    <delete id="delByIds">
        delete from userinfo where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>
  • 测试
@Test
    void delByIds() {  //foreach标签  根据id批量删除
        //批量删除id = 7,11,12的用户数据
        List<Integer> list = new ArrayList<Integer>();
        list.add(7);
        list.add(11);
        list.add(12);
        int result = userMapper.delByIds(list);
        System.out.println("收影响行数: " + result);
    }

在这里插入图片描述

#{}与${}区别

$符: 直接替换(将花括号里面的id直接替换成用户输入的数值) 不安全,存在SQL注入
#号:预执行(将花括号里面的id替换成占位符?号) 安全,不存在SQL注入
SQL注入: 输入一个错误的用户密码或者信息,还能查出用户正确信息

示例

在这里插入图片描述
下面是 #{} :
在这里插入图片描述

resultMap

是结果映射标签。对实体类进行映射。
使用场景:当数据库中字段名与程序中属性名不一样的话,就可以使用resultMap来配置映射

示例

  • 声明方法
@Mapper  
public interface UserMapper {
    List<Userinfo> getAll2();  //对于resultMap示例
}
  • 映射文件配置
<resultMap id="map" type="com.example.demo.model.Userinfo">
    <id column="id" property="id"></id>
    <result column="username" property="name"></result>
    <result column="password" property="password"></result>
</resultMap>
<select id="getAll2" resultMap="com.example.demo.mapper.UserMapper.map">
    select * from userinfo
</select>

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 测试
    @Test   //对resultMap映射 测试
    void getAll2() {
        List<Userinfo> list = userMapper.getAll2();
        System.out.println(list);
    }

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值