【精选】框架初探篇之——MyBatis的CRUD及配置文件

news2024/12/23 4:24:19

MyBatis增删改查

在这里插入图片描述

MyBatis新增

在这里插入图片描述

新增用户
  1. 持久层接口添加方法

    void add(User user);
    
    
  2. 映射文件添加标签

    <insert id="add" parameterType="com.mybatis.pojo.User">
       insert into user(username,sex,address) values(# {username},# {sex},# {address})
    </insert>
    
    
  3. 编写测试方法

    @Test
    public void testAdd() throws Exception {
      InputStream is= Resources.getResourceAsStream("SqlMapConfig.xml");
      SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
      SqlSessionFactory factory = builder.build(is);
      SqlSession session = factory.openSession();
      UserMapper userMapper = session.getMapper(UserMapper.class);
      User user = new User("程序员", "男", "上海");
      userMapper.add(user);
      // 提交事务
      session.commit();
      session.close();
      is.close();
    }
    
    

注意:

  1. 当接口方法的参数类型为POJO类型时,SQL语句中绑定参数时使用# {POJO的属性名}即可。
  2. MyBatis事务默认手动提交,所以在执行完增删改方法后,需要手动调用SqlSession对象的事务提交方法,否则数据库将不发生改变。

MyBatis修改

优化测试类

我们发现MyBatis的测试方法在操作数据库前都需要获取代理对象,操作数据库后都需要释放资源,可以利用Junit的前置后置方法,优化测试类代码。

InputStream is = null;
SqlSession session = null;
UserMapper userMapper = null;


@Before
public void before() throws IOException {
  // (1)读取核心配置文件
  is = Resources.getResourceAsStream("SqlMapConfig.xml");
  // (2)创建SqlSessionFactoryBuilder对象
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象
  SqlSessionFactory factory = builder.build(is);
  // (4)SqlSessionFactory对象获取SqlSession对象
  session = factory.openSession();
  // (5)获取代理对象
  userMapper = session.getMapper(UserMapper.class);
}


@After
public void after() throws IOException {
  // 释放资源
  session.close();
  is.close();
}

这样Junit就会自动执行获取代理对象和释放资源的方法。

修改用户
  1. 持久层接口添加方法

    void update(User user);
    
    
  2. 映射文件添加标签

    <update id="update" parameterType="com.mybatis.pojo.User">
       update user
       set username = #{username},
       sex    = #{sex},
       address=#{address}
       where id = #{id}
    </update>
    
    
  3. 编写测试方法

    @Test
    public void testUpdate(){
      User user = new User(8,"程序员1","女","深圳");
      userMapper.update(user);
      session.commit();
    }
    
    

MyBatis删除、根据Id查询

删除用户
  1. 持久层接口添加方法

    void delete(int userId);
    
  2. 映射文件添加标签

    <delete id="delete" parameterType="int">
       delete from user where id = #{id}
    </delete>
    
    

    注:当方法的参数类型是简单数据类型时,#{}中可以写任意名称

    • 简单数据类型:基本数据类型、字符串等
  3. 编写测试方法

    @Test
    public void testDelete(){
      userMapper.delete(8);
      session.commit();
    }
    
    
根据ID查询用户
  1. 持久层接口添加方法

    User findById(int userId);
    
  2. 映射文件添加标签

    <select id="findById" parameterType="int" resultType="com.mybatis.pojo.User">
       select * from user where id = #{userId}
    </select>
    
    
  3. 编写测试方法

    @Test
    public void testFindById(){
      User user = userMapper.findById(1);
      System.out.println(user);
    }
    
    

MyBatis模糊查询

使用#定义参数
  1. 持久层接口添加方法

    List<User> findByNameLike(String username);
    
  2. 映射文件添加标签

    <select id="findByNameLike" parameterType="string" resultType="com.mybatis.user.User">
       select * from user where username like #{name}
    </select>
    
  3. 编写测试方法

    @Test
    public void testFindByNameLike(){
      List<User> users = userMapper.findByNameLike("%王%");
      for (User user:users){
        System.out.println(user);
       }
    }
    
    

我们看到在映射文件中,parameterType的值为string而没有写java.lang.String,这是为什么呢?

  • 参数/返回值类型为基本数据类型/包装类/String等类型时,我们可以写全类名,也可以写别名。
数据类型别名
byte_byte
long_long
short_short
int_int
int_integer
double_double
float_float
boolean_boolean
Stringstring
Bytebyte
Longlong
Shortshort
Integerint/integer
Doubledouble
Floatfloat
Booleanboolean
Datedate
BigDecimaldecimal/bigdecimal
Objectobject
Mapmap
HashMaphashmap
Listlist
ArrayListarraylist
Collectioncollection
Iteratoriterator
使用$定义参数

模糊查询如果不想在调用方法时参数加%,可以使用拼接参数的方式设置Sql:

<select id="findByUsernameLike" parameterType="string" resultType="com.mybatis.pojo.User">
   select * from user where username like '%${value}%'
</select>

测试方法写法如下:

@Test
public void testFindByNameLike(){
  List<User> users = userMapper.findByUsernameLike("张三");
  users.forEach(System.out::println);
}

#和$的区别:

  1. #表示sql模板的占位符,$表示将字符串拼接到sql模板中。
  2. #可以防止sql注入,一般能用#就不用$。
  3. ${}内部的参数名必须写value。
使用< bind>定义参数

如果使用#还不想在调用方法的参数中添加%,可以使用<bind>标签,<bind>标签允许我们在 Sql语句以外创建一个变量,并可以将其绑定到当前的Sql语句中。用法如下:

<select id="findByUsernameLike" parameterType="string" resultType="com.mybatis.pojo.User">
  <bind name="likeName" value="'%'+username+'%'"/>
   select * from user where username like #{likeName}
</select>

测试方法写法如下:

@Test
public void testFindByNameLike(){
  List<User> users = userMapper.findByUsernameLike("张三");
  users.forEach(System.out::println);
}

MyBatis分页查询

分页查询时,Sql语句使用limit关键字,需要传入开始索引和每页条数两个参数。MyBatis的多参数处理有以下方式:

顺序传参

Sql中的参数使用arg0,arg1…或param1,param2…表示参数的顺序。此方法可读性较低,在开发中不建议使用。

  1. 持久层接口方法

    /**
       * 分页查询
       * @param startIndex 开始索引
       * @param pageSize 每页条数
       * @return
       */
    List<User> findPage(int startIndex,int pageSize);
    
  2. 映射文件

    <select id="findPage" resultType="com.mybatis.mapper.User">
       select * from user limit #{arg0},#{arg1}
    </select>
    
    
    <select id="findPage" resultType="com.mybatis.mapper.User">
       select * from user limit #{param1},#{param2}
    </select>
    
  3. 测试类

    @Test
    public void testFindPage(){
      List<User> users = userMapper.findPage(0,3);
      users.forEach(System.out::println);
    }
    
@Param传参

在接口方法的参数列表中通过@Param定义参数名称,在Sql语句中通过注解中所定义的参数名称指定参数位置。此方式参数比较直观的,推荐使用。

  1. 持久层接口方法

    List<User> findPage1(@Param("startIndex") int startIndex, @Param("pageSize")int pageSize);
    
  2. 映射文件

    <select id="findPage1" resultType="com.mybatis.mapper.User">
      select * from user limit #{startIndex},#{pageSize}
    </select>
    
  3. 测试类

    @Test
    public void testFindPage1(){
      List<User> users = userMapper.findPage1(3,3);
      users.forEach(System.out::println);
    }
    
POJO传参

自定义POJO类,该类的属性就是要传递的参数,在SQL语句中绑定参数时使用POJO的属性名作为参数名即可。此方式推荐使用。

  1. 自定义POJO

    public class PageQuery {
      private int startIndex;
      private int pageSize;
        // 省略getter/setter/构造方法
    }
    
    
  2. 持久层接口方法

    List<User> findPage2(PageQuery pageQuery);
    
    
  3. 映射文件

    <select id="findPage2" resultType="com.mybatis.pojo.User" parameterType="com.mybatis.pojo.PageQuery">
       select * from user limit #{startIndex},#{pageSize}
    </select>
    
    
  4. 测试类

    @Test
    public void testFindPage2(){
      PageQuery pageQuery = new PageQuery(3, 3);
      List<User> users = userMapper.findPage2(pageQuery);
      users.forEach(System.out::println);
    }
    
    
Map传参

如果不想自定义POJO,可以使用Map作为传递参数的载体,在SQL语句中绑定参数时使用Map的Key作为参数名即可。此方法推荐使用。

  1. 持久层接口方法

    List<User> findPage3(Map<String,Object> params);
    
    
  2. 映射文件

    <select id="findPage3" resultType="com.mybatis.pojo.User" parameterType="map">
       select * from user limit #{startIndex},#{pageSize}
    </select>
    
    
  3. 测试类

    @Test
    public void testFindPage3(){
      Map<String,Object> params = new HashMap();
      params.put("startIndex",0);
      params.put("pageSize",4);
      List<User> users = userMapper.findPage3(params);
      users.forEach(System.out::println);
    }
    
    

MyBatis聚合查询、主键回填

查询用户总数
  1. 持久层接口方法

    int findCount();
    
  2. 映射文件

    <select id="findCount" resultType="int">
       select count(id) from user
    </select>
    
  3. 测试类

    @Test
    public void testFindCount(){
      System.out.println(userMapper.findCount());
    }
    
主键回填

有时我们需要获取新插入数据的主键值。如果数据库中主键是自增的,这时我们就需要使用MyBatis的主键回填功能。

  1. 持久层接口方法

    void add(User user);
    
  2. 映射文件

    <insert id="add" parameterType="com.mybatis.user.User">
      <!-- keyProperty:主键属性名,keyColumn:主键列名,resultType:主键类型,order:执行时机 -->
      <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
         SELECT LAST_INSERT_ID();
      </selectKey>
       insert into user(username,sex,address) values(#{username},#{sex},#{address})
    </insert>
    

    SELECT LAST_INSERT_ID():查询刚刚插入的记录的主键值,只适用于自增主键,且必须和insert语句一起执行。

  3. 测试类

    @Test
    public void testAdd(){
      User user = new User("×××", "男", "北京");
      userMapper.add(user);
      session.commit();
      System.out.println(user.getId());
    }
    
    

MyBatis配置文件

在这里插入图片描述

< properties>标签

MyBatis配置文件结构:

-configuration
    -properties(属性)
        -property
    -settings(全局配置参数)
        -setting
    -plugins(插件)
        -plugin
    -typeAliases(别名)
        -typeAliase
        -package
    -environments(环境)
        -environment
            -transactionManager(事务管理)
            -dataSource(数据源)
    -mappers(映射器)
        -mapper
        -package
properties

属性值定义。properties标签中可以定义属性值,也可以引入外部配置文件。无论是内部定义还是外部引入,都可以使用 ${name} 获取值。

例如:我们可以将数据源配置写到外部的db.properties中,再使用properties标签引入外部配置文件,这样可以做到动态配置数据源。

  1. 编写db.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis
    jdbc.username=root
    jdbc.password=root
    
    
  2. 在配置文件中引入db.properties

    <properties resource="db.properties"></properties>
    
    <environments default="mysql">
      <environment id="mysql">
        <transactionManager type="JDBC"></transactionManager>
        <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>
    
    

当然我们也可以将数据源数据通过<properties>配置到MyBatis配置文件内,但这样做没什么意义。

<properties>
  <property name="jdbc.driver" value="com.mysql.jdbc.Driver"></property>
  <property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis"></property>
  <property name="jdbc.username" value="root"></property>
  <property name="jdbc.password" value="root"></property>
</properties>


<environments default="mysql">
  <environment id="mysql">
    <transactionManager type="JDBC"></transactionManager>
    <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>

< settings>标签

<settings>是配置MyBatis运行时的一些行为的,例如缓存、延迟加载、命名规则等一系列控制性参数。后期我们会使用该标签配置缓存和延迟加载等。

< plugins>标签

<plugins>是配置MyBatis插件的。插件可以增强MyBatis功能,比如进行sql增强,打印日志,异常处理等。后期我们会使用该标签配置分页插件。

< typeAliases>标签

MyBatis对常用类有默认别名支持,比如java.lang.Stirng的别名为string。除此之外,我们也可以使用<typeAliases>设置自定义别名。

为一个类配置别名
<typeAliases>
    <typeAlias type="全类名" alias="别名"></typeAlias>
</typeAliases>

此时我们即可在映射文件中使用自定义别名,如:

  1. 配置文件:

    <typeAliases>
        <typeAlias type="com.mybatis.pojo.User" alias="User">     </typeAlias>
    </typeAliases>
    
  2. 映射文件:

    <select id="findAll" resultType="User">
       select * from user
    </select>
    
为一个所有包下的所有类配置别名
<typeAliases>
  <package name="包名"></package>
</typeAliases>

此时该包下的所有类都有了别名,别名省略包名,和类名相同。如:

  1. 配置文件:

    <typeAliases>
      <package name="com.mybatis.pojo"></package>
    </typeAliases>
    
  2. 映射文件:

    <select id="findPage2" resultType="User" parameterType="PageQuery">
       select * from user limit #{startIndex},#{pageSize}
    </select>
    

< environments>标签

<environments>可以为MyBatis配置数据环境。

事务管理
<environments default="mysql">
  <environment id="mysql">
    <!-- JDBC:使用JDBC的提交和回滚 MANAGED:不做事务处理-->
    <transactionManager type="JDBC"></transactionManager>
  </environment>
</environments>
连接池
<environments default="mysql">
  <environment id="mysql">
    <transactionManager type="JDBC"></transactionManager>
    <!-- 连接池设置 -->
    <dataSource type="POOLED">
      <!-- 数据源设置... -->
    </dataSource>
  </environment>
</environments>

dataSource的type属性:

  • POOLED:使用连接池管理连接,使用MyBatis自带的连接池。
  • UNPOOLED:不使用连接池,直接由JDBC连接。
  • JNDI:由JAVAEE服务器管理连接,如果使用Tomcat作为服务器则使用Tomcat自带的连接池管理。

< mappers>标签

<mappers>用于注册映射文件或持久层接口,只有注册的映射文件才能使用,共有四种方式都可以完成注册:

  1. 使用相对路径注册映射文件

    <mappers>
     <mapper resource="com/mybatis/mapper/UserMapper.xml"/>
    </mappers>
    
  2. 使用绝对路径注册映射文件

    <mappers>  
      <mapper url="file:///C:\Users\a\IdeaProjects\mybatiscase\mybatisDemo1\src\main\resources\com\mybatis\mapper\UserMapper.xml"/> 
    </mappers>
    
  3. 注册持久层接口

    <mappers>  
      <mapper class="com.mybatis.mapper.UserMapper"/> 
    </mappers>
    
  4. 注册一个包下的所有持久层接口

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

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

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

相关文章

NX二次开发UF_CURVE_ask_joined_parms 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_joined_parms Defined in: uf_curve.h int UF_CURVE_ask_joined_parms(tag_t joined_curve_feature, UF_STRING_p_t uf_curve_string, int * creation_method, double …

Git仓库瘦身大作战:133M 到 4M 的实战

开局两张图 瘦身前瘦身后 目录 开局两张图前言下载 BFG克隆代码Git 仓库瘦身清理存储库储存库 GC推送仓库 Git 瘦身验证结语开源项目 前言 在进行项目开发的过程中&#xff0c;代码仓库的体积可能会逐渐增大&#xff0c;特别是在版本控制系统中保留了大量的历史提交记录和不必…

apple macbook M系列芯片安装 openJDK17

文章目录 1. 查找openjdk版本2. 安装openjdk3. 多jdk之间的切换 在这里我们使用 brew 命令查找并安装。 1. 查找openjdk版本 执行&#xff1a;brew search openjdk&#xff0c;注意&#xff1a;执行命令后&#xff0c;如果得到的结果中没有红框内容&#xff0c;则需要更新一下…

使用STM32+SPI Flash模拟U盘

试验目的&#xff1a;使用STM32F103C8T6 SPI Flash&#xff08;WSQ16&#xff09;实现模拟U盘的功能 SPI Flash读写说明&#xff1a; Step1 设置SPI1 用于读取SPI Flash&#xff1b; Step2&#xff1a;设置SPI Flash 的使能信号 Step3&#xff1a;使能USB通信 Step4&#xf…

一起学docker系列之九docker运行mysql 碰到的各种坑及解决方法

目录 前言1 Docker 运行mysql命令2 坑一&#xff1a;无法读取/etc/mysql/conf.d目录的问题3 坑二&#xff1a;/tmp/ibnr0mis 文件无法创建/写入的问题4 坑三&#xff1a;Navicat 连接错误&#xff08;1045-access denied&#xff09;5 坑四&#xff1a;MySQL 登录失败问题结语 …

25 Linux I2C 驱动

一、I2C简介 I2C老朋友了&#xff0c;在单片机里面也学过&#xff0c;现在再复习一下。I2C使用两条线在主控制器和从机之间进行数据通信。一条是 SCL(串行时钟线)&#xff0c;另外一条是 SDA(串行数据线)&#xff0c;这两条数据线需要接上拉电阻&#xff0c;总线空闲的时候 SCL…

NX二次开发UF_CURVE_ask_curve_struct_data 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_curve_struct_data Defined in: uf_curve.h int UF_CURVE_ask_curve_struct_data(UF_CURVE_struct_p_t curve_struct, int * type, double * * curve_data ) overview…

leetcode:随机链表的复制

题目描述 题目链接&#xff1a;138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 题目分析 这个题目很长&#xff0c;但是意思其实很简单&#xff1a;就是一个单链表&#xff0c;每个结点多了一个指针random随机指向链表中的任意结点或者NULL&#xff0c;我们血需…

CMSIS-DSP实数FFT相关API(单精度浮点float)

目录 1. CMSIS-DSP的实数FFT 2. 频域上求模值 3. 如何求解相位 4. 对比python的求解过程 5. 在频域上以模和相角的方式还原信号 6. 求能量值 平台&#xff1a;STM32F407-DiscoveryCMSIS-DSP-V1.6.0 1. CMSIS-DSP的实数FFT 文件&#xff1a;\CMSIS\DSP\Source\Transform…

模板初阶(1):函数模板,类模板

一、函数模板 1.1 概念 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函数的特定类型版本。 格式&#xff1a; template <typename T>或template <class T> template <class T>…

蓝桥杯第597题 跑步锻炼 C++ 日期模板题(模拟经典)

题目 跑步锻炼https://www.lanqiao.cn/problems/597/learning/?page1&first_category_id1&name%E8%B7%91%E6%AD%A5%E9%94%BB%E7%82%BC 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝每天都锻炼身…

CTFUB-web前置技能-HTTP协议

burp抓包,抓第二次的 修改请求方式为CTFHUB

操作系统的基本特性--并发、共享、虚拟、异步

批处理系统具有高资源利用率和系统吞吐量&#xff1b;分时系统能够获得及时响应&#xff1b;实时系统具有实时特征。而这三种系统都具有并发、共享、虚拟和异步四个基本特征 一、并发 OS通过并发提高系统中的资源利用率&#xff0c;增加系统的吞吐量 1.并行和并发 并行&…

利用Nginx与php处理方式不同绕过Nginx_host实现SQL注入

目录 首先需要搭建环境 nginxphpmysql环境&#xff1a; 搭建网站 FILTER_VALIDATE_EMAIL 绕过 方法1&#xff1a;冒号号分割host字段 方法2&#xff1a;冒号号分割host字段 方法3&#xff1a;SNI扩展绕过 首先需要搭建环境 nginxphpmysql环境&#xff1a; php安装包&a…

从0开始学习JavaScript--深入了解JavaScript框架

JavaScript框架在现代Web开发中扮演着关键角色&#xff0c;为开发者提供了丰富的工具和抽象层&#xff0c;使得构建复杂的、高性能的Web应用变得更加容易。本文将深入探讨JavaScript框架的核心概念、常见框架的特点以及它们在实际应用中的使用。 JavaScript框架的作用 JavaSc…

算法-中等-链表-两数相加

记录一下算法题的学习11 两数相加 题目&#xff1a;给你两个非空的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照逆序的方式存储的&#xff0c;并且每个节点只能存储一位数字。请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。你可以假设除了数字…

Re54:读论文 How Context Affects Language Models‘ Factual Predictions

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;How Context Affects Language Models’ Factual Predictions ArXiv网址&#xff1a;https://arxiv.org/abs/2005.04611 2020年AKBC论文&#xff0c;作者来自脸书和UCL。 本文主要关注…

【Amazon】安装卸载AWS CLI操作流程(Windows 、Linux系统)

AWS 命令行界面&#xff08;AWS CLI&#xff09;是用于管理 AWS 产品的统一工具。只需要下载和配置一个工具&#xff0c;您就可以使用命令行控制多个 AWS 产品并利用脚本来自动执行这些服务。 AWS CLI v2 提供了多项新功能&#xff0c;包括改进的安装程序、新的配置选项&#…

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(一) ​

随着大语言模型效果明显提升&#xff0c;其相关的应用不断涌现呈现出越来越火爆的趋势。其中一种比较被广泛关注的技术路线是大语言模型&#xff08;LLM&#xff09;知识召回&#xff08;Knowledge Retrieval&#xff09;的方式&#xff0c;在私域知识问答方面可以很好的弥补通…

[HCIE] IPSec-VPN (手工模式)

概念&#xff1a; A. IPSec&#xff1a;是对IP的安全性补充&#xff0c;工作在IP层&#xff0c;为IP网络通信提供安全服务。 B.安全联盟SA&#xff1a;是通信对等体之间对某些要素的协定。 C. IPSec安全联盟简称 IPSec SA.通常成对建立&#xff08;inbound和outbound&#x…