2024年9月22日---关于MyBatis框架(1)

一 Mybatis概述

1.1 简介

MyBatis(官网:mybatis – MyBatis 3 | 简介 )是一款优秀的开源的 持久层 框架,用于简化JDBC的开发。是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

MyBatis的特点

  • MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

  • MyBatis封装了几乎所有的JDBC代码和参数的手工设置以及结果集的检索;

  • MyBatis使用简单的XML或注解做配置和定义映射关系,将Java的POJO(Plain Old Java Objects)映射成数据库中的记录。

持久层:指的是就是数据访问层(dao),是用来操作数据库的。

框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。

1.2 MyBatis快速入门

1.2.1 准备数据

在mybatis_db库里维护Student表,添加数据

-- 创建数据库mybatis_db, 设置编码集 UTF8
create database if not exists mybatis_db character set utf8;
-- 切换到mybatis_db数据库
use mybatis_db;

-- 创建学生信息表
create table `student`(
`id` int primary key auto_increment comment '学生ID,学生证ID',
`name` varchar(20) not null comment '学生名称',
`gender` char(1) not null comment '学生性别',
`age` int not null comment '学生年龄',
`address` varchar(50) not null comment '家庭地址'   
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学生信息表';

-- 插入数据
insert into student values 
(1001,'刘备','m',40,'江南'),
(1002,'关羽','m',35,'上海'),
(1003,'虞姬','f',26,'北京'),
(1004,'赵云','m',27,'长春'),
(1005,'甄姬','f',26,'广州');

select * from student;

1.2.2 创建模块,导入坐标

<dependencies>
   <!--mybatis的依赖-->
   <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.5</version>
   </dependency>
   <!--mysql 驱动-->
   <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.31</version>
   </dependency>
   <!--junit 测试-->
   <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
      <scope>test</scope>
   </dependency>
</dependencies> 

1.2.3 编写Mybatis核心配置文件

替换连接信息,解决硬编码问题 文件名:mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--连接信息--><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/edu_mybatis?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;useTimezone=true"/><property name="username" value="root"/><property name="password" value="mmforu"/></dataSource></environment></environments><mappers><!--配置相应的实体接口映射文件 resource属性里是文件的路径--><mapper resource="UserMapper.xml"/></mappers>
</configuration>

1.2.4 编写sql映射文件

统一管理sql语句,解决硬编码问题 文件名:UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--   属性 namespace:名称空间   建议:写相应实体接口的全名  -->
<mapper namespace="test"><select id="findAll" resultType="com.shuilidianli.pojo.User">select * from tb_user;</select>
</mapper>

1.2.5 编写代码

① 根据数据库表,定义pojo类

② 加载核心配置文件,获取SqlSessionFactory对象

③ 获取SqlSession对象,执行sql语句

④ 释放资源

public static void main(String[] args) throws IOException {// 1. 加载mybatis的核心配置文件,获取SqlSessionFactoryString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
​//2. 获取SqlSession对象,用他来执行sqlSqlSession sqlSession = sqlSessionFactory.openSession();
​//3. 执行sql   调用selectList方法,传参 namespace.id,来指定要执行的sql语句List<User> users = sqlSession.selectList("test.findAll");System.out.println(users);
​//4. 释放资源sqlSession.close();
}

二 Mapper代理开发

2.1 目的

解决原生方式中的硬编码,简化后期执行的SQL

原生写法

//3 执行sql  namespace.id
List<User> users = sqlSession.selectList("test.findAll");

代理写法

//3 获取UserMapper接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.findAll();

2.2 步骤

使用Mapper代理方式完成入门案例

1) 定义与SQL映射文件同名的Mapper接口

public interface UserMapper {// ...抽象的增删改查等方法
}

2)将SQL映射文件放置在resources下的与Mapper接口同名的路径里。 注意创建的是Directory,不是package

3)设置SQL映射文件的namespace属性为Mapper接口全限定名

<mapper namespace="com.sldl.mapper.UserMapper">
</mapper>

4)在Mapper接口中定义方法,方法名就是SQL映射文件中SQL语法的id,并保持参数类型和返回值类型一致

package com.sldl.mapper;
​
import com.sldl.pojo.User;
import java.util.List;
​
public interface UserMapper {/*查询所有的用户信息*/List<User> findAll();
}

5)编码

- 通过SqlSession的getMapper方法获取Mapper接口的代理对象
- 调用对应方法完成sql的执行
@Test
public void test2() throws IOException {//1. 获取SqlSessionFactoryInputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
​//2. 获取SqlSession对象SqlSession sqlSession = factory.openSession();
​//3. 调用getMapper方法UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> users = mapper.findAll();for (User user : users) {System.out.println(user);}
​//4. 关闭会话sqlSession.close();
}

细节:如果Mapper接口名称与SQL映射文件名称相同,并且在同一个目录下,则可以使用包扫描的方式简化sql映射文件的加载

<mappers><mapper resource=/><package namne="com.sldl.mapper"/>
</mappers>

三 Mybatis配置文件解析

3.1 核心配置文件解析

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

<!--configuration:  mybatis核心配置文件的根元素-->
<configuration>

    <!--用于给pojo实体类起别名,起别名-->
    <typeAliases>
        <package name="com.sldl.pojo"/>
    </typeAliases>

    <!--environments:  设置连接数据库的环境,可以配置多个环境environment
        属性default:  表示要连接哪一个environment, 值为environment的id-->
    <environments default="development">

        <!-- 环境设置: id作为唯一标识符,-->
        <environment id="development">
            <!--配置事务管理方式:JDBC/MANAGED
                JDBC:使用JDBC的事务管理方式,需要手动的提交或者回滚
                MANAGED:将事务交给别的容器来管理:比如Spring....-->
            <transactionManager type="JDBC"/>
            <!--dataSource: 数据源的设置  JNDI/POOLED/UNPOOLED
                JNDI:使用上下文中的数据源,已过时
                POOLED:使用连接池(推荐)
                UNPOOLED:不使用连接池-->
            <dataSource type="POOLED">
                <!--连接mysql的驱动-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--连接mysql的url路径-->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis_db?useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;useTimezone=true"/>
                <!--连接mysql的用户名-->
                <!--连接mysql的密码-->
                <property name="username" value="root"/>
                <property name="password" value="mmforu"/>
            </dataSource>
        </environment>

        <environment id="wangcm">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--连接mysql的驱动-->
                <property name="driver" value="oracle"/>
                <!--连接mysql的url路径-->
                <property name="url" value="oracle"/>
                <property name="username" value="oracle"/>
                <property name="password" value="oracle"/>
            </dataSource>
        </environment>
    </environments>

    <!--加载sql映射文件-->
    <mappers>
        <!--resource:  用于书写映射文件的具体路径,注意:斜杠'/'作为分隔符-->
        <!--<mapper resource="com/sldl/mapper/UserMapper.xml"/>-->

        <!--如果文件路径较多, 可以使用路径扫描方式-->
        <package name="com.sldl.mapper"/>
    </mappers>

</configuration>

 

3.2 Sql映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Sql映射文件:namespace: 命名空间,可以理解为mapper的唯一标识命名特点: 尽量使用Sql映射文件对应的接口的全限定名。 从src下的第一个包名开始写
​mapper里配置的是各种与数据库交互的增删改查等操作标签
-->
<mapper namespace="com.sldl.mapper.UserMapper"><!--select:  表示查询,*id          对应的是操作方法*resultType:返回的类型,   如果核心配置文件里配置了typeAliases,则可以写短名,大小写不敏感--><select id="findAll" resultType="user">select * from user</select>
</mapper>

四 Mybatis完成CURD

4.1 MyBatisX插件

4.1.1 主要功能

① 智能补全与提示

MyBatisX 可以智能地提示和补全 SQL 语句中的关键字、表名、列名等信息,从而显著提高开发效率

② 代码生成器

- 虽然 MyBatisX 本身可能不直接提供一个完整的、独立的代码生成器,但它可能集成了或支持与其他代码生成工具(如 MyBatis Generator)的配合使用,以简化 Mapper 接口、Mapper XML 文件和 Java 实体类的生成过程。
​
- 通过 MyBatisX 的 GUI 界面,开发者可以根据数据库表结构快速生成所需的代码,减少重复劳动和降低出错率。

③ XML 校验器

MyBatisX 可以根据 XSD Schema 对 Mapper XML 文件进行验证,帮助开发者及时发现和解决 XML 文件中的语法错误。

④ 参数映射

MyBatisX 可以自动将 Java 方法参数与 Mapper XML 文件中的 SQL 语句参数进行映射,减少手动编写参数映射代码的需要

⑤ 快速导航与跳转

MyBatisX 支持在 Mapper 接口和 Mapper XML 文件之间快速导航和跳转,方便开发者在接口和 SQL 实现之间切换

⑥ 一键运行

MyBatisX 提供了一键运行的功能,允许开发者直接在编辑器中运行 SQL 语句,并查看执行结果和日志输出,方便调试和排错

4.1.2 安装与使用

① 安装插件

打开 IntelliJ IDEA,进入 File -> Settings -> Plugins -> Marketplace,搜索 “mybatisx” 并点击安装。注意,使用的 IDEA 版本需要与 MyBatisX 插件版本相兼容。

② 配置数据源

在 IDEA 中配置好数据库数据源,以便 MyBatisX 能够连接到数据库并根据数据库表结构生成代码。

③ 使用代码生成器

连接好数据源后,右键需要生成代码的表名,选择 MyBatisX 提供的代码生成器选项(如 MybatisX-Generator),然后按照提示填写相应信息并生成代码。

4.2 准备工作

4.2.1 数据库的表

-- 创建数据库mybatis_db, 设置编码集 UTF8
create database if not exists mybatis_db character set utf8;
-- 切换到mydb数据库
use mybatis_db;
-- 删除emp表结构
drop table if exists emp;
-- 创建emp表结构
CREATE TABLE `emp` (
  `EMPNO` int primary key auto_increment COMMENT '员工编号',
  `ENAME` varchar(10) DEFAULT NULL COMMENT '员工姓名',
  `JOB` varchar(9) DEFAULT NULL COMMENT '员工职位',
  `MGR` int DEFAULT NULL COMMENT '员工的直属领导编号,注意,领导也是员工,领导的信息也在这个表中',
  `HIREDATE` date DEFAULT NULL COMMENT '入职日期',
  `SAL` int DEFAULT NULL COMMENT '员工工资',
  `COMM` int DEFAULT NULL COMMENT '员工奖金',
  `DEPTNO` int DEFAULT NULL COMMENT '员工所在部门编号'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='员工信息表'


-- 插入数据
insert into emp values
(7369,'SMITH','CLERK',7902,'1980-12-17',800,null,20),
(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30),
(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30),
(7566,'JONES','MANAGER',7839,'1981-04-02',2975,null,20),
(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30),
(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,null,30),
(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,null,10),
(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,null,20),
(7839,'KING','PRESIDENT',null,'1981-11-17',5000,null,10),
(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30),
(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,null,20),
(7900,'JAMES','CLERK',7698,'1981-12-03',950,null,30),
(7902,'FORD','ANALYST',7566,'1981-12-02',3000,null,20),
(7934,'MILLER','CLERK',7782,'1982-01-23',1300,null,10);
-- 查询表记录
select * from emp;

 

4.2.2 根据表映射实体类

4.2.3 根据实体类或者表映射Mapper接口

4.2.4 根据Mapper接口创建SQL映射文件

4.3 CURD的R

4.3.1 CRUD的R1

1)在Mapper接口里添加findAll方法

public interface EmployeeMapper {List<Employee> findAll();
}

2)在SQL映射文件中添加对应的配置

<select id="findAll" resultType="student">select * from emp
</select>

3)执行方法,测试

@Test
public void test3() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();
​StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> students = mapper.findAll();for (Student student : students) {System.out.println(student);}
​sqlSession.close();
}

4.3.2 MyBatis获取参数的方式

如果接口里的方法带有参数,那么Mybatis的Sql语句是如何获取参数的呢?Mybatis提供了两种参数占位符,分别是 #{}${}

1)#{}:

相当于JDBC中的问号(?)占位符,是为SQL语句中的参数值进行占位,大部分情况下都是使用#{}占位符;并且当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号);

在mapper文件中: select * from employee where name=#{name}
在程序执行时替换成:     select * from employee where name=?

2)${}

是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在 ${} 占位符所在的位置,不会进行任何的转义处理。(由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题)

需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!mybatis3.5.x后可以不封装。

4.3.3 CRUD的R2

1)在接口里添加findById方法

Student findById(int id);

2)在Sql映射文件中添加对应的配置

<select id="findById" resultType="com.sldl.pojo.Student" resultMap="a">select * from student where id = #{id}
</select>

3)测试

@Testpublic void test4() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
​SqlSession sqlSession = factory.openSession();
​StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​Student student = mapper.findById(1);System.out.println(student);
​sqlSession.close();}

4.4 CRUD的CUD

4.4.1 MyBatis事务

在核心配置文件中,我们配置了数据源的事务管理方式,要么是JDBC,要么是MANAGED。

  • JDBC: 即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())等。

  • MANAGED: MyBatis自身不会去实现事务管理,而是让程序的容器如(SPRING)来实现对事务的管理。

MyBatis在进行数据库的增删改(CUD)操作时,就涉及到了事务这个概念。

  • openSession(): 默认开启事务,进行增删改操作后需要使用sqlSession.commit(); 手动提交事务。(推荐使用)

  • openSession(true): 向方法中传入true,表示设置自动提交事务。(不推荐)

4.4.2 CRUD的U

1)在Mapper接口里添加修改方法

void updateEmployee(Employee e);

2)在Sql映射文件中添加对应的update配置

    <!--修改员工信息--><update id="updateStudent" parameterType="student">update student setname = #{name},age = #{age},gender = #{gender},id_card = #{idcard},address = #{address}where id = #{id}</update>

3)测试

  @Testpublic void test5() throws IOException {
​InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();
​StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​//新创建一个Student类型Student s =new Student(1,"张三一",22,"女","220102000011112222", "北京");
​mapper.updateStudent(s);
​//提交操作sqlSession.commit();//关闭sqlSession.close();}

4.4.3 CRUD的C

1)在StudentMapper.java里添加如下方法

void addStudent(Student s);

2)在StudentMapper.xml里添加对应的insert配置

<!--添加学生功能-->
<insert id="addStudent" parameterType="student">insert into student values (null, #{name},#{age},#{gender},#{idcard},#{address})
</insert>

3)测试

@Test
public void test6() throws IOException {
​InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();
​StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​//新创建一个Student类型Student s =new Student("老七",22,"女","220102000011113333", "深圳");
​mapper.addStudent(s);
​//提交操作sqlSession.commit();//关闭sqlSession.close();
}

4.4.4 CRUD的D

1)在接口StudentMapper.java里添加如下方法

void delStudent(int id)

2)在映射文件StudentMapper.xml里完善delete标签

<delete id="delStudent">delete from student where id = #{id}
</delete>

3)测试

@Test
public void test7() throws IOException {//获取SqlSession对象InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();
​//获取代理对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​//调用删除方法 删除id为1的记录mapper.delStudent(1);
​//增删改的事务会自动开启,因此需要手动提交sqlSession.commit();sqlSession.close();
}

4.5 多条件CRUD

上面的案例中,接口里方法的形参个数都是1个;如果方法形参是两个或者两个以上时,MyBatis又该如何获取获取参数呢?

Mybatis提供了好几种方式,可以获取多个参数的值

第一种: 使用arg0,arg1…或者param1,param2…来按照参数顺序获取对应的值

//2个或者2个以上的参数
Employee findByCondition1(String username,String password)

接口里的方法与Sql映射文件中的语句进行映射后,并且在调用方法期间,Mybatis会默认将所有传入到方法中的实际参数封装到一个Map对象中,实际参数作为value,按照从左到右的顺序,分别绑定到key名为arg0,arg1…或者param1,param2…上。

因此我们在获取参数时,可以这样写

select...from...where username = #{arg0} and password = #{arg1} .....
或者
select...from...where username = #{param1} and password = #{param2} .....

第二种:Map作为参数

map 集合:只需要保证 SQL 中的参数名和 map 集合的键的名称对应上,即可设置成功

List<Student> findByCondition2(Map<String,Object> map);

第三种:实体类作为参数

实体类封装参数:只需要保证 SQL 中的参数名和实体类属性名对应上,即可设置成功

List<Student> findByCondition1(Student student);

第四种:使用@Param注解命名参数

散装参数:需要使用 @Param (" SQL 中的参数占位符名称")

List<Student> findByCondition1(@Param("id") int id, @Param("name") String name, @Param("address") String address);

2)在StudentMapper.xml里添加对应的select配置

<select id="findByCondition1" resultType="com.shuilidianli.pojo.Student">select * from student where id=#{id} and name=#{name} and address=#{address}
</select>

3)测试

 @Testpublic void test1() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();
​StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//        List<Student> byCondition1 = mapper.findByCondition1(1, "张三一", "北京");Student student = new Student(1,"张三一",-1,null,null,"北京");
//        List<Student> byCondition1 = mapper.findByCondition1(student);Map<String,Object> map = new HashMap<>();//map.put("id",1);map.put("name","张三一");map.put("address","北京");List<Student> byCondition1 = mapper.findByCondition1(map);System.out.println(byCondition1);}

4.6 动态SQL

SQL语句会随着用户的输入和外部条件的变化而变化,我们称之为动态SQL。MyBatis对动态SQL有很强大的支持。

4.6.1 where/if标签

if标签,是根据test属性中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段

存在的问题:第一个条件不需要逻辑运算符。

案例演示:

在接口StudentMapper.java里添加如下方法

List<Student> findByCondition(Map map);

在映射文件StudentMapper.xml里配置如下

第一种方案:使用恒等式让所有条件格式都一样

<select id="findByCondition1" >select *from studentwhere 1 = 1<if test="id != null">and id = #{id}</if><if test="name != null and name != '' ">and name = #{name}</if><if test="address != null and address != '' ">and address = #{address}</if></select>

第二种方案:使用<where>标签替换where关键字。 注意:where标签会将第一个条件之前的连接符自动去掉

<select id="findByCondition1" >select *from student/* where 1 = 1*/<where><if test="id != null">and id = #{id}</if><if test="name != null and name != '' ">and name = #{name}</if><if test="address != null and address != '' ">and address = #{address}</if></where>
</select>

4.6.2 choose/when标签

choose(when,otherwise):类似于java的switch-case-default, 只要满足一个when,choose就结束了,如果都不满足,就会执行otherwise。

1)在接口StudentMapper里添加如下方法

List<Student> findByCondition1(Map map);

2)在sql映射文件StudentMapper.xml里添加如下内容

<select id="findByCondition1" >select *from studentwhere<choose><!-- 类似于switch--><when test=" id != null"><!-- 类似于case-->id = #{id}</when><when test=" name != null and name != '' ">name = #{name}</when><when test=" address != null and address != ''">address = #{address}</when><otherwise><!-- 类似于default-->1 = 1</otherwise></choose>
</select>

3)测试

@Test
public void test9() throws IOException {//获取SqlSession对象InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();
​//获取代理对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​//创建一个map对象Map<String,Object> map = new HashMap<>();//        map.put("id",2);//        map.put("name","小明");//        map.put("address","长春朝阳区");
​/*选择map中的一个条件进行查询,*/List<Student> students = mapper.findByCondition1(map);
​for (Student student : students) {System.out.println(student);}
​sqlSession.close();
}

4.6.3 set/if标签

当进行修改时,有些字段可能有选择的进行修改,这时我们就可以使用<set>标签 配合<if>标签来完成操作。set标签会自动将最后一个条件的逗号去掉。

1)在接口StudentMapper里添加如下方法

//修改学生信息
void modifyStudent(Map map);

2)在StudentMapper.xml里添加如下内容

<update id="modifyStudent">update student<set><if test="name !=null  and name != ''">name = #{name},</if><if test="age != null and age != '' ">age = #{age},</if><if test="gender != null and gender != '' ">gender = #{gender},</if><if test="idcard != null and idcard != '' ">idcard = #{idcard},</if><if test="address != null and address != '' ">address = #{address},</if></set>where id = #{id}
</update>

3)测试

@Test
public void test10() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​Map<String,Object> info = new HashMap<>();//存储id为2的信息info.put("id",2);info.put("name","王小二");info.put("gender","女");info.put("age",23);info.put("address","净月区");
​mapper.modifyStudent(info);
​sqlSession.commit();sqlSession.close();
​
}

4.6.4 foreach标签

<foreach>标签的使用, 比如进行集合查询等操作

1)在接口StudentMapper里添加如下方法

List<Student> findByIds(List list);

2)在StudentMapper.xml里添加如下内容

<select id="findByIds" resultType="com.sldl.pojo.Student">select *from studentwhere id in<foreach collection="list" separator="," open="(" close=")" item="id">#{id}</foreach>
</select>

3)测试

@Test
public void test11() throws IOException {InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);SqlSession sqlSession = factory.openSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
​List<Integer> ids = new ArrayList<>();ids.add(1);ids.add(2);ids.add(3);ids.add(4);ids.add(5);
​List<Student> byIds = mapper.findByIds(ids);for (Student byId : byIds) {System.out.println(byId);}
​sqlSession.close();
​
}

4.7------------------未完待续-----------------

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

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

相关文章

PCL 随机下采样

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xff08;长期更新&#xff09; 一、概述 随机下采样 是一种常用的点…

类和对象(2)(重点)

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目&#xff1a;C知识点的补充_Jason_from_China的博客-CSDN博客 类的默认成员函数 概念概述 默认成员函数就是用户没有显式实现&#xff0c;编译器会自…

项目扩展一:信道池的实现

项目扩展一&#xff1a;信道池的实现 一、为何要设计信道池1.引入信道的好处2.为何要设计信道池 二、信道池的设计1.服务器需要设计信道池吗&#xff1f;2.设计&#xff1a;动态变化的信道池1.为什么&#xff1f;2.怎么办&#xff1f;1.动态扩容和缩容2.LRU风格的信道置换3.小总…

0基础学习HTML(十三)布局

HTML 布局 网页布局对改善网站的外观非常重要。 请慎重设计您的网页布局。 如何使用 <table> 元素添加布局。 网站布局 大多数网站会把内容安排到多个列中&#xff08;就像杂志或报纸那样&#xff09;。 大多数网站可以使用 <div> 或者 <table> 元素来创建…

软件测试分类篇(下)

目录 一、按照测试阶段分类 1. 单元测试 2. 集成测试 3. 系统测试 3.1 冒烟测试 3.2 回归测试 4. 验收测试 二、按照是否手工测试分类 1. 手工测试 2. 自动化测试 3. 手工测试和自动化测试的优缺点 三、按照实施组织分类 1. α测试(Alpha Testing) 2. β测试(Beta…

【LTW】Domain General Face Forgery Detection by Learning to Weight

文章目录 Domain General Face Forgery Detection by Learning to Weightkey points方法LTW元分割策略学习过程损失函数实验评价结果消融实验总结Domain General Face Forgery Detection by Learning to Weight 会议:AAAI-21 作者: code: https://github.com/skJack/LTW 上…

理解JVM中的死锁:原因及解决方案

死锁是并发应用程序中的常见问题。在此类应用程序中&#xff0c;我们使用锁定机制来确保线程安全。此外&#xff0c;我们使用线程池和信号量来管理资源消耗。然而&#xff0c;在某些情况下&#xff0c;这些技术可能会导致死锁。 在本文中&#xff0c;我们将探讨死锁、死锁出现…

旋转机械故障诊断 震动故障分析与诊断

旋转机械故障诊断 机理资料整理 电气故障&#xff0c;机械故障(不平衡&#xff0c;不对中&#xff0c;松动&#xff0c;轴承&#xff0c;共振&#xff0c;流体振动&#xff0c;皮带松动)&#xff0c;低速与高速机器故障诊断等 旋转机械故障诊断&#xff1a;机理资料整理 目录…

河钢数字PMO牛红卫受邀为第四届中国项目经理大会演讲嘉宾

全国项目经理专业人士年度盛会 河钢数字技术股份有限公司项目管理部PMO牛红卫受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾&#xff0c;演讲议题为“从技术到领导力——项目经理成长进阶之道”。大会将于10月26-27日在北京举办&…

数据结构——串的模式匹配算法(BF算法和KMP算法)

算法目的&#xff1a; 确定主串中所含子串&#xff08;模式串&#xff09;第一次出现的位置&#xff08;定位&#xff09; 算法应用&#xff1a; 搜索引擎、拼写检查、语言翻译、数据压缩 算法种类&#xff1a; BF算法&#xff08;Brute-Force&#xff0c;又称古典的…

NASA:ATLAS/ICESat-2 L3 B每周网格大气数据集V005

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Weekly Gridded Atmosphere V005 简介 该产品报告每周全球云覆盖率、海洋上总列光学深度、极地云覆盖率、风吹雪频率、视表面反照率以及地面探测频率。 参数&#xff1a;云光学…

Java 每日一刊(第15期):内部类

文章目录 前言内部类成员内部类&#xff08;Member Inner Class&#xff09;静态内部类&#xff08;Static Nested Class&#xff09;局部内部类&#xff08;Local Inner Class&#xff09;匿名内部类&#xff08;Anonymous Inner Class&#xff09; 内部类的详细对比内部类字节…

新增用户 开发

原型分析 接口设计 数据库设计 代码开发 controller /*** 新增员工** param employeeDTO* return*/ApiOperation("新增员工")PostMappingpublic Result<String> save(RequestBody EmployeeDTO employeeDTO) {log.info("新增员工&#xff1a;{}", emp…

C++离线查询

前言 C算法与数据结构 打开打包代码的方法兼述单元测试 概念及原理 离线算法( offline algorithms)&#xff0c;离线计算就是在计算开始前已知所有输入数据&#xff0c;输入数据不会产生变化&#xff0c;且在解决一个问题后就要立即得出结果的前提下进行的计算。 通俗的说&a…

智能优化算法-遗传算法(GA)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 遗传算法 (Genetic Algorithm, GA) 是一种基于自然选择和遗传学原理的元启发式优化算法&#xff0c;它模仿了生物进化过程中的选择、交叉和变异操作来搜索最优解。 GA的工作机制主要包括&#xff1a; 选择&am…

73 矩阵置零

解题思路&#xff1a; \qquad 原地算法&#xff0c;指除原有输入资料所占空间外&#xff0c;使用额外空间尽可能少(常数空间)的算法。本题容易想到的一种解法是&#xff0c;对于m x n的矩阵&#xff0c;一次遍历把含有0元素的行号、列号记录下来&#xff0c;然后再一次遍历把对…

中序遍历二叉树全过程图解

文章目录 中序遍历图解总结拓展&#xff1a;回归与回溯 中序遍历图解 首先看下中序遍历的代码&#xff0c;其接受一个根结点root作为参数&#xff0c;判断根节点是否为nil&#xff0c;不为nil则先递归遍历左子树。 func traversal(root *TreeNode,res *[]int) {if root nil …

阿⾥编码规范⾥⾯Manager分层介绍-专⽤名词和POJO实体类约定

开发⼈员&#xff1a;张三、李四、王五 ⼀定要避免单点故障 ⼀个微服务起码两个⼈熟悉&#xff1a;⼀个是主程⼀个是技术leader 推荐是团队⾥⾯两个开发⼈员 N⽅库说明 ⼀⽅库: 本⼯程内部⼦项⽬模块依赖的库(jar 包)⼆⽅库: 公司内部发布到中央仓库&#xff0c;可供公司…

计算机毕业设计推荐-基于python的白酒销售数据可视化分析

精彩专栏推荐订阅&#xff1a;在下方主页&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、白酒销售数据…

记一次Meilisearch轻量级搜索引擎使用

以前使用的是mysql的全文索引、最开始还行。后续觉得就不好用了&#xff0c;但是服务器资源有限&#xff0c;没法上ES&#xff0c;只好找一个轻量级的搜索引擎、找了半天&#xff0c;决定使用这一个&#xff0c;目前效果还不错的。 参考网址 官网&#xff1a;https://www.meil…