使用MyBatis(2)

目录

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

二、MyBatis的增删改查 

🍅1、MyBatis传递参数查询

        🎈写法一

         🎈写法二

        🎈两种方式的区别

🍅2、删除操作

🍅3、根据id修改用户名

🍅4、添加用户操作

        🎈返回受影响的行数

        🎈返回自增id

🍅5、like查询

🍅6、多表查询

三、注意

🍅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);
    }
}

 


三、注意

🍅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是实体类里的属性,写反了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WPF线程使用详解:提升应用性能和响应能力

在WPF应用程序开发中&#xff0c;线程的合理使用是保证应用性能和响应能力的关键。WPF提供了多种线程处理方式&#xff0c;包括UI线程、后台线程、Task/Async Await和BackgroundWorker。这些方式与传统的Thread类相比&#xff0c;更加适用于WPF框架&#xff0c;并能够简化线程操…

使用pikachu管理工具下的XSS后台进行实战

写在前面的重要提示&#xff1a; Attention&#xff1a;技术没有好坏之分&#xff0c;关键在于使用技术的人或组织。网络安全技术是一把双刃剑 – 作为网络安全人&#xff0c;虽然无法控制头上的帽子是否会变绿&#xff0c;但能控制不让它变黑&#xff1b;无论我们在物质上面对…

深度学习实践——卷积神经网络实践:裂缝识别

深度学习实践——卷积神经网络实践&#xff1a;裂缝识别 系列实验 深度学习实践——卷积神经网络实践&#xff1a;裂缝识别 深度学习实践——循环神经网络实践 深度学习实践——模型部署优化实践 深度学习实践——模型推理优化练习 深度学习实践——卷积神经网络实践&#xff…

VUE之VueRouter页面跳转

参考资料&#xff1a; 参考视频 参考demo及视频资料 VUE之基本部署及VScode常用插件 VUE之基本组成和使用 VUE之Bootstrap和Element-UI的使用 VUE之axios使用&#xff0c;跨域问题&#xff0c;拦截器添加Token Vue Router官网 Vue Router说明&#xff1a; 说明&#xf…

【计算机网络】10、ethtool

文章目录 一、ethtool1.1 常见操作1.1.1 展示设备属性1.1.2 改变网卡属性1.1.2.1 Auto-negotiation1.1.2.2 Speed 1.1.3 展示网卡驱动设置1.1.4 只展示 Auto-negotiation, RX and TX1.1.5 展示统计1.1.7 排除网络故障1.1.8 通过网口的 LED 区分网卡1.1.9 持久化配置&#xff08…

详细介绍 React 中如何使用 redux

在使用之前要先了解它的配套插件&#xff1a; 在React中使用redux&#xff0c;官方要求安装其他插件 Redux Toolkit 和 react-redux Redux Toolkit&#xff1a;它是一个官方推荐的工具集&#xff0c;旨在简化 Redux 的使用和管理。Redux Toolkit 提供了一些提高开发效率的工具…

GO语言日志切割 + 记录调用源

准备工作 日志记录对程序排查问题比较关键&#xff0c;记录下GO中日志选择&#xff0c;从以下出发点考虑&#xff1a; 日志文件能自动切割&#xff0c;以免过大能记录从哪个文件哪行代码调用的&#xff0c;方便排查问题配置简单明了库文件使用人数较多&#xff0c;稳定 经过一段…

ChatIE:通过多轮问答问题实现实命名实体识别和关系事件的零样本信息抽取,并在NYT11-HRL等数据集上超过了全监督模型

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

python读取json文件

import json# 文件路径(同目录文件名即可,不同目录需要绝对路径) path 1.json# 读取JSON文件 with open(path, r, encodingutf-8) as file:data json.load(file)#data为字典 print(data) print(type(data))

文件上传

js绕过 打开网页尝试上传一句话木马&#xff0c;发现只能上传图片文件 审计源代码&#xff0c;发现使用一个checkfile函数js对文件类型进行了屏蔽 于是我们修改网页代码&#xff0c;去除返回值的检查函数 checkFile() 上传成功&#xff0c;使用蚁剑连接 连接成功 .htaccess绕…

element-ui使用动态渲染下拉选择框el-select已经选择的下拉框的值不可以重复选择让其disabled

调接口拿到下拉框数据的数据的时候将其disabled全为true 但是如果编辑的时候就需要与详情接口对比&#xff0c;如果有id一致就将disabled为true if (res.code 0) {if (this.dialogtitle "新增合同") {res.data.map((v) > {v.nameUnitVoList.forEach((item) >…

小程序新渲染引擎 Skyline 发布正式版

为了进一步提升小程序的渲染性能和体验&#xff0c;我们推出了一套新渲染引擎 Skyline&#xff0c;现在&#xff0c;跟随着基础库 3.0.0 发布 Skyline 正式版。 我们知道&#xff0c;小程序一直用 WebView 来渲染界面&#xff0c;因其有不错的兼容性和丰富的特性&#xff0c;且…

lc209.长度最小的子数组

暴力破解&#xff1a;二次for循环遍历num[i]...num[j]&#xff0c;记录满足条件的最小长度 前缀和二分&#xff1a;前缀和降低计算num[i]...num[j]的时间复杂度 对前缀和数组中的每个数进行遍历&#xff0c;找到距离这个数满足条件的最小长度 前缀和数组单调递增&#xff0c;此…

最小时间差(力扣)排序 + 思维 JAVA

给定一个 24 小时制&#xff08;小时:分钟 “HH:MM”&#xff09;的时间列表&#xff0c;找出列表中任意两个时间的最小时间差并以分钟数表示。 示例 1&#xff1a; 输入&#xff1a;timePoints [“23:59”,“00:00”] 输出&#xff1a;1 示例 2&#xff1a; 输入&#xff1a;…

支持向量机(iris)

代码&#xff1a; import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn import svm import numpy as np# 定义每一列的属性 colnames [sepal-length, sepal-width, petal-length, petal-width, class] # 读取数据 iris pd.read_csv(data\\i…

[自然语言处理] 自然语言处理库spaCy使用指北

spaCy是一个基于Python编写的开源自然语言处理库。基于自然处理领域的最新研究&#xff0c;spaCy提供了一系列高效且易用的工具&#xff0c;用于文本预处理、文本解析、命名实体识别、词性标注、句法分析和文本分类等任务。 spaCy的官方仓库地址为&#xff1a;spaCy-github。本…

信号的学习笔记二

文章目录 信号捕捉signal信号捕捉sigaction信号集未决信号集和阻塞信号集的工作过程 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b896346af6f1462089779e513a7e237b.png)信号集相关函数sigemptysetsigfillsetsigaddsetsigdelsetsigismember应用 以下函数设置内核信号集…

八股总结(八)SSM框架体系

文章目录 Spring基础1、Spring、SpringMVC、Mybatis与SpringBoot的区别2、Spring中常用的注解及作用 Spring IoC 、 DI、Bean3、Spring IoC是什么&#xff0c;有什么好处&#xff0c;Spring中是怎么实现的&#xff1f;4、Bean相关5、Component 和 Bean 的区别是什么&#xff1f…

Java-简单认识类和对象

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

系统架构设计师 10:软件架构的演化和维护

一、软件架构演化 如果软件架构的定义是 SA{components, connectors, constraints}&#xff0c;也就是说&#xff0c;软件架构包括组件、连接件和约束三大要素&#xff0c;这类软件架构演化主要关注的就是组件、连接件和约束的添加、修改与删除等。 二、面向对象软件架构演化…