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

目录

前言

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  #自动驼峰转换

 


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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值