首页 > 其他分享 >使用标签实现MyBatis的基础操作

使用标签实现MyBatis的基础操作

时间:2024-10-08 23:48:23浏览次数:8  
标签:username 标签 age userinfo SQL MyBatis 操作 id Select

目录

前言

1.配置MyBatis⽇志打印

2.参数传递 

2.1 #{} 和 ${}区别

 2.2传递多个参数

 3.增删改查

3.1增(Insert)

3.2删(Delete)

3.3改(Update)

 3.4查(Select)


前言

 接下来我们会使用的数据表如下:

对应的实体类为:UserInfoMapper

所有的准备工作都在如下文章。

MyBatis 操作数据库入门-CSDN博客文章浏览阅读169次,点赞5次,收藏11次。什么是MyBatis?MyBatis是⼀款优秀的 持久层 框架,⽤于简化JDBC的开发Mybatis操作数据库的入门步骤:1.创建springboot⼯程2.数据库表准备、实体类3.引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)4.编写SQL语句(注解/XML) ,进行测试了解更多MyBatis中文网1.创建springboot⼯程创建springboot⼯程,并导⼊ mybatis的起步依赖、mysql的驱动包。https://blog.csdn.net/WHabc2002/article/details/142743762

 


1.配置MyBatis⽇志打印

在Mybatis当中我们可以借助⽇志, 查看到sql语句的执⾏、执⾏传递的参数以及执⾏结果 在配置⽂件中进⾏配置即可

 如果是application.yml, 配置内容如下

mybatis:
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
如果是application.properties, 配置内容如下
#指定mybatis输出⽇志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

 打印形式如下:


2.参数传递 

 像select * from userinfo where id=4这种SQL语句已经写死,只能查找id=4 的数据。我们想要更加自由的使用SQL语句,我们就需要动态的数值。

解决⽅案:

将⽅法中的参数,传给SQL语句,使⽤ #{}或${} 的⽅式获取⽅法中的参数

2.1 #{} 和 ${}区别

1.预编译SQL和即时SQL 的区别

1.#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句 中. #{} 会根据参数类型, ⾃动拼接引号 " " 2.${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 " "

 1.#{}

    @Select("select * from userinfo where username = #{userName}")
    public Userinfo getUserByName(String userName);

测试结果:

 2.${}

  @Select("select * from userinfo where username = '${userName}'")
    public Userinfo getUserByName2(String userName);

测试结果:

 2.#{}的效率更高

   绝⼤多数情况下, 某⼀条 SQL 语句可能会被反复调⽤执⾏, 或者每次执⾏的时候只有个别的值不同 如果每次都需要 经过1.语法解析, 2.SQL优化、3.SQL编译等,则效率就明显不⾏了。    预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译 (只是输⼊的参数不同), 省去了解析优化等过程, 以此来提⾼效率

3.#{}更安全(防⽌SQL注⼊) 

因为${} 会直接进⾏字符替换, ⼀起对SQL进⾏编译

SQL注⼊:

  是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的 ⽅法。

 可以得出结论: ${} 会有SQL注⼊的⻛险, 所以我们尽量使⽤#{}完成查询

 既然如此, 是不是 ${} 就没有存在的必要性了呢?

当然不是,#{} 会根据参数类型, 如果参数类型为String,⾃动拼接引号 " ",当我们不想要⾃动拼接引号 " "时,我们选择${},但一旦使用了${},就一定要考虑SQL注入。

例子1:排序

使用 ${}时

    @Select("select * from userinfo order by id ${sort}")
    public List<Userinfo> queryAllUser2(String sort);

测试结果:

 

使用 #{}时

    @Select("select * from userinfo order by id #{sort}")
    public List<Userinfo> queryAllUser3(String sort);

测试结果:

 

2.like 查询 

 @Select("select * from userinfo where username like '%${key}%'")
    public List<Userinfo> queryAllUser3(String key);
#{}会SQL错误,但是${}存在SQL注⼊的问题, 所以不能直接使⽤ ${} 解决办法: 使⽤ mysql 的内置函数 concat() 来处理,实现代码如下:
@Select("select * from userinfo where username like concat('%',#{username},'%')")
    public List<Userinfo> queryAllUser4(String key);

 2.2传递多个参数

1.如果SQL语句中只有一个变量,变量名不需要与参数名对应。

2.如果SQL语句中有多个变量,变量名必需与参数名对应。

3.会自动生成对应参数比如param1自动对应函数的第一个参数。

    @Select("select * from userinfo where username = #{userName} and age = #{age}")
    public List<Userinfo> queryAllUser5(String userName1,int age);

测试结果:

也可以通过 @Param , 设置参数的别名, 如果使⽤ @Param 设置别名, #{...}⾥⾯的属性名必须和 @Param 设置的⼀样

 3.增删改查

3.1增(Insert)

    @Insert("insert into userinfo (username, password, age, gender) " +
            "values (#{username},#{password},#{age},#{gender})")
    Integer insert(Userinfo userinfo);

测试代码:

    @Test
    void insert() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("wh");
        userinfo.setPassword("123456");
        userinfo.setAge((byte) 18);
        userinfo.setGender((byte) 1);
        Integer insert = userInfoMapper.insert(userinfo);
        System.out.println(insert);
    }

结果:

 

注意:如果设置了 @Param 属性, #{...}对象就只能是一个整体需要使⽤ 参数.属性 来获取。

    @Insert("insert into userinfo (username, password, age, gender) " +
            "values (#{userinfo.username},#{userinfo.password},#{userinfo.age},#{userinfo.gender})")
    Integer insert2(@Param("userinfo") Userinfo userinfo);
返回主键 如果想要拿到⾃增id, 需要在Mapper接⼝的⽅法上添加⼀个Options的注解 keyProperty:指定能够唯⼀识别对象的属性
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into userinfo (username, password, age, gender) " +
            "values (#{username},#{password},#{age},#{gender})")
    Integer insert3(Userinfo userinfo);

测试代码:

    @Test
    void insert3() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("bbb");
        userinfo.setPassword("bbb");
        userinfo.setAge((byte) 18);
        userinfo.setGender((byte) 1);
        Integer insert = userInfoMapper.insert3(userinfo);
        System.out.println(userinfo.getId());
    }

3.2删(Delete)

@Delete("delete from userinfo where id = #{id}")
    Integer delete(Integer id);

3.3改(Update)

@Update("update userinfo set password = #{password} where id = #{id}")
    Integer update(UserInfo userInfo);

 3.4查(Select)

    @Select("select * from userinfo")
    public List<UserInfo> queryAllUser();

 测试结果:

原因; 

当⾃动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性 

解决办法:

1.起别名

2.结果映射

 /**
     * 起别名
     * @return
     */
    @Select("SELECT id, username, password, age, gender, phone, " +
            "delete_flag as deleteFlag, create_time as createTime, update_time as updateTime " +
            "FROM `userinfo`")
    List<UserInfo> selectUserInfos();

    /**
     * 指定结果映射关系
     * @return
     */
    @Results(id ="resultMap" , value = {
            @Result(column = "delete_flag", property = "deleteFlag"),
            @Result(column = "create_time", property = "createTime"),
            @Result(column = "update_time", property = "updateTime")
    })
    @Select("SELECT * FROM `userinfo`")
    List<UserInfo> selectUserInfos2();

 3.开启驼峰命名(推荐)

通常数据库列使⽤蛇形命名法进⾏命名(下划线分割各个单词), ⽽ Java 属性⼀般遵循驼峰命名法约定. 为了在这两种命名⽅式之间启⽤⾃动映射,需要将 mapUnderscoreToCamelCase 设置为 true。 我们进行如下配置即可 以application.yml为例:
mybatis:
  configuration:
    map-underscore-to-camel-case: true  #自动驼峰转换

 


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

标签:username,标签,age,userinfo,SQL,MyBatis,操作,id,Select
From: https://blog.csdn.net/WHabc2002/article/details/142745011

相关文章

  • javascript学习——CSS 操作总结
    CSS操作CSS与JavaScript是两个有着明确分工的领域,前者负责页面的视觉效果,后者负责与用户的行为互动。但是,它们毕竟同属网页开发的前端,因此不可避免有着交叉和互相配合。本章介绍如何通过JavaScript操作CSS。HTML元素的style属性操作CSS样式最简单的方法,就是......
  • D29【python 接口自动化学习】- python基础之输入输出与文件操作
    day29格式化输出学习日期:20241006学习目标:输入输出与文件操作﹣-41格式化输出:如何将执行结果通过屏幕输出?学习笔记:三种常用的格式化输出方式 百分号方式 format函数方式 总结1.格式化输出是为了让提示信息和输出的结果更人性化2.可以根据输出的复杂度和特点,......
  • D30【python 接口自动化学习】- python基础之输入输出与文件操作
    day30F-strings输出学习日期:20241007学习目标:输入输出与文件操作﹣-42F-strings-如何通过定义好的格式进行输出?学习笔记:F-strings介绍F-strings的计算功能F-strings宽度和精度调整练习#宽度为10个字符,不足补0print(f'{number:010}')#000123.456#指定类......
  • D31【python 接口自动化学习】- python基础之输入输出与文件操作
    day31文件的打开学习日期:20241008学习目标:输入输出与文件操作﹣-43常见常新:文件的打开学习笔记:文件的概念使用open()函数打开文件文件路径处理文件打开模式总结文件操作包括:打开,关闭,读取,写入类Unix系统中设备,虚拟设备,网络套接字等都被当作文件可以学......
  • 7-1单链表的基本操作
    题目:7-1单链表基本操作分数20作者朱允刚单位吉林大学请编写程序实现单链表插入、删除结点等基本算法。给定一个单链表和一系列插入、删除结点的操作序列,输出实施上述操作后的链表。单链表数据域值为整数。输入格式:输入第1行为1个正整数n,表示当前单链表长度;第2行为n个......
  • 对UVM添加超时前的打印信息+AXI低功耗接口+process的await语句+对象当成参数+sv的单例
    对UVM添加超时前的打印信息首先获取到UVM的超时值,然后手动设定\$time的比较和while延时循环,当超出时间后,打印特殊的debug信息。$time<set_time,则进行循环。uvm_cmdline_processorclp;clp=uvm_cmdline_processor::get_inst();stringtimeout_settings[$];stringtimeout......
  • SpringBoot整合Easy-ES实现对ES操作
    Easy-ES简介Easy-ES是一个基于Elasticsearch的Java客户端库,旨在简化与Elasticsearch的交互。它为开发者提供了更易用、更高效的API,帮助他们快速实现数据的索引、查询、更新和删除等操作。主要特性简化的API提供直观友好的接口,降低了使用Elasticsearch的学习曲......
  • ROS2二十一讲学习——ROS2命令行操作
    Linux中的命令行命令行界面(Command-lineinterface,缩写:CLI):通常认为,命令行界面(CLI)没有图形用户界面(GUI)那么方便用户操作。因为,命令行界面的软件通常需要用户记忆操作的命令,但是,由于其本身的特点,命令行界面要较图形用户界面节约计算机系统的资源。在熟记命令的前提下,使用......
  • 轻松上云怎么操作?IoT_CLOUD之中移OneNET
    ​ 最近来了很多新朋友,也经常被问:可以多讲些云平台的操作吗?当然可以!文末留言你想要了解的云平台,优先安排~接下来,本文将以Air780E+LuatOS作为示例,教你使用合宙IoT_CLOUD连接中移OneNET物联网云平台。 一、IoT_CLOUD简 1.1IoT_CLOUD特色简介IoT_CLOUD——是合宙专门为了......
  • C++刷题:加一操作
    问题描述小W拥有一项魔法,可以对任意数字字符串进行加一的操作,比如当他拿到“798”这样的数字字符串,每一次操作,他会将其中每一个字符进行加一,比如经过一次操作后得到了“8109”。他想知道操作`k`次后,这个数字将会变成多少,由于答案可能很大,最终结果需要对1000000007取......