MyBatis查询数据库

目录

1.MyBatis是什么?

2.为什么要学习 MyBatis?

3.怎么学MyBatis?

4.第⼀个MyBatis查询

4.1创建数据库表

4.2 添加MyBatis框架⽀持

4.3配置连接字符串和MyBatis

4.3.1配置连接字符串

4.3.2 配置 MyBatis 中的 XML 路径

4.4添加业务代码

4.4.1 添加实体类

4.4.2添加Mapper接口

4.4.3 添加 UserMapper.xml

4.4.4 添加 Service

4.4.5 添加 Controller

4.4.6 使⽤ postman 测试

4.4.7带有参数的查询

5.增、删、改操作

5.1增加操作

5.2 修改⽤户操作

5.3 删除⽤户操作

6.查询操作

6.1 单表查询

​编辑

​编辑

​编辑

6.1.1 参数占位符 #{} 和 ${}

6.1.2SQL注入问题

6.1.3${} 优点

6.1.4 like 查询

6.2多表查询

6.2.1 返回类型:resultType

6.2.2返回字典映射:resultMap

6.2.3 多表查询

6.2.3.1 ⼀对⼀的表映射

 7.复杂情况:动态SQL使⽤

7.1 标签

7.2 标签

7.3 标签

7.4 标签

 7.5 标签

​8.补充

1.MyBatis是什么?

MyBatis 是⼀款优秀的持久层框架,它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了⼏乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJO(Plain Old Java Objects,普通⽼式 Java 对象)为数据库中的记录。
简单来说 MyBatis 是更简单完成程序和数据库交互的⼯具,也就是更简单的操作和读取数据库⼯具。

2.为什么要学习 MyBatis?

对于后端开发来说,程序是由以下两个重要的部分组成的:
1. 后端程序
2. 数据库
⽽这两个重要的组成部分要通讯,就要依靠数据库连接⼯具,那数据库连接⼯具有哪些?⽐如之前我们学习的 JDBC,还有今天我们将要介绍的 MyBatis,那已经有了 JDBC 了,为什么还要学习 MyBatis?这是因为 JDBC 的操作太繁琐了,我们回顾⼀下 JDBC 的操作流程:
1. 创建数据库连接池 DataSource
2. 通过 DataSource 获取数据库连接 Connection
3. 编写要执⾏带 ? 占位符的 SQL 语句
4. 通过 Connection 及 SQL 创建操作命令对象 Statement
5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
6. 使⽤ Statement 执⾏ SQL 语句
7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
8. 处理结果集
9. 释放资源

3.怎么学MyBatis?

MyBatis 学习只分为两部分:
配置 MyBatis 开发环境;
使⽤ MyBatis 模式和语法操作数据库;

4.第⼀个MyBatis查询

开始搭建 MyBatis 之前,我们先来看⼀下 MyBatis 在整个框架中的定位,框架交互流程图:
MyBatis 也是⼀个 ORM 框架, ORM(Object Relational Mapping),即对象关系映射。在⾯向
对象编程语⾔中,将关系型数据库中的数据与对象建⽴起映射关系,进⽽⾃动的完成数据与对象
的互相转换:
1. 将输⼊数据(即传⼊对象)+SQL 映射成原⽣ SQL
2. 将结果集映射为返回对象,即输出对象
ORM 把数据库映射为对象:
数据库表(table)--> 类(class)
记录(record,⾏数据)--> 对象(object)
字段(field) --> 对象的属性(attribute)
⼀般的 ORM 框架,会将数据库模型的每张表都映射为⼀个 Java 类。也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表,可以实现对象和数据库表之间的转换,接下来我们来看 MyBatis 的使⽤吧。

4.1创建数据库表

接下来我们要实现的功能是:使⽤ MyBatis 的⽅式来读取⽤户表中的所有⽤户,我们使⽤个⼈博
客的数据库和数据包,具体 SQL 如下。
-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
use mycnblog;
-- 创建表[⽤户表]
drop table if exists userinfo;
create table userinfo(
 id int primary key auto_increment,
 username varchar(100) not null,
 password varchar(32) not null,
 photo varchar(500) default '',
 createtime datetime default now(),
 updatetime datetime default now(),
 `state` int default 1
) default charset 'utf8mb4';
-- 创建⽂章表
drop table if exists articleinfo;
create table articleinfo(
 id int primary key auto_increment,
 title varchar(100) not null,
 content text not null,
 createtime datetime default now(),
 updatetime datetime default now(),
 uid int not null,
 rcount int not null default 1,
 `state` int default 1
)default charset 'utf8mb4';
-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(
 vid int primary key,
 `title` varchar(250),
 `url` varchar(1000),
createtime datetime default now(),
updatetime datetime default now(),
 uid int
)default charset 'utf8mb4';
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`,
`createtime`, `updatetime`, `state`) VALUES
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1)
;
insert into articleinfo(title,content,uid)
 values('Java','Java正⽂',1);
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://ww
w.baidu.com',1);
select * from userinfo;
select * from userinfo where username='admin' and password= '' or 1='1';
select * from userinfo ORDER BY id DESC;
select * from userinfo where username like CONCAT('%','m','%');

4.2 添加MyBatis框架⽀持

在创建新项目时,在添加Spring框架的基础上,加入MyBatis FrameWork和MySQL Driver框架支持。

4.3配置连接字符串和MyBatis

此步骤需要进⾏两项设置,数据库连接字符串设置和 MyBatis 的 XML ⽂件配置。

4.3.1配置连接字符串

application.yml文件中添加以下内容:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL=false
    username: root
    password: 111111
    driver-class-name: com.mysql.cj.jdbc.Driver

4.3.2 配置 MyBatis 中的 XML 路径

MyBatis 的 XML 中保存是查询数据库的具体操作 SQL,配置如下:

#数据库配置
mybatis:
  mapper-locations: classpath:mapper/**Mapper.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

4.4添加业务代码

下⾯按照后端开发的⼯程思路,也就是下⾯的流程来实现 MyBatis 查询所有⽤户的功能:

4.4.1 添加实体类

先添加用户的实体类,使用Data注解可以自己生成一些方法:

@Data
public class User {

    private Integer id;
    private String name;
    private String pwd;
    private String photo;
    private Date createtime;
    private Date updatetime;
    private Integer state;
}

4.4.2添加Mapper接口

@Mapper
public interface UserMapper {
    /**
     * 查询所有数据
     * @return
     */
    List<User> queryAll();
}

4.4.3 添加 UserMapper.xml

数据持久成的实现,mybatis 的固定 xml 格式:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
s.org/dtd/mybatis-3-mapper.dtd">
<!--实现的哪个接口-->
<mapper namespace="com.example.springmybatisdemo.mapper.UserMapper">


</mapper>
UserMapper.xml 查询所有⽤户的具体实现 SQL:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
s.org/dtd/mybatis-3-mapper.dtd">
<!--实现的哪个接口-->
<mapper namespace="com.example.springmybatisdemo.mapper.UserMapper">
<!--    实现的是接口里的哪个方法-->
    <select id="queryAll" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo
    </select>


</mapper>
以下是对以上标签的说明:
●<mapper>标签:需要指定 namespace 属性,表示命名空间,值为 mapper 接⼝的全限定
名,包括全包名.类名。
<select>查询标签:是⽤来执⾏数据库的查询操作的:
    ○id:是和 Interface(接⼝)中定义的⽅法名称⼀样的,表示对接⼝的具体实现⽅法。
    ○resultType:是返回的数据类型,也就是开头我们定义的实体类。

4.4.4 添加 Service

服务层实现代码如下:
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public List<User> selectAllUser() {
        return userMapper.queryAll();
    }
}

4.4.5 添加 Controller

控制器层的实现代码如下:
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/selectAll")
    public List<User> selectAllUser(){
        return userService.selectAllUser();
    }
}
以上代码写完,整个 MyBatis 的查询功能就实现完了,接下来使⽤ postman 来测试⼀下。

4.4.6 使⽤ postman 测试

4.4.7带有参数的查询

     /**
     * 根据id查询
     * 当只有一个参数时,可以不用加注解,参数名可以随便写,可以不一样
     */
    User queryById(@Param("uid") Integer id);

当只有一个参数时,接口内的参数名可以随便写,不用加注解,有多个参数时,需要添加@Param注解,注解内的value值与xml中的要一致。

    <select id="queryById" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where id = ${uid}
    </select>

把xml文件中的id改成uid,可以执行成功。

5.增、删、改操作

接下来,我们来实现⼀下⽤户的增加、删除和修改的操作,对应使⽤ MyBatis 的标签如下:
●<insert>标签:插⼊语句
●<update>标签:修改语句
●<delete>标签:删除语句
具体实现如下。

5.1增加操作

mapper接口:

Integer insert(User user);

xml实现:

<insert id="insert">
<!--        mybatis会自动帮我们生成以属性名命名的变量-->
        insert into userinfo (username,password,photo) values(#{username},#{password},#{photo})
    </insert>

使用Test方法实现结果:

如果设置了Param注解,就必须要使用Param注解的命名

Integer insert2(@Param("userinfo") User user);
<insert id="insert2" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username,password,photo) values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})
    </insert>

想要拿到自增id,可以在xml文件的insert标签里面添加以下内容:

<insert id="insert2" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username,password,photo) values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})
    </insert>
●useGeneratedKeys:这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据
库内部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动
递增字段),默认值:false。
●keyColumn:设置⽣成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列
不是表中的第⼀列的时候,是必须设置的。如果⽣成列不⽌⼀个,可以⽤逗号分隔多个属性
名称。
●keyProperty:指定能够唯⼀识别对象的属性,MyBatis 会使⽤ getGeneratedKeys 的返回
值或 insert 语句的 selectKey ⼦元素设置它的值,默认值:未设置(unset)。如果⽣成列
不⽌⼀个,可以⽤逗号分隔多个属性名称。

5.2 修改⽤户操作

mapper接口:

void update(User user);
mapper.xml 实现代码:
    <update id="update">
        update userinfo set username=#{username},password=#{password} where id=#{id}
    </update>

5.3 删除⽤户操作

mapper接口:

     /**
     * 删除数据
     */
    void delete(Integer id);

mapper.xml 实现代码:

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

6.查询操作

6.1 单表查询

上面我们已经实现了简单的单表查询操作,但我们的SQL语句属性都使用的是#,如果换成$会有什么结果呢?

根据id查询:

User queryById(@Param("uid") Integer id);
    <select id="queryById" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where id = #{uid}
    </select>

使用#查询结果:

 使用$查询结果:

    <select id="queryById" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where id = ${uid}
    </select>

根据name查询: 

User queryByName(String username);

使用#:

    <select id="queryByName" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username= #{username}
    </select>

使用$:

    <select id="queryByName" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username= ${username}
    </select>

为什么使用$就会出现异常呢?

6.1.1 参数占位符 #{} 和 ${}

●#{}:预编译处理。
●${}:字符直接替换。
预编译处理是指:MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号,使⽤ PreparedStatement
的 set ⽅法来赋值。直接替换:是MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。
预编译处理和字符串替换的区别故事(头等舱和经济舱乘机分离的故事):
在坐⻜机的时候头等舱和经济舱的区别是很⼤的,如下图所示:
⼀般航空公司乘机都是头等舱和经济舱分离的,头等舱的⼈先登机,登机完之后,封闭经济舱,然后再让经济舱的乘客登机,这样的好处是可以避免浑⽔摸⻥,经济舱的⼈混到头等舱的情况,这就相当于预处理,可以解决程序中不安全(越权处理)的问题。
⽽直接替换的情况相当于,头等舱和经济舱不分离的情况,这样经济舱的乘客在通过安检之后可能越权摸到头等舱,如下图所示:
这就相当于参数直接替换,它的问题是可能会带来越权查询和操作数据等问题,⽐如后⾯会讲的 SQL注⼊问题。

6.1.2SQL注入问题

User queryByNameAndPassword(@Param("username") String username,@Param("password") String password);
    <select id="queryByNameAndPassword" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username="${username}" and password = "${password}"
    </select>
 @Test
    void queryByNameAndPassword() {
        String username="admin";
//        String password="admin";
        String password="' or 1='1";

        User user=userMapper.queryByNameAndPassword(username,password);
        log.info(user==null?null:user.toString());
    }

可以从上述的结果中发现,我们给密码赋值为“' or 1='1” ,即使不需要密码,也可以查出全部信息,这就会造成很严重的安全问题。

6.1.3${} 优点

当我们使用#{}进行排序操作时:

    <select id="queryByOrder" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo order by id #{order}
    </select>
 
                 

 通过结果可以发现,当我们使用#操作时,会将传入排序的方法认为是想要查询的值,程序查不出来就会报错。

使用${}:

    <select id="queryByOrder" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo order by id ${order}
    </select>


 当我们使用${},程序就可以正常的查询出来。

所以排序时,只能使用${},为了防止SQL注入的问题,我们再前端让用户只能点击来排序,参数由后端来拼接,后端在查询之前,对参数进行校验,只能传入两个值:desc,asc。

6.1.4 like 查询

使用#{}:

    <select id="queryByLike" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username like '%#{name}%'
    </select>


当使用#{}时,程序会报错;

使用${}:

    <select id="queryByLike" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username like '%${name}%'
    </select>

使用${}不会报错,但${}存在SQL注入问题,该怎么解决呢?

使用mysql的内置函数concat:

    <select id="queryByLike" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username like concat('%',#{name},'%')
    </select>

6.2多表查询

如果是增、删、改返回搜影响的⾏数,那么在 mapper.xml 中是可以不设置返回的类型的,如下图所示:

然⽽即使是最简单查询⽤户的名称也要设置返回的类型,否则会出现如下错误:

显示运⾏了⼀个查询但没有找到结果映射,也就是说对于 <select> 查询标签来说⾄少需要两个属性:
id 属性:⽤于标识实现接⼝中的那个⽅法;
结果映射属性:结果映射有两种实现标签:<resultMap>和<resultType>

6.2.1 返回类型:resultType

绝⼤数查询场景可以使⽤ resultType 进⾏返回,如下代码所示:
    <select id="queryByLike" resultType="com.example.springmybatisdemo.model.User">
        select * from userinfo where username like concat('%',#{name},'%')
    </select>
它的优点是使⽤⽅便,直接定义到某个实体类即可。
数据库字段命名规则和Java的命名规则不一致
数据库命名:字母小写,以下划线分隔
Java属性命名:小驼峰,第一个英文单词首字母小写,其他英文单词首字母大写。

6.2.2返回字典映射:resultMap

resultMap 使⽤场景:
●字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射;
●⼀对⼀和⼀对多关系可以使⽤ resultMap 映射并查询数据。
     <resultMap id="BaseMap" type="com.example.springmybatisdemo.model.User">
        <id property="id" column="id"></id>
        <result property="name" column="username"></result>
        <result property="pwd" column="password"></result>
        <result property="createtime" column="cteatetime"></result>
        <result property="updatetime" column="updatetime"></result>
    </resultMap>
    <select id="queryByMap" resultMap="BaseMap">
        select * from userinfo
    </select>

一个xml文件中可以存在多个resultMap,只要id不同就可以。

resultMap 的使⽤如下:

如果程序中的属性和SQL字段名不一致,就会查不出来,但使用resultMap就可以解决这个问题。

6.2.3 多表查询

在多表查询时,如果使⽤ resultType 标签,在⼀个类中包含了另⼀个对象是查询不出来被包含的对象的,⽐如以下实体类:
@Data
public class ArticleInfo {
    private Integer id;
    private String title;
    private String content;
    private Date createtime;
    private Date updatetime;
    private Integer uid;
    private Integer rcount;
    private Integer state;
//    //作者相关信息
    private User user;
    private String username;
}
程序的执⾏结果如下图所示:

此时我们就需要使⽤特殊的⼿段来实现联表查询了。

6.2.3.1 ⼀对⼀的表映射

⼀对⼀映射要使⽤ <association> 标签,具体实现如下(⼀篇⽂章只对应⼀个作者): 

    <resultMap id="BaseMap" type="com.example.springmybatisdemo.model.ArticleInfo">
        <id property="id" column="id"></id>
        <result property="title" column="title"></result>
        <result property="content" column="content"></result>
        <result property="createtime" column="createtime"></result>
        <result property="updatetime" column="updatetime"></result>
        <association property="user" resultMap="com.example.springmybatisdemo.mapper.UserMapper.BaseMap">

        </association>
    </resultMap>

引入其他xml的resultMap,路径是:xml的namespace+resultMap的id

常见使用写法:

   <select id="queryArticle2" resultMap="BaseMap2">
        select ta.*,
        tb.id as userid,
        tb.username as username
                ta.id as id,
                ta.title as title,
                ta.content as content,
                ta.createtime as createtime ,
                ta.updatetime as updatetime
        from articleinfo ta left join userinfo tb on ta.uid=tb.id
    </select>
    <resultMap id="BaseMap2" type="com.example.springmybatisdemo.model.ArticleInfo">
        <id property="id" column="id"></id>
        <result property="title" column="title"></result>
        <result property="content" column="content"></result>
        <result property="createtime" column="createtime"></result>
        <result property="updatetime" column="updatetime"></result>
        <result property="uid" column="userid"></result>
        <result property="username" column="username"></result>

    </resultMap>

 7.复杂情况:动态SQL使⽤

动态 sql 是Mybatis的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接。

7.1 <if>标签

在注册⽤户的时候,可能会有这样⼀个问题,如下图所示:
注册分为两种字段:必填字段和⾮必填字段,那如果在添加⽤户的时候有不确定的字段传⼊,程序应该如何实现呢?
这个时候就需要使⽤动态标签 <if> 来判断了。
    <insert id="insertByCondition">
        insert into articleinfo(
        <if test="title!=null">
            title
        </if>
        <if test="content!=null">
            ,content
        </if>
        <if test="uid!=null">
            ,uid
        </if>
        <if test="state!=null">
            ,state
        </if>
        )
        values
        (
        <if test="title!=null">
            #{title}
        </if>
        <if test="content!=null">
            ,#{content}
        </if>
        <if test="uid!=null">
            ,#{uid}
        </if>
        <if test="state!=null">
            ,#{state}
        </if>
        )
    </insert>

但当我们给第一个属性不赋值时,会出现错误:

这时候就可以使用trim标签:

7.2 <trim>标签

如果所有字段都是⾮必填项,就考虑使⽤
<trim>标签结合<if>标签,对多个字段都采取动态⽣成的⽅式。
<trim>标签中有如下属性:
prefix:表示整个语句块,以prefix的值作为前缀
suffix:表示整个语句块,以suffix的值作为后缀
prefixOverrides:表示整个语句块要去除掉的前缀
suffixOverrides:表示整个语句块要去除掉的后缀
调整 UserMapper.xml 的插⼊语句为:
    <insert id="insertByCondition">
        insert into articleinfo
        <trim prefix="(" suffix=")" suffixOverrides="," prefixOverrides=",">
            <if test="title!=null">
                title
            </if>
            <if test="content!=null">
                ,content
            </if>
            <if test="uid!=null">
                ,uid
            </if>
            <if test="state!=null">
                ,state
            </if>

        </trim>
        values
        <trim prefix="(" suffix=")" prefixOverrides="," suffixOverrides=",">

            <if test="title!=null">
                #{title}
            </if>
            <if test="content!=null">
                ,#{content}
            </if>
            <if test="uid!=null">
                ,#{uid}
            </if>
            <if test="state!=null">
                ,#{state}
            </if>

        </trim>
    </insert>

 

在以上 sql 动态解析时,会将第⼀个 <trim> 部分做如下处理:
基于 prefix 配置,开始部分加上 (
基于 suffix 配置,结束部分加上 )
多个 <if>组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixOverrides 配置去掉最后⼀个 ,
注意 <if test=“createTime != null”> 中的 createTime 是传⼊对象的属性

7.3 <where>标签

传⼊的⽤户对象,根据属性做 where 条件查询,⽤户对象中属性不为 null 的,都为查询条件。
Mapper 接⼝中新增条件查询⽅法:
List<ArticleInfo>queryByCondition(@Param("uid") Integer uid,@Param("state") Integer state);

 

    <select id="queryByCondition" resultType="com.example.springmybatisdemo.model.ArticleInfo">
        select *
        from articleinfo
        
            <if test="uid!=null">
              and  uid=#{uid}
            </if>

            <if test="state!=null">
               and state=#{state}
            </if>
       

    </select>

我们传入两个参数:

但当我们只传入一个参数时:

 

报错了,where后面直接跟的and,第一个参数不传,结果where和and中间的数据没有了,造成sql语句报错,该怎么解决呢?

1.在where后面加1=1

    <select id="queryByCondition" resultType="com.example.springmybatisdemo.model.ArticleInfo">
        select *
        from articleinfo where 1=1

            <if test="uid!=null">
              and  uid=#{uid}
            </if>


            <if test="state!=null">
               and state=#{state}
            </if>


    </select>

 2.使用where标签:

 

    <select id="queryByCondition" resultType="com.example.springmybatisdemo.model.ArticleInfo">
        select *
        from articleinfo 
        <where>
            <if test="uid!=null">
              and  uid=#{uid}
            </if>


            <if test="state!=null">
               and state=#{state}
            </if>
        </where>

    </select>

不传入第一条数据:

一条数据都不传入:

7.4 <set>标签

根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤<set>标签来指定动态内容。

 

当我们更新多个字段时,也会出现与上面一样的问题,我们就可以通过set标签来解决:

    <update id="updateByCondition">
        update articleinfo
        <set>
            <if test="uid!=null">
                state=#{state},
            </if>

            <if test="state!=null">
                uid=#{state};
            </if>
        </set>


    </update>

 7.5 <foreach>标签

对集合进⾏遍历时可以使⽤该标签。<foreach>标签有如下属性:
collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
item:遍历时的每⼀个对象
open:语句块开头的字符串
close:语句块结束的字符串
separator:每次遍历之间间隔的字符串
批量删除:
void batchDelete(@Param("ids") List<Integer>ids);
    <delete id="batchDelete">
        delete from articleinfo where id in
        <foreach collection="ids" open="(" close=")" separator="," item="deleteId">
            #{deleteId}
        </foreach>
    </delete>

8.补充

MyBatis的实现有两种方式:

1.xml方式,也就是我们上面所用到的方式

2.注解方式

@Mapper
public interface UserMapper2 {
    @Select("select * from userinfo")
    List<User> queryAll();

    @Select("select * from userinfo where id= #{id}")
    List<User> queryById(Integer id);
}

对于比较简单的SQL语句,注解的方式写起来很简单,但是负责一点的SQL语句写起来会非常复杂

字符串的拼接很繁琐,而且没有错误提示,比较不适合新手,所以新手学习MyBatis框架,建议先使用xml方式再学习注解的方式。 

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李(写代码版)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值