利用MyBatis框架操作数据库2

简介: 利用MyBatis框架操作数据库

利用MyBatis框架操作数据库1:https://developer.aliyun.com/article/1521801

like 模糊查询

在sql语句进行查询时也会经常用到like模糊查询,%表示0或多个字符,_表示一个字符,那么先使用?{}占位符来查询username中含有‘a’字符的用户信息。

xml的select标签的信息如下:

<select id="getUserInfoByLike" resultType="com.example.mybatisdemo.model.UserInfo">
        select * from userinfo where username like %?{username}%
</select>

测试结果:

并不能完成直接替换,那么使用#{}参数占位符来进行测试,测试结果如下:

这两种参数占位符都不能直接实现模糊查询,就需要使用mysql中的内置函数concat来进行处理,将xml文件中的select标签的内容修改如下:

    <!-- 模糊查询用户信息-->
    <select id="getUserInfoByLike" resultType="com.example.mybatisdemo.model.UserInfo">
        select * from userinfo where username like concat('%',#{username},'%')
    </select>

测试结果如下:

多表查询

上述的操作都是在单表的基础上进行,但是查询还存在多表查询,常见的表关系有一对一、一对多和多对多,那么利用MyBatis就可以实现一对一和一对多的多表查询。

一对一的多表查询

在mycnblog数据库中有userinfo和articleinfo表,两个表的字段设置如下所示:

其中articleinfo表的uid对应userinfo表的的id。

查询文章对应的用户信息。

首先在model包下创建ArticleInfo类,将articleinfo表的字段作为ArticleInfo类的属性,并添加UserInfo属性。

@Data
public class ArticleInfo {
    private int id;
    private String title;
    private String content;
    private String createtime;
    private String updatetime;
    private int uid;
    private int rcount;
    private int state;
    private UserInfo userInfo;
}

在Mapper包下创建ArticleMapper接口,定义id获取文章信息的方法:

 //通过文章id来获取文章信息
    public ArticleInfo getUserInfoByArticleInfoId(@Param("id") Integer id);

在mybatis包下创建ArticleMapper.xml文件,添加select标签,由于要实现多表查询,select标签的ResultType标签就无法满足需求了,就需要添加一个resultMap标签, 其id为标签名,type为要映射的实体类的路径,在该标签中设置主键(id)和其他普通的字段(result),其中column为数据库字段名,property为程序中的属性名,并且在UserMapper.xml文件中也添加resultMap标签,然后在ArticleMapper.xml的resultMap标签中继续添加association标签,property代表要连接的表在程序中的属性名,resultMap为UserMapper.xml文件中的resultMap标签名称,由于userinfo表和articleinfo表中有同名的字段名,就使用columnPrefix属性,表示在原有字段名前添加设置的columnPrefix属性值,UserMapper.xml文件的resultMap标签如下:

<resultMap id="baseMapper" type="com.example.mybatisdemo.model.UserInfo">
        <!--设置主键属性-->
        <id column="id" property="id"></id>
        <!--设置其他属性-->
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="username" property="username"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <result column="state" property="state"></result>
 </resultMap>

ArticleMapper.xml文件的内容如下:

<resultMap id="baseMapper" type="com.example.mybatisdemo.model.ArticleInfo">
        <!--设置主键-->
        <id column="id" property="id"></id>
        <!-- 设置其他属性-->
        <result column="title" property="title"></result>
        <result column="content" property="content"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <result column="uid" property="uid"></result>
        <result column="rcount" property="rcount"></result>
        <result column="state" property="state"></result>
        <association property="userInfo"
                     resultMap="com.example.mybatisdemo.mapper.UserMapper.baseMapper"
                     columnPrefix="u_">
        </association>
    </resultMap>
    <select id="getUserInfoByArticleInfoId" resultMap="baseMapper">
        select a.*,u.id u_id,u.username u_username,u.password u_password,u.photo u_photo from articleinfo a left join userinfo u on a.uid=u.id
        where a.id=#{id}
    </select>

最后在生成的test类中编写测试方法:

 //通过id获取文章信息,实现一对一的多表查询
    @Test
    void getUserInfoByArticleInfoId() {
        ArticleInfo articleInfo  = articleMapper.getUserInfoByArticleInfoId(1);
        log.info(String.valueOf(articleInfo));
    }

测试结果:

日志中的信息:

createtime等字段为null因为在查询的时候就没有select这些字段。

一对多的多表查询

一个用户对应多篇文章,就需要使用一对多的多表查询。

先在UserInfo类中增加一个存放文章信息的集合:

private List<ArticleInfo> atrlist;

然后再UserMapper接口中定义查询方法:

 //根据id查询用户信息,并实现一对多的多表查询
 public UserInfo getUserInfoAndArtInfoById(@Param("id") Integer id);

在UserMapper.xml文件的resultMap标签中添加collection标签,其属性与association标签的属性值类似:

<collection property="atrlist"
                    resultMap="com.example.mybatisdemo.mapper.ArticleMapper.baseMapper"
                    columnPrefix="a_">
</collection>

再添加select标签:

    <!-- 通过id获取到用户信息,实现一对多的多表查询-->
    <select id="getUserInfoAndArtInfoById" resultMap="baseMapper">
        select u.*,a.id a_id,a.title a_title,a.content a_content from userinfo u left join  articleinfo a on u.id=a.uid
        where u.id=#{id}
    </select>

在生成的测试类中编写如下的代码:

    @Test
    void getUserInfoAndArtInfoById() {
        UserInfo userInfo = userMapper.getUserInfoAndArtInfoById(1);
        log.info(String.valueOf(userInfo));
    }

测试结果:

日志中的文章信息如下:

四、动态SQL

在上述的操作中都使用的是固定的参数,并且有时会多写,等都会出现报错,但动态SQL就能很好的解决上述问题。

if标签

if标签的test属性可以判断参数是否有值,如果没有值,就会隐藏if标签中的参数。

非必传的参数就可以使用if标签。

例如新增一个Userinfo信息,username和id为必传信息,但是photo信息为非必传。

那么UserMapper的insert标签如下:

<insert id="addUserInfoByIf">
        insert into userinfo(username,password
        <if test="photo!=null">
            ,photo
        </if>)
        values(#{username},#{password}
        <if test="photo!=null">
                    ,#{photo}
                </if>
                )
</insert>

在传入参数的时候未传入photo参数:

@Test
    void addUserInfoByIf() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("老6");
        userInfo.setPassword("1234");
        int i = userMapper.addUserInfoByIf(userInfo);
        Assertions.assertEquals(1,i);
    }

测试结果:

trim标签

trim标签有如下的属性:

  • prefix:整个语句块,以prefix的值作为前缀;
  • suffix:整个语句块,以suffix的值作为后缀;
  • prefixOverrides:表示整个语句块要去除掉的前缀;
  • suffixOverrides:表示整个语句块要去除掉的后缀。

那么, 上面新增一个Userinfo信息就可以使用trim标签,修改xml标签的内容如下:

<insert id="addUserInfoByIf">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">   username,password
        <if test="photo!=null">
            ,photo
        </if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
        #{username},#{password}
        <if test="photo!=null">
                    ,#{photo}
                </if>
        </trim>
    </insert>


测试结果:

where标签

where标签可以实现查询中的where语句替换,如果where中没有任何查询条件,那么就会删除where语句,如果有查询条件,就会自动生成相应的sql语句,并可以自动去除最前面的and标签,where标签通常搭配if标签来进行使用。

例如利用名字和密码查询用户信息:

UserMapper.xml的查询标签如下所示:

 <!--通过where标签查询用户信息-->
    <select id="getUserInfoByWhere" resultType="com.example.mybatisdemo.model.UserInfo">
        select * from userinfo
        <where>
            <if test="username!=null">
                username=#{username}
            </if>
            <if test="password!=null">
               and password=#{password}
            </if>
        </where>
    </select>


当传入用户名和密码之后测试结果如下:

where标签也可以使用<trim>标签进行替换:

<trim prefix="where" suffixOverrides="and">

</trim>

set标签

set标签是针对update更新语句的,可以代替update标签中的set关键字来完成。

set标签通常需要搭配if标签来进行使用。

例如利用id来修改用户信息。

在xml文件中的update标签如下:

    <update id="updateUserInfoById">
        update userinfo
        <set>
            <if test="username!=null">
                username=#{username},
            </if>
            <if test="password!=null">
                password=#{password}
            </if>
        </set>
        where id=#{id}
    </update>

在测试类中的测试代码如下:

    @Test
    void updateUserInfoById() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("王五");
        userInfo.setPassword("9087");
        userInfo.setId(3);
        int i = userMapper.updateUserInfoById(userInfo);
        Assertions.assertNotNull(i);
    }

测试结果:

set标签也可以用trim标签进行替代

<trim prefix="set" suffixOverrides=",">

</trim>

foreach标签

对集合遍历时通常会使用该标签,在in关键字之后通常使用,该标签有如下的属性:

collection:绑定方法参数的集合,如List、Set、Map以及数组等;

item:遍历时的每个对象;

open:语句块开头的字符串;

close:语句块结束的字符串;

separator:每次遍历之间的字符串。

例如删除id在指定集合的用户信息:

xml文件中的delete标签如下:

    <delete id="deleteUserInfoByList">
        delete
        from userinfo
        where id in <foreach collection="list" item="uid" open="(" close=")" separator=",">
        #{uid}
    </foreach>
    </delete>

在生成的test类编写的测试代码如下:

    @Test
    void deleteUserInfoByList() {
        List<Integer> list = new LinkedList<>();
        list.add(4);
        list.add(3);
        list.add(5);
        int i = userMapper.deleteUserInfoByList(list);
        log.info(String.valueOf(i));
    }


测试结果:


目录
相关文章
|
12天前
|
SQL Java 数据库连接
深入 MyBatis-Plus 插件:解锁高级数据库功能
Mybatis-Plus 提供了丰富的插件机制,这些插件可以帮助开发者更方便地扩展 Mybatis 的功能,提升开发效率、优化性能和实现一些常用的功能。
86 26
深入 MyBatis-Plus 插件:解锁高级数据库功能
|
11天前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
29 1
持久层框架MyBatisPlus
|
17天前
|
SQL 安全 Java
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
13 1
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
|
1月前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
64 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
1月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
42 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
25天前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
28 0
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
SQL Java 数据库连接
Hibernate 是一款开源 ORM(对象关系映射)框架,封装了 JDBC,允许以面向对象的方式操作数据库,简化了数据访问层的开发。
Hibernate 是一款开源 ORM(对象关系映射)框架,封装了 JDBC,允许以面向对象的方式操作数据库,简化了数据访问层的开发。通过映射机制,它可以自动处理对象与数据库表之间的转换,支持主流数据库,提高了代码的可移植性和可维护性。其核心接口包括 SessionFactory、Session 和 Transaction 等,通过它们可以执行数据库的 CRUD 操作。配置方面,需在项目中引入 Hibernate 及数据库驱动依赖,并创建 `hibernate.cfg.xml` 配置文件来设置数据库连接和 Hibernate 行为参数。
47 1
|
3月前
|
SQL 关系型数据库 MySQL
解决:Mybatis-plus向数据库插入数据的时候 报You have an error in your SQL syntax
该博客文章讨论了在使用Mybatis-Plus向数据库插入数据时遇到的一个常见问题:SQL语法错误。作者发现错误是由于数据库字段中使用了MySQL的关键字,导致SQL语句执行失败。解决方法是将这些关键字替换为其他字段名称,以避免语法错误。文章通过截图展示了具体的操作步骤。
|
3月前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
36 0