前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis由浅入深 - 02增删改查CRUD

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

作者头像
天罡gg
发布2022-12-02 15:21:28
6930
发布2022-12-02 15:21:28
举报
文章被收录于专栏:天罡gg

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

通过本文您将掌握:

  1. 基本的CRUD语句如何写?
  2. insert如何获得自增id值?
  3. #{}与${}的区别?
  4. @Param到底该怎么用? 什么时侯必须用,什么时侯可以不用
  5. SqlSessionFactory如何单例?

使用环境

以下为基础前置条件:请参考其它博文自行安装。

创建Mysql测试表

代码语言:javascript
复制
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、插入insert

1.1 接口方法

在UserMapper.java接口新增一个方法:

代码语言:javascript
复制
	int insert(User user);

1.2. 对应的xml映射文件

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

代码语言:javascript
复制
	<insert id="insert" parameterType="com.tiangang.dao.po.User">
        insert into user (id, name, age)
        values (#{id}, #{name}, #{age})
    </insert>

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

代码语言:javascript
复制
    <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,所以推荐做法就是在insert节点增加一个selectKey节点,在order=“after” 时将自增id值设置到keyProperty列。

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

1.3 单元测试

代码语言:javascript
复制
	@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、修改update

2.1 接口方法

同理,在UserMapper.java接口新增一个方法:

代码语言:javascript
复制
	int updateById(User user);

2.2 对应的xml映射文件

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

代码语言:javascript
复制
    <update id="updateById" parameterType="com.tiangang.dao.po.User">
        update user
        set name = #{name},
        age = #{age}
        where id = #{id}
    </update>

2.3 单元测试

代码语言:javascript
复制
	@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、删除delete

3.1 接口方法

同理,在UserMapper.java接口新增一个方法:

代码语言:javascript
复制
    int deleteById(Long id);

3.2 对应的xml映射文件

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

代码语言:javascript
复制
    <delete id="deleteById" parameterType="java.lang.Long">
        delete from user
        where id = #{id}
    </delete>

3.3 单元测试

代码语言:javascript
复制
	@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、查询select

为了演示需要,新插入User:User{id=3, name=‘天罡666’, age=28}

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

在UserMapper.java接口新增方法如下:

代码语言:javascript
复制
    // 必会查询场景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节点

代码语言:javascript
复制
	<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 单元测试

代码语言:javascript
复制
    @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.getSqlSessionFactory方法中(使用单例模式),并向外提供了MyBatisManager.openSession,屏蔽了内部实现,使用方只需要每次调用openSession即可,你Get到了吗?

代码语言:javascript
复制
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测试功能一致,只是使用executeUserMapperMethod方法简化了代码,不作赘述,详细请见源码:https://download.csdn.net/download/scm_2008/86509214

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 通过本文您将掌握:
  • 使用环境
    • 创建Mysql测试表
    • 1、插入insert
      • 1.1 接口方法
        • 1.2. 对应的xml映射文件
          • 1.3 单元测试
          • 2、修改update
            • 2.1 接口方法
              • 2.2 对应的xml映射文件
                • 2.3 单元测试
                • 3、删除delete
                  • 3.1 接口方法
                    • 3.2 对应的xml映射文件
                      • 3.3 单元测试
                      • 4、查询select
                        • 4.1 接口方法(5个必会的查询场景)
                          • 4.2 对应的xml映射文件
                            • 4.3 单元测试
                            • 5、补充封装的MyBatisManager
                            • 6、本文全部源码
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档