使用MyBatis(2){使用myBatis操作增删改查/动态SQL}

news2024/9/25 1:24:46

目录

一、定义接口、实体类、创建XML文件实现接口)

二、MyBatis的增删改查 

🍅1、MyBatis传递参数查询

        🎈写法一

         🎈写法二

        🎈两种方式的区别

🍅2、删除操作

🍅3、根据id修改用户名

🍅4、添加用户操作

        🎈返回受影响的行数

        🎈返回自增id

🍅5、like查询

🍅6、多表查询

 三、动态SQL

        🍅 <if>标签

        🍅 <trim>标签

        🍅 <where>标签

        🍅 <set>标签

        🍅 <foreach>标签

四、注意

🍅1、mybatisx插件报错

🍅2、数据回滚

🍅 3、查询某字段结果为null时


一、定义接口、实体类、创建XML文件实现接口)

注意包名:

实体类

package com.example.demo.model;

import lombok.Data;

import java.time.LocalDateTime;

@Data
public class UserInfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private LocalDateTime updatatime;
    private LocalDateTime createtime;
    private int state;

}

接口

package com.example.demo.dao;

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

import java.util.List;

@Mapper  //数据持久层的标志
public interface UserMapper {
    List<UserInfo> getAll();
}

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.dao.UserMapper">
<!--    id是UserMapper的方法名-->
    <select id="getAll" resultType="com.example.demo.model.UserInfo">
--         不写分号
            select * from userinfo
    </select>
</mapper>

二、MyBatis的增删改查 

🍅1、MyBatis传递参数查询

        🎈写法一

@Param("id")与${id}相互匹配 (及时执行)

使用id去查询某条数据(传参数)

UserInfo getUserById(@Param("id") Integer uid);
-- 这里应该写${id},而不是uid
<select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where id=${id}
    </select>

测试类: 

@Test
    void getUserById() {
        UserInfo userInfo = userMapper.getUserById(1);
        System.out.println(userInfo.toString());
    }

         🎈写法二

@Param("id")与#{id}相互匹配 (预执行)

<select id="getUserById" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where id=#{id}
    </select>

        🎈两种方式的区别

1.${}是直接替换;而#{}是预执行

2.使用${}是不安全的,存在SQL注入;而#{}是安全的,不存在SQL注入

3.${}使用场景:当业务需要传递SQL语句时,只能使用${},不能使用#{}。

SQL注入:将SQL代码插入或添加到应用(用户)的输入参数中的攻击,之后再将这些参数传递给后台的sql服务器加以解析和执行。


🍅2、删除操作

UserInfo getUserById(@Param("id") Integer uid);
<!--    delete操作不需要设置返回类型-->
    <delete id="delById">
        delete from userinfo where id=#{id}
    </delete>

 测试类


    @Transactional   //数据回滚:使用该注解,会执行下面操作,但是不会真的操作数据库中的内容
    @Test
    void testGetUserById() {
        int id = 1;
        UserInfo result = userMapper.getUserById(id);
        System.out.println("受影响的行数:"+result);
    }

🍅3、根据id修改用户名

//    根据id修改用户名
//    返回受影响行数
    int update(UserInfo userInfo);
<!--    默认返回受影响的行数,不需要设置resultType-->
    <update id="update" >
        update userinfo set username=#{username} where id=#{id}
    </update>
@Transactional
    @Test
    void update() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1);
        userInfo.setUsername("管理员");
        int result = userMapper.update(userInfo);
        System.out.println("受影响行数"+ result);
    }

 运行结果:


🍅4、添加用户操作

        🎈返回受影响的行数

//返回受影响字段
int add(UserInfo userInfo);
<insert id="add">
        insert into userinfo(username,password,photo) 
values (#{username},#{password},#{photo})
    </insert>
//测试类
@Test
    void add() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("张三");
        userInfo.setPassword("11111");
        userInfo.setPhoto("/image/default.png");
        int result = userMapper.add(userInfo);
        System.out.println("受影响的行数:"+ result);
    }

 运行结果:

        🎈返回自增id

    int insert(UserInfo userInfo);
<insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into userinfo(username,password,photo) values (#{username},#{password},#{photo})
    </insert>
//测试类 
@Test
    void insert() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("李四");
        userInfo.setPassword("111111");
        userInfo.setPhoto("");
        int result = userMapper.insert(userInfo);
        System.out.println("受影响的行数:" + result +
                "| id:"+ userInfo.getId());
    }

 运行结果:

 对应关系:


🍅5、like查询

    List<UserInfo> getListByLike(@Param("username")String username);
<select id="getListByLike" resultType="com.example.demo.model.UserInfo">
        select * from userinfo where username like concat('%',#{username},'%')
    </select>
@Test
    void getListByLike() {
        String username = "三";
        List<UserInfo> list = userMapper.getListByLike(username);
        System.out.println(list);
    }

运行结果:


🍅6、多表查询

使用注解将sql语句和接口连接起来。

之前是,写一个接口就要写一个对应的xml文件编写sql语句。现在可以不使用这种方法

可以直接在接口中通过注解编写查询语句:

@Mapper
public interface ArticleMapper{
    @Select("select a.*,u.username from articleinfo a" +
    "left join userinfo u on a.uid=u.id")
    List<Articleinfo> getAll();
}

测试类:

class ArticleMapperTest {
    @Autowired
    private ArticleMapper articleMapper;
    @Test
    void getAll() {
        List<Articleinfo> list = articleMapper.getAll();
        System.out.println(list);
    }
}


 三、动态SQL

  动态SQL时MyBatis的强大特性之一,可以完成不同条件下的sql拼接,就是在XML文件中动态的去写判断条件。以下是一些动态标签:

        🍅 <if>标签

语法:

        <if test="photo!=null">

                ........

        </if>

//代码示例


int add2(UserInfo userinfo);


<insert id="add2">
        insert into userinfo(username,password
        <if test="photo!=null">
            ,photo
        </if>
        )values (#{username},#{password}
        <if test="photo!=null">
            ,#{photo}
        </if>
        )
    </insert>

        🍅 <trim>标签

<trim>标签中有如下属性:

        * prefix:表示整个语句块,以prefix的值作为前缀

        * suffix:表示整个语句块,以suffix的值作为后缀

        * prefixOverrides:表示整个语句块要去除掉的前缀

        * suffixOverrides:表示整个语句块要去除掉的后缀

int add3(UserInfo userInfo);


<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>

        🍅 <where>标签

<where>标签:

        * 根据有<where>标签中的内容决定是否生成“where”关键字

        * 去除最前面的“and”关键字,不能去掉后面的

<!--    直接写select * from userinto where会报错,但是使用where标签就不会报错-->
    <select id="getListByWhere" resultType="com.example.demo.model.UserInfo">
        select * from userinfo
        <where>
            <if test="id!=0">
                id=#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=null">
                and password=#{password}
            </if>
        </where>
    </select>

使用<trim>标签也可以生成where

<select id="getListByWhere" resultType="com.example.demo.model.UserInfo">
        select * from userinfo    
    <trim prefix="where" prefixOverrides="and">
            <if test="id!=0">
                id=#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=null">
                and password=#{password}
            </if>
        </trim>
    </select>

        🍅 <set>标签

        和where标签使用一样

<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>

        🍅 <foreach>标签

MyBatis提供了<foreach>标签来处理动态SQL中的循环操作。这个标签允许你在SQL语句中迭代一个集合,并生成重复的SQL片段。

    <foreach>标签属性:

                * collection:绑定方法参数中的集合,如List,Set,Map或数组对象

                * item:遍历时的每一个对象

                * open:语句块开头的字符串

                * close:语句块结束的字符传

                * separator:每次遍历之间间隔的字符串 

以下例子可以看成是:

delete from userinfo where id in(?,?,?,?) 
    <delete id="delByIds">
        delete from userinfo
        where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>
//测试类
@Test
    void delByIds() {
        List<Integer> list = new ArrayList<Integer>(){{
            add(8);
            add(9);
            add(10);
            add(11);
        }};
        int result = userMapper.delByIds(list);
        System.out.println("result" + result);
    }

四、注意

🍅1、mybatisx插件报错

 以上并非系统报错,而是插件在报错,告诉我们没有设置返回的技术类型,高版本的idea遇到这种情况运行是不会报错的。

🍅2、数据回滚

 @Transactional   //数据回滚:使用该注解,会执行下面操作,但是不会真的操作数据库中的内容

🍅 3、查询某字段结果为null时

原因是:实体类中的属性和数据库表中的字段名不一致。

       解决方案:

        1.将实体类中的属性和表中的字段名保持一致(最简单的解决方案)

        2.使用sql语句中的as进行列名(字段名)重命名,让列名(字段名)等于属性名

<!--   加入要查询的字段名应该是name,对name进行重命名 -->
<selet id="getUserById" resultType="com.example.demo.model.UserInfo">
        select username as name from userinfo where id=#{id}c
    </select>

        3.定义一个resultMap,将属性名和字段名进行手动映射

        resultMap放入mapper.xml的<mapper></mapper>中 

<resultMap id="UserMapper" type="com.example.demo.model.UserInfo">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
    </resultMap>
<select id="getUserById" resultMap="BaseMap">
        select * from userinfo where id=#{id}
    </select>

以下是对应关系:尽量把全部属性映射上,否则多表查询时可能会报错。

上图有个错误!!!  colum是表里面的字段名,property是实体类里的属性,写反了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/822705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 基础进阶总结(一)反射机制学习总结

文章目录 一、初识反射机制1.1 反射机制概述1.2 反射机制概念1.3 Java反射机制提供的功能1.4 反射机制的优点和缺点 二、反射机制相关的 API2.1 一、初识反射机制 1.1 反射机制概述 JAVA 语言是一门静态语言&#xff0c;对象的各种信息在程序运行时便已经确认下来了&#xff0…

延长周末体验感

延长周末体验感 写在最前面周末的时间规划题外话善解人意的chatgpt 提升周末体验感的好方法随机选择一个周末活动 怎样才能获得充分的休息 写在最前面 话题征文~ https://activity.csdn.net/creatActivity?id10533&spm1011.2432.3001.9644 工作以后常常容易感到疲于奔命…

python简单小游戏代码100行,python小游戏程序源代码

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python简单小游戏代码100行&#xff0c;python小游戏代码能用的&#xff0c;现在让我们一起来看看吧&#xff01; Python编写简易猜数字小游戏&#xff08;附完整代码&#xff09; 猜数字游戏是一款非常经典的小游戏&am…

AD21 PCB设计的高级应用(九)3D PDF的输出

&#xff08;九&#xff09;3D PDF的输出 1.3D PDF的输出2.制作PCB 3D视频 1.3D PDF的输出 Altium Designer 19 带有 3D输出功能,能够直接将 PCB 的 3D效果输出到 PDF 中。 ’(1)打开带有 3D 模型的 PCB 文件,执行菜单栏中“文件”→“导出”→“PDF3D”命令&#xff0c;选择…

P1419 寻找段落(二分答案)(内附封面)

寻找段落 题目描述 给定一个长度为 n n n 的序列 a a a&#xff0c;定义 a i a_i ai​ 为第 i i i 个元素的价值。现在需要找出序列中最有价值的“段落”。段落的定义是长度在 [ S , T ] [S, T] [S,T] 之间的连续序列。最有价值段落是指平均值最大的段落。 段落的平均值…

SpringBoot整合TrueLicense生成和验证License证书

一 License介绍 License&#xff0c;也就是版权许可证书&#xff0c;一般用于收费软件给付费用户提供的访问许可证明。根据应用部署位置的不同&#xff0c;一般可以分为以下几种情况讨论&#xff1a; 应用部署在开发者自己的云服务器上。这种情况下用户通过账号登录的形式远程…

Halcon——在C#中各数据类型的相互转换

Halcon——在C#中各数据类型的相互转换 前言一、HObject to1.HObject to HImage 二、HTuple to1.HTuple to Int2.HTuple to Double3.HTuple to String4.HTuple to long5.HTuple to object6.HTuple to Arr 总结 前言 用c#进行Halcon代码转换的时候&#xff0c;虽然有halcon自带…

Python基础语法-梳理的几个知识点

1.书写格式 不需要声明变量类型&#xff0c;因为 在python中&#xff0c;变量为弱类型变量&#xff0c;Python解析器根据值自动匹配变量类型分支结构、循环结构中的条件表达式&#xff0c;不需要用小括号括起来执行语句体不需要大括号括起来&#xff0c;而是用冒号代替 2.格式…

GRNN神经网络原理与matlab实现

1案例背景 1.1GRNN神经网络概述 广义回归神经网络(GRNN Generalized Regression Neural Network&#xff09;是美国学者 Don-ald F. Specht在1991年提出的,它是径向基神经网络的一种。GRNN具有很强的非线性映射能力和柔性网络结构以及高度的容错性和鲁棒性,适用于解决非线性问…

使用 JMeter 进行压力测试

一.前言 压力测试是每一个Web应用程序上线之前都需要做的一个测试&#xff0c;他可以帮助我们发现系统中的瓶颈问题&#xff0c;减少发布到生产环境后出问题的几率&#xff1b;预估系统的承载能力&#xff0c;使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步…

套接字通信(C/C++ 多线程)----基于线程池的并发服务器

&#xff08;一&#xff09;大家可以看我写的这三篇&#xff0c;了解一下&#xff1a; 基于linux下的高并发服务器开发&#xff08;第四章&#xff09;- 多线程实现并发服务器_呵呵哒(&#xffe3;▽&#xffe3;)"的博客-CSDN博客https://blog.csdn.net/weixin_4198701…

Jmeter如何添加插件

一、前言 ​ 在我们的工作中&#xff0c;我们可以利用一些插件来帮助我们更好的进行性能测试。今天我们来介绍下Jmeter怎么添加插件&#xff1f; 2023最新Jmeter接口测试从入门到精通&#xff08;全套项目实战教程&#xff09; 二、插件管理器 ​ 首先我们需要下载插件管理器j…

一个完整的http请求响应过程

一、 HTTP请求和响应步骤 图片来自&#xff1a;理解Http请求与响应 以上完整表示了HTTP请求和响应的7个步骤&#xff0c;下面从TCP/IP协议模型的角度来理解HTTP请求和响应如何传递的。 二、TCP/IP协议 TCP/IP协议模型&#xff08;Transmission Control Protocol/Internet Pr…

04、并发用户数该怎么计算

什么是并发&#xff1f; 我们假设上图中的这些小人是严格按照这个逻辑到达系统的&#xff0c;那显然&#xff0c;系统的绝对并发用户数是 4。如果描述 1 秒内的并发用户数&#xff0c;那就是 16。是不是显而易见&#xff1f;但是&#xff0c;在实际的系统中&#xff0c;用户通常…

若依框架 - 对二次封装数据分页

LsDistrictController /*** 查询地段列表*/ApiOperation("查询地段列表")GetMapping("/list")public TableDataInfo list(LsDistrict lsDistrict) {startPage();Map<String, List> map lsDistrictService.selectLsDistrictList(lsDistrict);if (Col…

java类和对象详解(1)

面向对象的初步认知 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program, 简称OOP),在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。 用面向对象的思想来涉及程序&#xff0c;更…

AntdesignVue 时间设置为年份不回显问题解决

时间设置为年份回显时报如下错误 年份设置值后报value异常 解决方案 格式不一致导致的 moment格式化后是string类型&#xff0c;后台返回的是Number类型导致的&#xff0c;统一格式就会显示了

人工智能安全-3-噪声数据处理

0 提纲 噪声相关概述噪声处理的理论与方法基于数据清洗的噪声过滤主动式过滤噪声鲁棒模型1 噪声相关概述 噪声类型: 属性噪声:样本中某个属性的值存在噪声标签噪声:样本归属类别关于噪声分布的假设:均匀分布、高斯分布、泊松分布等。 标签噪声的产生原因: (1)特定类别…

Unity 引擎做残影效果——1、BakeMesh

Unity实现残影效果 大家好&#xff0c;我是阿赵。   这次来分享一下在Unity里面做残影的效果。   所谓的残影&#xff0c;就是在角色移动的过程中&#xff0c;留下一串残留的影子。 这种效果比较常出现在格斗游戏和动作游戏。   在Unity里面做残影&#xff0c;方法很多…