【MyBatis】| MyBatis使用⼩技巧

news2024/11/26 12:31:21

目录

一:MyBatis使用⼩技巧

1. #{}和${}

2. typeAliases

3. mappers

4. IDEA配置⽂件模板

5. 插⼊数据时获取⾃动⽣成的主键


一:MyBatis使用⼩技巧

1. #{}和${}

#{}:先编译sql语句,再给占位符传值,底层是PreparedStatement实现。可以防⽌sql注⼊,⽐较常⽤。

${}:先进⾏sql语句拼接,然后再编译sql语句,底层是Statement实现。存在sql注⼊现象。只有在需要进⾏sql语句关键字拼接的情况下才会⽤到。

(1)定义接口CarMapper ,面向接口编程

package com.bjpowernode.mybatis.mapper;

import com.bjpowernode.mybatis.pojo.Car;

import java.util.*;

public interface CarMapper {
    // 根据汽车类型查询
    List<Car>  selectByCarType(String carType);
}

(2)在CarMapper.xml文件中编写sql语句

注意:namespace是接口CarMapper的完整类名,id是接口对应的方法名

<?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.bjpowernode.mybatis.mapper.CarMapper">
    <select id="selectByCarType" resultType="com.bjpowernode.mybatis.pojo.Car">
      select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from t_car
        where car_type = #{carType}
    </select>
</mapper>

(3)编写测试类,看执行结果对比

package com.bjpowernode.mybatis.test;

import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void testSelectByCarType(){
        SqlSession sqlSession = SqlSessionUtils.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByCarType("燃油车");
        for (Car car :cars){
            // 会调toString方法
            System.out.println(car);
        }
        sqlSession.close();
    }
}

①使用#{}执行结果,能正常执行结果

特点:先执行SQL语句的编译,然后给SQL语句的占位符问号?传值

②使用${}执行结果,会抛出异常,直接拼接字符串但是没有引号

特点:先执行SQL语句的拼接,然后再对SQL语句进行编译

(4)#{}和${}的选择

注:如果需要SQL语句的关键字放到SQL语句中,只能使用${},因为#{}是以值的形式放到SQL语句当中;例如:升序或者降序排需要传asc或者desc,此时要把这个关键字传进去,就需要${}

①接口类中的方法

package com.bjpowernode.mybatis.mapper;
import com.bjpowernode.mybatis.pojo.Car;
import java.util.*;

public interface CarMapper {
    // 根据汽车类型查询
    List<Car>  selectByCarType(String carType);

    // 查询所有的汽车信息,然后通过asc升序,desc降序
    List<Car> selectByAscOrDesc(String ascOrDesc);
}

②编写sql语句,根据传参按照produce_time升序或者降序

<?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.bjpowernode.mybatis.mapper.CarMapper">
    <select id="selectByCarType" resultType="com.bjpowernode.mybatis.pojo.Car">
      select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from t_car
        where car_type = #{carType}
    </select>

    <select id="selectByAscOrDesc" resultType="com.bjpowernode.mybatis.pojo.Car">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        order by
            produce_time #{ascOrDesc}
    </select>
</mapper>


③编写测试程序

package com.bjpowernode.mybatis.test;

import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class CarMapperTest {
    @Test
    public void selectByAscOrDesc(){
        SqlSession sqlSession = SqlSessionUtils.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
        List<Car> cars = mapper.selectByAscOrDesc("asc");
        for (Car car :cars){
            // 会调toString方法
            System.out.println(car);
        }
        sqlSession.close();
    }
}

使用#{},先编译在传值,传的是一个字符串,会有引号,明显不符合语法!

 使用${},先把关键字拼串上去,在进行编译,符合语法规则!

(5) 使用${}完成表名拼接

注:这里需要查询新的表名,所以需要编写新的PoJo类Log、新建配置文件LogMapper.xml、新建一个接口LogInterface、新建测试类LogMapperTest类进行测试、在核心配置文件mybatis-config.xml当中引入LogMapper.xml

①现实业务当中,可能会存在分表存储数据的情况,因为一张表存储数据的话,数据量太大,查询效率比较低。
②可以将这些数据有规律的分表存储,这样扫描的数据量变少了,在查询的时候效率就比较高。例如日志表:专门存储日志信息的,可以每天生成一个新表,每张表以当天日期作为名称,例如:t_log_20220901、t_log_20220902....
③假如想知道某一天的日志信息,假设今天是20230103,那么直接把日期传进去,完成“t_log_日期表”的拼接。

<?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.powernode.mybatis.mapper.LogMapper">

    <select id="selectAllByTable" resultType="com.bjpowernode.mybatis.pojo.Log">
        <!--select * from t_log_#{date}-->
        select * from t_log_${date}
    </select>

</mapper>

(6)使用${}完成批量删除

注:批量删除对应的sql语句有两种写法

第一种:使用or的形式,delete from t_user where id = 1 or id = 2 or id = 3;

第二种:使用in的形式,delete from t_user where id in(1, 2, 3);

①定义的方法中参数实际上是一个String类型的字符串,我们传参的时候,也是一个字符串传过去,例如:mapper.deleteBatch("1,2,3")的形式。

②关键是我们先拼串再编译,还是先编译在传值;前者是字符串的完美拼接,后者是直接把一个字符串传过去,会带有引号!

<delete id="deleteBatch">
     delete from t_car where id in(${ids})
</delete>

(7)使用${}完成模糊查询

需求:根据汽车品牌进行模糊查询
例如:select * from t_car where brand like '%奔驰%';

<select id="selectByBrandLike" resultType="CAR">
        select
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
        where
            <!--brand like '%#{brand}%'-->
            brand like '%${brand}%'
            brand like concat('%',#{brand},'%')
            brand like concat('%','${brand}','%')
            brand like "%"#{brand}"%"
</select>

①如果使用"%#{brand}%",最终#{}底层肯定是转化为?,但是比较尴尬的是放到双引号或者单引号"?"的?是无法识别的,所以无法进行传值!

②解决方法1:使用"%${brand}%",会先进行拼串,然后在编译!

③解决方法2:concat函数,这个是mysql数据库当中的一个函数,专门进行字符串拼接,concat('%',#{brand},'%');这里也可以使用${band},外面加一个单引号,比较鸡肋,
concat('%','${brand}','%')。

④解决方法3:"%"#{brand}"%",把两个%用引号括起来,就能识别中间的?了,就能正常传值了。

2. typeAliases

使用 typeAliases标签完成别名机制!

(1)我们打开CarMapper.xml文件,发现resultType标签的全限定名称很长,包括我们以后写其它类型的查询语句,都要写这个带包的类名;所以就使用别名机制先定义别名。

 <select id="selectByCarLike" resultType="com.bjpowernode.mybatis.pojo.Car">
 </select>

(2)第一种:在核心配置文件mybatis-config.xml文件中使用typeAliases标签下的子标签typeAlias标签起别名。

注:namespace标签必须写全限定名称,是不能起别名的!

①type属性:指定给那个类型起别名

②alias:指定别名

    <typeAliases>
        <typeAlias type="com.bjpowernode.mybatis.pojo.Car" alias="car" />
    </typeAliases>

③ 这样就能在CarMapper.xml文件中运用别名了,并且不区分大小写!

 <select id="selectByCarLike" resultType="car">
 </select>

④实际上alias属性是可以省略的,有默认的别名,别名是类的简名;例如:com.bjpowernode.mybatis.pojo.Car对应的就是Car、car、cAr等等,不区分大小写。

(3)第二种:在核心配置文件mybatis-config.xml文件中使用typeAliases标签下的子标签package指定包名即可。(常用)

我们使用package标签指定一个包名,那么这个包下所有的类全部自动起别名,别名就是类简名,不区分大小写

    <typeAliases>
        <package name="com.bjpowernode.mybatis.pojo" />
    </typeAliases>

 (4)小总结

所有别名不区分大小写;namespace不能使用别名机制!

    <typeAliases>
        <!--别名自己指定的-->
        <typeAlias type="com.powernode.mybatis.pojo.Car" alias="aaa"/>
        <typeAlias type="com.powernode.mybatis.pojo.Log" alias="bbb"/>

        <!--采用默认的别名机制-->
        <typeAlias type="com.powernode.mybatis.pojo.Car"/>
        <typeAlias type="com.powernode.mybatis.pojo.Log"/>

        <!--包下所有的类自动起别名。使用简名作为别名。-->
        <package name="com.powernode.mybatis.pojo"/>
    </typeAliases>

3. mappers

(1)mapper标签的属性可以有三个:

①resource:这种方式是从类的根路径下开始查找资源;采用这种方式,配置文件需要放到类路径当中才行。
②url:这种方式是一种绝对路径的方式,这种方式不要求配置文件必须放到类路径当中,哪里都行,只要提供一个绝对路径就行;这种方式使用极少,因为移植性太差。
③class:这个位置提供的是mapper接口的全限定接口名,必须带有包名的。
例如:<mapper class="com.powernode.mybatis.mapper.CarMapper"/>,class指定的是:com.powernode.mybatis.mapper.CarMapper,那么mybatis框架会自动去com/powernode/mybatis/mapper目录下查找CarMapper.xml文件。

注意:也就是说,如果采用这种方式,必须保证CarMapper.xml文件和CarMapper接口必须在同一个目录下,并且名字一致。如:CarMapper接口-> CarMapper.xml。

解释:所谓的同一个目录,是在resource目录下创建包名,并且这个包名与java下的CarMapper接口包名必须一致,然后把配置文件CarMapper.xml扔到包名里;实际上java和resource都是根目录,只不过两种展现形式!

解释:在resource下创建包,实际上是创建目录,因为只有在java下创建包才是"点"的形式,例如:com.bjpowernode就表示com目录下的bjpowernode目录;对于resource下创建包就是直接创建目录,例如:com/bjpowernode也表示com目录下的bjpowernode目录,如果采用com.bjpowernode就表示一个名为com.bjpowernode的目录。

 <mappers>
    <mapper resource="CarMapper.xml"/> 要求类的根路径下必须有:CarMapper.xml
    <mapper url="file:///d:/CarMapper.xml"/> 要求在d:/下有CarMapper.xml文件
    <mapper class="com.powernode.mybatis.mapper.CarMapper"/> 全限定接口名,带有包名
 </mappers>

(2)假如有很多个接口名,要写很多个全限定接口名也很麻烦;实际上在mappers标签下还有一个package属性,用来指定包名,这种方式在开发中是比较常用的。

前提:XML文件必须和接口放在一起,并且名字一致!

解释:指定报名,实际上就是指定这个路径,在这个路径下查找配置文件。

<mappers>
    <package name="com.bjpowernode.mybatis.mapper" />
</mappers>

4. IDEA配置⽂件模板

mybatis-config.xml和SqlMapper.xml⽂件可以在IDEA中提前创建好模板,以后通过模板创建配置⽂件

(1)准备好的mybatis-config.xml核心配置文件的模板

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties resource=""/>
    <typeAliases>
        <package name=""/>
    </typeAliases>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name=""/>
    </mappers>
</configuration>

(2)准备好的SqlMapper.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="">
</mapper>

(3)步骤:File--->Settings--->Editor--->File and Code Templates

(4)使用:以后直接alt+insert就能找到这个模板

 (5)选定这个模板后,就会让你输出文件的名字,例如:mybatis-config 

(6)点击ok,就会自动生成我们自定义模板的核心配置文件mybatis-config.xml

5. 插⼊数据时获取⾃动⽣成的主键

(1)前面用的主键一直是自动生成的,所以我们并不知道主键是多少,要是下面这种业务,⼀个⽤户有多个⻆⾊,一对多,两张表,多的表加外键

 (2)插⼊⼀条新的记录之后,⾃动⽣成了主键,⽽这个主键需要在其他表中使⽤时;插⼊⼀个⽤户数据的同时需要给该⽤户分配⻆⾊:需要将⽣成的⽤户的id插⼊到⻆⾊表的user_id字段 上。

①第⼀种⽅式:可以先插⼊⽤户数据,再写⼀条查询语句获取id,然后再插⼊user_id字段。【⽐较麻烦】

②第⼆种⽅式:mybatis提供了⼀种⽅式更加便捷。

(3)主要是在插入数据时,使用两个属性

①useGeneratedKeys="true" 表示使用自动生成的主键值。
②keyProperty="id" 指定主键值赋值给对象的哪个属性,就表示将主键值赋值给Car对象的id属性。

<insert id="insertCarUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
        insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>

(4)测试结果

①如果不加上这两个参数,打印结果主键显示null

 ②如果加上这两个参数,打印结果就会显示自动生成的主键

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

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

相关文章

【C语言进阶】一文带你学会C语言文件操作

前言 我们前面学习结构体时&#xff0c;写了通讯录的程序&#xff0c;当通讯录运行起来的时候&#xff0c;可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯录中的数据自然就不存在了&#xff0c;等下次运行通讯录…

Python---自动生成二维码

专栏&#xff1a;python 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;本专栏主要更新一些python的基础知识&#xff0c;也会实现一些小游戏和通讯录&#xff0c;学时管理系统之类的&#xff0c;有兴趣的朋友可以关注一下。 自动生成二维码 二维码的本质上&#xff0c;就…

人工智能学习06--pytorch05--torchvision中的数据集使用DataLoader的使用

torchvision中的数据集使用 test_set的class属性 把数据集每一部分都变成tensor类型 现在输出的就是tensor数据类型了 DataLoader的使用 batch_size 一摞牌中&#xff0c;每次抓几张shuffle 打乱&#xff0c;第二次打牌前&#xff0c;牌的顺序要跟第一次不一样&#xff0…

【JavaSE】一文看懂构造器/构造方法(Cunstructor)

&#x1f331;博主简介&#xff1a;大一计科生&#xff0c;努力学习Java中!热爱写博客~预备程序媛 &#x1f4dc;所属专栏&#xff1a;Java冒险记【从小白到大佬之路】 ✈往期博文回顾: 【JavaSE】保姆级教程|1万字10张图学会类与对象–建议收藏 &#x1f575;️‍♂️近期目标…

CSS边框、边距、轮廓(边框宽度/颜色/各边/简写属性/圆角边框/内外边距/高度宽度/框模型/轮廓宽度/颜色/属性/偏移)——万字长文|一文搞懂

目录 CSS边框 CSS 边框属性 CSS 边框样式 实例 CSS 边框宽度 实例 特定边的宽度 实例 CSS 边框颜色 实例 特定边框的颜色 实例 HEX 值 实例 RGB 值 实例 HSL 值 实例 CSS 边框 - 单独的边 实例 不同的边框样式 实例 它的工作原理是这样的&#xff1a; …

ROS学习寄录1

1 创建ROS工作空间 1.1 创建工作空间 &#xff08;1&#xff09;创建工作空间 mkdir catkin_ws &#xff08;2&#xff09;进入catkin_ws文件夹&#xff0c;然后创建一个src文件夹 cd catkin_ws mkdir src &#xff08;3&#xff09;进入src文件夹&#xff0c;生成CMakeL…

「自控原理」4.2 根轨迹法分析与校正

本节介绍利用根轨迹法分析系统性能发热方法 本节介绍根轨迹校正 文章目录利用根轨迹分析系统性能主导极点法增加零极点对系统的影响根轨迹校正串连超前校正原理与步骤超前校正例题串连滞后校正附加开环偶极子的作用原理与步骤滞后校正例题利用根轨迹分析系统性能 利用根轨迹分…

Oracle cloud vps实例配置访问

Oracle cloud vps实例配置访问创建一个免费配置的实例&#xff0c;并配置访问创建实例时&#xff0c;系统映像选择创建实例时候的ssh密钥配置子网&#xff0c;打开22端口使用工具登录服务器配置多个公钥&#xff0c;支持多个ssh私钥来登录登录vps实例修改登录用户和身份验证方式…

【接口】接口超时原因分析

接口超时的原因&#xff1a; 一、网络抖动 有可能是你的网络出现抖动、网页请求API接口、接口返回数据给网页丢包了。 二、被带宽占满 用户量暴增&#xff0c;服务器网络带宽被占满。 服务器带宽&#xff1a;一定时间内传输数据的大小&#xff0c;如&#xff1a;1s传输10M…

剑指Offer 第1天

第 1 天 栈与队列&#xff08;简单&#xff09; 剑指 Offer 09. 用两个栈实现队列 class CQueue { public: CQueue() {} void appendTail(int value) { s1.push(value); } int deleteHead() { while(!s1.empty()) { …

【Git :分布式版本控制工具】

【Git &#xff1a;分布式版本控制工具】 了解 Git 基本概念 能够概述 Git 工作流程 能够使用 Git 常用命令 熟悉 Git 代码托管服务 能够使用 IDEA 操作 Git 一、 概述 1. 开发中的实际场景 备份代码还原协同开发追溯问题代码的编写人和编写时间 2. 版本控制器的方式 集中式…

【数据结构】6.6 图的应用

文章目录生成树及其构造生成树的特点无向图的生成树6.6.1 最小生成树最小生成树及其典型应用MST性质构造最小生成树1. Prim(普里姆)算法2. Kruskal(克鲁斯卡尔)算法两种算法比较6.6.2 最短路径最短路径问题1. Dijkstra(迪杰斯特拉)算法迪杰斯特拉算法步骤2. Floyd(弗洛伊德)算法…

从零搭建一个组件库(二)创建代码规范

文章目录前言集成eslint1.安装2.替换默认解析器3.创建.eslintrc.yml配置文件4.创建忽略文件.eslintignore集成 prettier1.安装2.创建配置文件.prettierrc集成# commitizen1.安装2.修改package.json3.测试className的BEM规范1.安装2.BEM概述3.创建hooks函数4.使用hooks函数5.封装…

Vuex里面四个map方法(mapState、mapGetters、mapActions、mapMutation)

本章节主要讲述Vuex里面的四个优化代码的map方法&#xff0c;mapState、mapGetters、mapActions、mapMutation 一、store文件夹下面index.js主要内容&#xff0c;包含state(用于存储数据)、getters(计算属性)、mutatiions(加工数据)、actions(相应组件动作、写逻辑) 二、四个ma…

多个盒子排列规则(视觉格式化模型) 多个盒子的排列 页面布局

目录常规流常规流布局块盒的排列规则常规流 盒模型&#xff1a;规定单个盒子的规则 视觉格式化模型&#xff08;布局规则&#xff09;&#xff1a;页面中的多个盒子排列规则 视觉格式化模型&#xff0c;大体上将页面中盒子的排列分为三种方式&#xff1a; 常规流浮动定位 …

react源码:目录结构、调试源码

我的技术栈是React,最近在整理react的源码,react版本是18.1.0,之前版本,没有看过,就此略过。 源码目录 从github将源码下载后,先看看源码目录结构,如下图所示: fixtures:代码贡献者提供的测试react package:react源码的主要部分,包含了Schedule、reconcile等等 s…

RadSystems Studio 8.1.8 Crack

RadSystems Studio 是一个用于快速开发和交付自定义应用程序的环境&#xff0c;快速应用开发环境&#xff0c;更快生成完整应用。RadSystems为生成现代应用程序和 API 提供了无数的设计选项和组件。很少或没有编码。无需专门的编程知识。可通过减少冗余编码时间来促进应用程序开…

Centos7 安装SkyWalking

Centos7 安装SkyWalkingCentos7 安装SkyWalking1 基础介绍1.1 概念1.2 核心三部分1.3 架构图2 快速安装2.1 前提条件2.2 拉取镜像2.3 启动SkyWalking2.4 访问SkyWalking UI界面Centos7 安装SkyWalking 1 基础介绍 1.1 概念 SkyWalking是一个国产的开源框架&#xff0c;2015年…

计算机组成原理3个实验-logisim实现“七段数码管”、“有限状态机控制的8*8位乘法器”、“单周期MIPS CPU设计”。

目录 标题1.首先是七段数码管 标题二&#xff1a;有限状态机控制的8*8位乘法器 标题三&#xff1a;单周期MIPS CPU设计 标题1.首先是七段数码管 1看一下实验要求&#xff1a; 2.接下来就是详细设计&#xff1a; 1. 组合逻辑设计 由于7段数码管由7个发光的数码管构成&#x…

信息论复习—率失真理论

目录 失真的概念&#xff1a; 信息率与失真的关系&#xff1a; 信息率失真理论&#xff1a; 失真函数矩阵&#xff1a; 平均失真度定义为&#xff1a; 平均失真度与信道转移概率的关系&#xff1a; 率失真函数&#xff1a; 率失真函数的物理意义&#xff1a; 率失真函数…