小工具      在线工具  汉语词典  css  js  c++  java

Mybatis由浅入深——02增删改查CRUD

Mybatis,mybatis,java,开发语言 额外说明

收录于:40天前

这是Mybatis由浅入深的第2节,上文传送门:【Mybatis由浅入深-01入门】

通过本文您将掌握:

  1. 如何编写基本的CRUD语句?
  2. insert如何获取自增id值?
  3. #{} 和 ${} 有什么区别?
  4. 如何使用@Param?什么时候必须使用,什么时候不能使用?
  5. 如何单例SqlSessionFactory?

使用环境

以下是基本的先决条件:请参考其他博文自行安装。

创建mysql测试表

CREATE TABLE `user`  (
  `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `age` tinyint(1) UNSIGNED NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
insert into `user` VALUES (1,'天罡gg',18);

1、插入插入

1.1 接口方法

在 UserMapper.java 接口中添加一个新方法:

	int insert(User user);

1.2. 对应的xml映射文件

在UserMapper.xml中插入插入节点,一般指定ID(像使用雪花算法等 )的插入是这样的:

	<insert id="insert" parameterType="com.tiangang.dao.po.User">
        insert into user (id, name, age)
        values (#{id}, #{name}, #{age})
    </insert>

如果不指定id, 如何获取插入后自增的id值?

    <insert id="insert" parameterType="com.tiangang.dao.po.User">
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into user (name, age)
        values (#{name}, #{age})
    </insert>

阐明:现在一般公司都是遵循阿里规范,id是自增列,插入以后要拿到id,所以推荐做法就是在插入节点增加一个选择键节点,在订单=“之后” 时将自动递增id值设置到关键属性列。

面试常见考点
#{} 是参数占位符, #{id}就是id的占位符,会解析为JDBC预编译语句, 可以防sql注入(就像使用JDBC的?一样);
${} 是字符串替换,不防sql注入,在 SQL 语句中直接插入一个不转义的字符串,一般用在代替表名列名场景。
例如:
按列名称排序 :select * from user order by ${age},
按任意列查询:select * from user where ${columnName} = #{value}
得到到了吗?

1.3 单元测试

	@Test
    public void insertTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行insert
            User user = new User();
            user.setName("天罡666");
            user.setAge(28);
            int rows = mapper.insert(user);
            System.out.println("受影响行数:" + rows);
            System.out.println("新插入User:" + user);
            sqlSession.commit();
        } catch (Exception e) {
    
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
    
            sqlSession.close();
        }
    }

插入成功截图:
在这里插入图片描述

2、修改更新

2.1 接口方法

同样的方式,在UserMapper.java接口中添加一个新方法:

	int updateById(User user);

2.2 对应的xml映射文件

同理,在UserMapper.xml中插入更新节点

    <update id="updateById" parameterType="com.tiangang.dao.po.User">
        update user
        set name = #{name},
        age = #{age}
        where id = #{id}
    </update>

2.3 单元测试

	@Test
    public void updateByIdTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行update
            User user = new User();
            user.setId(2L);
            user.setName("天罡666");
            user.setAge(38);
            int rows = mapper.updateById(user);
            System.out.println("受影响行数:" + rows);
            System.out.println("修改后的User:" + user);
            sqlSession.commit();
        } catch (Exception e) {
    
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
    
            sqlSession.close();
        }
    }

执行结果如下图:
在这里插入图片描述

3、删除删除

3.1 接口方法

同样的方式,在UserMapper.java接口中添加一个新方法:

    int deleteById(Long id);

3.2 对应的xml映射文件

同理,在UserMapper.xml中插入删除节点

    <delete id="deleteById" parameterType="java.lang.Long">
        delete from user
        where id = #{id}
    </delete>

3.3 单元测试

	@Test
    public void deleteByIdTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行delete
            int rows = mapper.deleteById(2L);
            System.out.println("受影响行数:" + rows);
            sqlSession.commit();
        } catch (Exception e) {
    
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
    
            sqlSession.close();
        }
    }

执行结果如下图:
在这里插入图片描述

4、查询选择

为了演示目的,新插入 User:User{id=3, name='Tiangang 666',age=28}

4.1 接口方法(5个必会的查询场景)

将以下方法添加到 UserMapper.java 接口中:

    // 必会查询场景1:查询1个结果, 返回单个User
    User selectById(int id);
    // 必会查询场景2:查询N个结果, 返回结果List
    List<User> selectListByName(String name);
    // 必会查询场景3:根据N个参数(@Param指定参数名),查询N个结果,返回结果List
    List<User> selectListByNameAge(@Param("name") String name, @Param("gleAge") Integer gleAge);
    // 必会查询场景4:使用${} 进行任意列查询。另外,多个参数未指定@Param的使用
    List<User> selectByAnyOneColumn(String columnName, String symbol, String value);
    // 必会查询场景5:使用${} 进行order by
    List<User> selectAll(String orderBy);

4.2 对应的xml映射文件

在UserMapper.xml中插入5个选择节点

	<select id="selectById" resultType="com.tiangang.dao.po.User">
        select * from user where id = #{id}
    </select>

    <select id="selectListByName" resultType="com.tiangang.dao.po.User">
        select * from user
        where name like concat ('%', #{name},'%')
    </select>

    <select id="selectListByNameAge" resultType="com.tiangang.dao.po.User">
        select * from user
        where name like concat ('%', #{name},'%') and age>=#{gleAge}
    </select>

    <select id="selectByAnyOneColumn" resultType="com.tiangang.dao.po.User">
        select * from user
        where ${arg0} ${arg1} #{arg2}
    </select>

    <select id="selectAll" resultType="com.tiangang.dao.po.User">
        select * from user order by ${orderBy}
    </select>

4.3 单元测试

    @Test
    public void selectByIdTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行select
            User user = mapper.selectById(1);
            System.out.println(user);
        } catch (Exception e) {
    
            e.printStackTrace();
        } finally {
    
            sqlSession.close();
        }
    }

    @Test
    public void selectListByNameTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行select
            List<User> userList = mapper.selectListByName("天罡");
            System.out.println(userList);
        } catch (Exception e) {
    
            e.printStackTrace();
        } finally {
    
            sqlSession.close();
        }
    }

    @Test
    public void selectListByNameAgeTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行select
            List<User> userList = mapper.selectListByNameAge("天罡", 1);
            System.out.println(userList);
        } catch (Exception e) {
    
            e.printStackTrace();
        } finally {
    
            sqlSession.close();
        }
    }

    @Test
    public void selectByAnyOneColumnTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行select
            List<User> userList = mapper.selectByAnyOneColumn("name", "=", "天罡666");
            System.out.println(userList);
        } catch (Exception e) {
    
            e.printStackTrace();
        } finally {
    
            sqlSession.close();
        }
    }

    @Test
    public void selectAllTest() {
    
        // 1. 打开SqlSession
        SqlSession sqlSession = MyBatisManager.openSession();
        try {
    
            // 2. 得到UserMapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            // 3. 执行select
            List<User> userList = mapper.selectAll("age");
            System.out.println(userList);
        } catch (Exception e) {
    
            e.printStackTrace();
        } finally {
    
            sqlSession.close();
        }
    }

5、补充封装的MyBatisManager

细心的小伙伴可能已经发现多了一个MyBatisManager类,如果看了上文,就知道SqlSessionFactory应该是全局唯一的,所以我们将它封装到了MyBatisManager.获取SqlSessionFactory方法中(使用单例模式),并向外提供了MyBatisManager.开放会话,屏蔽了内部实现,使用方只需要每次调用开放会话即可,你得到到了吗?

public class MyBatisManager {
    

    private static volatile SqlSessionFactory sqlSessionFactory = null;

    public static SqlSessionFactory getSqlSessionFactory() {
    
        // double check 双重检查, 保证SqlSessionFactory全局只创建一次
        if (sqlSessionFactory == null) {
    
            synchronized (MyBatisManager.class) {
    
                if (sqlSessionFactory == null) {
    
                    String resource = "mybatis-config.xml";
                    try {
    
                        Reader reader = Resources.getResourceAsReader(resource);
                        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                    } catch (IOException e) {
    
                        e.printStackTrace();
                    }
                }
            }
        }
        return sqlSessionFactory;
    }

    public static SqlSession openSession() {
    
        return getSqlSessionFactory().openSession();
    }
}

6、本文全部源码

这节看似非常简单,实则非常考验基础,很多知识点相信有几年工作经验的人依然傻傻弄不清楚,
如有不到之处,敬请指正!
另外,源码中在单元测试类中CRUD做了简单的封装,新加了 UserMapperTest02Better.java,与UserMapperTest02.java测试功能一致,只是使用执行UserMapper方法方法简化了代码,不作赘述,详细请见源码:https://download.csdn.net/download/scm_2008/86509214

. . .

相关推荐

额外说明

flutter 解压 zip 中文乱码问题处理

前言 很简单的一个 zip 包解压缩的功能,但是 windows 平台中文显示乱码,很糟心,搜了一圈没找到现成的方法,在此贴上我的解决方式。 实现 导入需要的包 flutter pub add archive flutter pub add fast_

额外说明

【Unity3D开发小游戏】《植物大战僵尸游戏》Unity开发教程

推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 文章目录 一、前言 二、源码 三、正文 版本 1.主摄像机设置 2.创造草地 3.草坪音效 4.生命值脚本 5.创建向日葵植物 6

额外说明

8086版汇编

汇编不是一个语言,而是一群语言(不同架构不一样,相同架构不同版本不一样,相同架构相同版本可能还有不同的格式,如 x86 就有 ATT 和 intel 两种格式)。学汇编前现需要明白自己的学的汇编版本。本篇讲述的是 86/88 16 位的 intel 格式

额外说明

Kubernetes(一)----概述

文章目录 简介 起源 Kubernetes设计架构 Kubernetes节点 分层架构 kubelet kube-proxy Kubernetes控制面板 etcd Kubernetes API Server Scheduler Kubernetes控制

额外说明

JVM虚拟机详解

前排提示:文章内容过多,请耐心阅读或根据目录获取所需内容 前方高能 由于脑图比较长,可能部分用户无法看清内容,关注公众号:不会修电脑,获取本文所有脑图资源 1.JVM相关 1.1.概述 JVM是Java Virtual Machine的缩写,中文意思是J

额外说明

云原生-云应用挂载持久化存储卷NAS及通过NAS实现批量机器并发查找日志

接上篇跑路文:云原生-ZK集群及ZK云应用(ZK镜像制作、镜像上传、部署ZK应用、挂载持久化存储卷NAS) 需求 先说明需求,为什么要用NAS? 1.因为之前机器都是在ECS模式下,日志都可以持久化存储在ECS机器上,但是一旦应用上云部署为云应用了,那么

额外说明

【C# 基础精讲】继承、封装、多态

继承(Inheritance)、封装(Encapsulation)和多态(Polymorphism)是面向对象编程中的三大核心概念,它们构成了面向对象编程的基础,有助于创建更加模块化、可扩展和可维护的代码。这三个概念在C#及其他面向对象编程语言中广泛应用

额外说明

美团:复杂风控场景下,如何打造一款高效的规则引擎

转载来源:https://tech.meituan.com/2020/05/14/meituan-security-zeus.html 在互联网时代,安全已经成为企业的命脉。美团信息安全团队需要采用各种措施和手段来保障业务安全,从而确保美团平台上的用户和

额外说明

探索生成人工智能的前景

什么是生成式人工智能? 生成式人工智能是一类旨在创建新颖内容的人工智能 (AI) 技术和模型。这些模型不是简单地复制,而是利用从训练数据集中收集的模式和见解从头开始生成数据(例如文本、图像、音乐等)。 生成式人工智能如何运作? 生成式人工智能使用各种机器

额外说明

TCP/UDP网络调试工具-Windows下的NetAssist和Linux下的nc网络调试工具

1.Windows下的网络调试工具-NetAssist 由于Windows下经常使用网络调试工具NetAssist.exe来监控TCP和UDP服务器和客户端,因此对于需要编写各种通信协议的TCP服务器、客户端和UDP通信程序来说非常方便。 。 NetAs

ads via 小工具