• 【Mybatis实战】02——XML方式的基本用法


    一、一个简单的权限控制需求配置

    设定了一个简单的权限控制需求,采用RBAC(Role-Based Access Control ,基于角色的访问控制)方式。

    步骤1:配置环境

    步骤1:

    1. 创建数据库表
    2. 创建实体类
    3. 创建接口类(eq:UserMapper.class)
    4. 创建接口类的mapper XML(eq:UserMapper.xml)
    5. 配置MybatisUtils 配置类
    6. 编写select、insert、update、delete等CRUD语句



    1. 创建数据库表

    
    -- 用户表
    create table `sys_user`(
    	id bigint not null auto_increment primary key comment '用户ID',
    	user_name varchar(50) comment '用户名',
    	user_password varchar(50) comment '密码',
    	user_email varchar(50) comment '邮箱',
    	user_info text comment '简介',
    	head_img blob comment '头像',
    	create_time datetime comment '创建时间'
    )engine = innodb  charset=utf8
    
    
    insert into `sys_user` values('1','admin','123456','admin@mybatis','管理员',null,'2022-08-11 15:00:00');
    insert into `sys_user` values('1001','test','123456','test@mybatis','测试用户',null,'2022-08-11 15:04:00');
    
    
    -- 角色表
    create table sys_role (
    	id bigint not null auto_increment primary key comment '角色ID',
    	role_name varchar(50) comment '用户名',
    	enabled int comment '有效标志',
    	create_by bigint comment '创建人',
    	create_time datetime comment '创建时间'
    )engine = innodb  charset=utf8
    
    
    
    
    insert into `sys_role` values('1','管理员','1','1','2022-08-11 15:10:00');
    insert into `sys_role` values('2','普通用户','1','1','2022-08-11 15:14:00');
    
    
    -- 权限表
    create table sys_privilege (
    
    	id bigint not null auto_increment primary key comment '权限ID',
    	privilege_name varchar(50) comment '权限名称',
    	privilege_url varchar(200) comment '权限URL'
    )engine = innodb  charset=utf8
    
    
    
    
    
    
    insert into `sys_privilege` values('1','用户管理','/users');
    insert into `sys_privilege` values('2','角色管理','/roles');
    insert into `sys_privilege` values('3','系统日志','/logs');
    insert into `sys_privilege` values('4','人员维护','/persons');
    insert into `sys_privilege` values('5','单位维护','/companies');
    
    
    
    
    -- 用户角色关联表
    create table sys_user_role(
    	user_id bigint comment '用户ID',
    	role_id bigint comment '角色ID'
    )
    
    
    insert into `sys_user_role` values('1','1');
    insert into `sys_user_role` values('1','2');
    insert into `sys_user_role` values('1001','2');
    
    
    
    -- 角色权限关联表
    
    create table sys_role_privilege (
    	role_id bigint comment '角色ID',
    	privilege_id bigint comment '权限ID'
    )
    
    
    insert into `sys_role_privilege` values('1','1');
    insert into `sys_role_privilege` values('1','3');
    insert into `sys_role_privilege` values('1','2');
    insert into `sys_role_privilege` values('2','4');
    insert into `sys_role_privilege` values('2','5');
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82



    2. 创建实体类

    因为Mybatis 默认是遵循 下划线转驼峰命名方式的,所以在创建实体类时一般都按照这种方式进行创建

    共有5个实体表

    • 用户表:SysUser.class
    • 角色表:SysRole.class
    • 权限表:SysPrivilege.class
    • 用户角色表:SysUserRole.class
    • 角色权限表:SysRolePrivilege.class

    用户表:SysUser.class

    public class SysUser {
    
        private Long id;
    
        private String userName;
    
        private String userPassword;
    
        private String userEmail;
    
        private String userInfo;
    
        private byte[] headImg;
    
        private Date createTime;
    
    
       // 省略get()set() toString()方法
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    角色表:SysRole.class

    public class SysRole {
    
        private Long id;
    
        private String roleName;
    
        private Long createBy;
    
        private Date createTime;
    
        private SysUser user;
    
       // 省略get()set() toString()方法
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    权限表:SysPrivilege.class

    public class SysPrivilege {
    
        private Long id;
    
        private String privilegeName;
    
        private String privilegeUrl;
     // 省略get()set() toString()方法
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    用户角色表:SysUserRole.class

    public class SysUserRole {
    
        private Long userId;
    
        private Long roleId;
     // 省略get()set() toString()方法
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    角色权限表:SysRolePrivilege.class

    public class SysRolePrivilege {
    
        private Long roleId;
    
        private Long privilegeId;
     // 省略get()set() toString()方法
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8



    3. 创建接口类

    创建五个接口类

    public interface UserMapper {
    }
    
    
    • 1
    • 2
    • 3
    public interface RoleMapper {
    }
    
    
    • 1
    • 2
    • 3
    public interface PrivilegeMapper {
    }
    
    
    • 1
    • 2
    • 3
    public interface UserRoleMapper {
    }
    
    
    • 1
    • 2
    • 3
    public interface RolePrivilegeMapper {
    }
    
    
    • 1
    • 2
    • 3



    4. 创建对应mapper

    创建对应mapper.xml

    
            DOCTYPE mapper
                    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    
    <mapper namespace="com.lyf.dao.UserMapper">
    
    mapper>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    
            DOCTYPE mapper
                    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.lyf.dao.RoleMapper">
    
    
    mapper>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    
            DOCTYPE mapper
                    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    
    <mapper namespace="com.lyf.dao.PrivilegeMapper">
    
    
    mapper>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    
            DOCTYPE mapper
                    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.lyf.dao.UserRoleMapper">
    
    
    mapper>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    
            DOCTYPE mapper
                    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    
    <mapper namespace="com.lyf.dao.RolePrivilegeMapper">
    
    mapper>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10



    5. 配置MybatisUtils

    MybatisUtils.class

    public class MybatisUtils {
    
        private static SqlSessionFactory sqlSessionFactory;
    
        static {
    
            try {
                //使用mybatis第一步获取SessionFactory对象
                String resource = "mybatis-config.xml";
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
        // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
        // 你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
    
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24



    步骤2:编写业务流程

    步骤2-业务流程:

    1. 接口添加方法(在UserMapper.class接口中,添加selectById方法)
    2. mapper配置映射(在UserMapper.xml中,添加resultMap和select)
    3. 测试类:测试

    XML字段映射主要有三种方式:

    • SQL别名
    • 配置驼峰命名mapUnderscoreToCamelCase(常用)
    • 使用ResultMap

    1. 接口添加方法

    public interface UserMapper {
    
        /**
         * 通过 id 查询用户
         * @param id
         * @return
         */
        SysUser selectById(Long id);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2. mapper配置映射

    
            DOCTYPE mapper
                    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    
    <mapper namespace="com.lyf.dao.UserMapper">
    
        <resultMap id="userMap" type="com.lyf.entity.SysUser">
            <id property="id" column="id"/>
            <result property="userName" column="user_name"/>
            <result property="userPassword" column="user_password"/>
            <result property="userEmail" column="user_email"/>
            <result property="userInfo" column="user_info"/>
            <result property="headImg" column="head_img" jdbcType="BLOB"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    
        resultMap>
    
        
        <select id="selectById" resultMap="userMap">
            select * from sys_user where id = #{id}
        select>
    mapper>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3. 测试

      @Test
        public void testSelectById(){
            // 获取SqlSession
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                //获取 UserMapper接口
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
                //调用 selectById 方法 ,查询Id 为 1 的用户
                SysUser user = mapper.selectById(1l);
                // user不为空
                Assert.assertNotNull(user);
    
                // userName = admin
                Assert.assertEquals("admin",user.getUserName());
    
                System.out.println(user);
            }finally {
                sqlSession.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    测试结果:查询成功!!!
    在这里插入图片描述

    二、编写CRUD方法

    1. Select

    业务需求:查询所有用户

    业务需求:查询所有用户
    业务过程还是那三步:

    1. 接口添加方法
    2. mapper配置映射(以下Mapper都是在UserMapper.xml 添加)
    3. 测试类:测试
      /**
         * 查询全部用户
         * @return
         */
        List<SysUser> selectAll();
    
    • 1
    • 2
    • 3
    • 4
    • 5
        <select id="selectAll" resultType="com.lyf.entity.SysUser">
            select id,
                user_name,
                user_password,
                user_email,
                user_info,
                head_img,
                create_time
            from sys_user
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
      @Test
        public void testSelectAll(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
                // 调用selectALL 方法查询所有用户
                List<SysUser> userList = mapper.selectAll();
                // 结果不为空
                Assert.assertNotNull(userList);
                // 用户数量大于0个
                Assert.assertTrue(userList.size() > 0);
                // 打印输出
                System.out.println(userList);
    
            }finally {
                sqlSession.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    测试结果:总量:6条
    在这里插入图片描述

    业务需求:根据用户id 获取角色信息

    业务需求:根据用户id 获取角色信息

        /**
         * 根据用户id 获取角色信息
         * @param userId
         * @return
         */
        List<SysRole> selectRolesByUserId(Long userId);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
      <select id="selectRolesByUserId" resultType="com.lyf.entity.SysRole">
            select
                r.id,
                r.role_name roleName,
                r.enabled,
                r.create_by createBy,
                r.create_time createTime,
                u.user_name as "user.userName",
                u.user_email as "user.userEmail"
            from sys_user u
            inner join sys_user_role ur on u.id = ur.user_id
            inner join sys_role r on ur.role_id = r.id
            where u.id = #{userId}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
     @Test
        public void testSelectRolesByUserId(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
                List<SysRole> roleList = mapper.selectRolesByUserId(1L);
    
                Assert.assertNotNull(roleList);
    
                Assert.assertTrue(roleList.size()>0);
    
                System.out.println(roleList);
            }finally {
                sqlSession.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    测试结果:
    在这里插入图片描述

    2. Insert

    业务需求:新增用户

    业务需求:新增用户

       /**
         * 新增用户
         * @param sysUser
         * @return
         * @TODO: insert attempted to return null from a method with a primitive return type (int).
         */
        int insert(SysUser sysUser);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
        <insert id="insert">
            insert into sys_user(
                id,user_name,user_password,
                user_email,user_info,head_img,create_time
            )
            values(
                #{id},#{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg ,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}
            )
        insert>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
        @Test
        public void testInsert(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
                // 创建一个对象
                SysUser user = new SysUser();
                user.setUserName("test1");
                user.setUserPassword("123456");
                user.setUserEmail("test@mybatis");
                user.setUserInfo("test info");
                user.setHeadImg(new byte[]{1,2,3});
                user.setCreateTime(new Date());
                // 将新建的对象插入数据库中, 特别注意这里的返回值result是执行的SQL影响的行数
                int result = mapper.insert(user);
                // 只插入一条数据
                Assert.assertEquals(1,result);
    
                //id 为null , 没有给id 赋值, 并且没有配置回写id的值
                Assert.assertNull(user.getId());
                System.out.println(result);
    
            }finally {
                sqlSession.commit();
                sqlSession.close();
            }
            }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    测试结果:添加成功
    在这里插入图片描述

    业务需求:新增用户-使用 useGenerateKeys 方式

    业务需求:新增用户-使用 useGenerateKeys 方式

     int insert2(SysUser sysUser);
    
    • 1
      <insert id="insert2" useGeneratedKeys="true" keyProperty="id">
            insert into sys_user(
                user_name,user_password,
                user_email,user_info,head_img,create_time
            )
            values(
                #{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg ,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}
            )
        insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
        @Test
        public void testInsert2(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
                // 创建一个对象
                SysUser user = new SysUser();
                user.setUserName("test1");
                user.setUserPassword("123456");
                user.setUserEmail("test@mybatis");
                user.setUserInfo("test info");
                user.setHeadImg(new byte[]{1,2,3});
                user.setCreateTime(new Date());
                // 将新建的对象插入数据库中, 特别注意这里的返回值result是执行的SQL影响的行数
                int result = mapper.insert2(user);
                // 只插入一条数据
                Assert.assertEquals(1,result);
    
                //因为id 会写, 所以id 不为null
                Assert.assertNotNull(user.getId());
                if (result>0){
                    System.out.println("添加成功:"+user);
                }
    
            }finally {
                sqlSession.commit();
                sqlSession.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    测试结果:
    在这里插入图片描述

    业务需求:新增用户 -使用 selectKey 方式

    业务需求:新增用户 -使用 selectKey 方式

        /**
         * 新增用户 -使用 selectKey 方式
         */
        int insert3(SysUser sysUser);
    
    • 1
    • 2
    • 3
    • 4
        <insert id="insert3" >
            insert into sys_user(
                user_name,user_password,
                user_email,user_info,head_img,create_time
            )
            values(
                #{userName},#{userPassword},#{userEmail},#{userInfo},#{headImg ,jdbcType=BLOB},#{createTime,jdbcType=TIMESTAMP}
            )
            <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
                SELECT LAST_INSERT_ID()
            selectKey>
        insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    
        @Test
        public void testInsert3(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
                // 创建一个对象
                SysUser user = new SysUser();
                user.setUserName("test1");
                user.setUserPassword("123456");
                user.setUserEmail("test@mybatis");
                user.setUserInfo("test info");
                user.setHeadImg(new byte[]{1,2,3});
                user.setCreateTime(new Date());
                // 将新建的对象插入数据库中, 特别注意这里的返回值result是执行的SQL影响的行数
                int result = mapper.insert3(user);
                // 只插入一条数据
                Assert.assertEquals(1,result);
    
                //因为id 会写, 所以id 不为null
                Assert.assertNotNull(user.getId());
                if (result>0){
                    System.out.println("添加成功:"+user);
                }
    
            }finally {
                sqlSession.commit();
                sqlSession.close();
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    测试结果:三种方式都可以添加成功,根据业务不同选择不同方式。
    在这里插入图片描述

    3. Update

    业务需求:根据主键更新

    业务需求:根据主键更新

        /**
         * 根据主键更新
         * @param sysUser
         * @return
         */
        int updateById(SysUser sysUser);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
        <update id="updateById">
            update sys_user
            set user_name = #{userName},
                user_password = #{userPassword},
                user_email = #{userEmail},
                user_info = #{userInfo},
                head_img = #{headImg,jdbcType=BLOB},
                create_time = #{createTime,jdbcType=TIMESTAMP}
            where id = #{id}
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
       @Test
        public void testUpdateById(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
                SysUser user = mapper.selectById(1L);
                user.setUserName("admin_test2");
                user.setUserEmail("admin@mybatis2");
                int result = mapper.updateById(user);
                if (result>0){
                    System.out.println("更新成功:"+user);
                }
    
    
    
            }finally {
                // 提交,存储在数据库
                sqlSession.commit();
                // 回滚,存储在缓存
    //            sqlSession.rollback();
                sqlSession.close();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    测试:
    在这里插入图片描述

    4. Delete

    业务需求:通过主键删除

    业务需求:通过主键删除

        /**
         * 通过主键删除
         * @param id
         * @return
         */
        int deleteById(Long id);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
      <delete id="deleteById">
            delete from sys_user where id = #{id}
        delete>
    
    • 1
    • 2
    • 3
        @Test
        public void testDeleteById(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
                int result = mapper.deleteById(1019L);
                if (result >0){
                    System.out.println("删除成功");
                }
    
            }finally {
    //            sqlSession.rollback();
                // 造成数据变动,都要commit提交
                sqlSession.commit();
                sqlSession.close();
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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

    三、多个接口参数

    1. 接口参数为基本类型

    在实际应用中经常会遇到使用多个参数的情况,我们通常将多个参数合并到一个JavaBean中,例如:User类、Role类。这种方法用起来很方便,适合参数较多的情况,并不适合全部的情况。
    对于参数比较少的情况,还有两种方式可以采用:

    • 使用Map类型作为参数
    • 使用@Param注解

    Map类型不太简洁,所以主要使用@Param
    步骤:

    • 接口:@Param(“userId”) Long userId
    • sql传入:#{userId}

    先来看下不使用@Param 注解会发生什么错误:

    业务需求:根据用户ID 和角色的enabled 状态来查询用户的所有角色。

       /**
         * 根据用户id 和角色的enabled状态获取用户的角色
         * @param userId
         * @param enabled
         * @return
         */
        List<SysRole> selectRolesByUserIdAndRoleEnabled( Long userId, Integer enabled);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
     <select id="selectRolesByUserIdAndRoleEnabled"
                resultType="com.lyf.entity.SysRole">
            select
                r.id,
                r.role_name roleName,
                r.enabled,
                r.create_by createBy,
                r.create_time createTime
            from sys_user u
            inner join sys_user_role ur on u.id = ur.user_id
            inner join sys_role r on ur.role_id = r.id
            where u.id = #{userId} and r.enabled = #{enabled}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
     @Test
        public void testSelectRolesByUserIdAndRoleEnabled(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
                List<SysRole> userList = mapper.selectRolesByUserIdAndRoleEnabled(1L, 1);
                System.out.println(userList);
    
            }finally {
    //            sqlSession.rollback();
                // 造成数据变动,都要commit提交
                sqlSession.close();
                // Parameter 'userId' not found. Available parameters are [arg1, arg0, param1, param2]
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    测试结果:

    报错:Parameter 'userId' not found. Available parameters are [arg1, arg0, param1, param2]
    
    • 1

    这个错误表示,XML可用的参数只有arg1, arg0, param1, param2, param1, param2 都是Mybatis根据参数位置自定义的名字,如果将XML中的#{userId} 改为#{arg0} 或 #{param1} ,将 # {enabled} 改为 #{1} 或 #{param2} ,这个方法便可使用,但实际上不建议这么做。

    使用@param 目的:指明:SQL查询#{userId}的具体参数值在哪

    添加@param注解

        /**
         * 根据用户id 和角色的enabled状态获取用户的角色
         * @param userId
         * @param enabled
         * @return
         */
        List<SysRole> selectRolesByUserIdAndRoleEnabled(@Param("userId") Long userId,@Param("enabled") Integer enabled);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    这种情况一般出现在两个参数以上,因为一个参数的时候,Mybatis不关心这个参数叫什么名字,就会直接把这个唯一的参数值拿来使用。

    2. 接口参数为对象类型

    步骤:

    • 接口:@Param(“user”) SysUser user,
    • sql传入:#{user.id}
        /**
         * 根据用户id 和角色的enabled状态获取用户的角色
         * 参数类型:实体类对象
         * @param user
         * @param role
         * @return
         */
        List<SysRole> selectRolesByUserIdAndRoleEnabled2(@Param("user") SysUser user,@Param("role") SysRole role );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
     <select id="selectRolesByUserIdAndRoleEnabled2"
                resultType="com.lyf.entity.SysRole">
            select
                r.id,
                r.role_name roleName,
                r.enabled,
                r.create_by createBy,
                r.create_time createTime
            from sys_user u
            inner join sys_user_role ur on u.id = ur.user_id
            inner join sys_role r on ur.role_id = r.id
            where u.id = #{user.id} and r.enabled = #{role.enabled}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
     @Test
        public void testSelectRolesByUserIdAndRoleEnabled2(){
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            try{
                UserMapper mapper = sqlSession.getMapper(UserMapper.class);
                SysUser user = new SysUser();
                user.setId(1L);
                SysRole sysRole = new SysRole();
                sysRole.setEnabled(1L);
                List<SysRole> userList = mapper.selectRolesByUserIdAndRoleEnabled2(user,sysRole );
                System.out.println(userList);
    
            }finally {
    //            sqlSession.rollback();
                // 造成数据变动,都要commit提交
                sqlSession.close();
                // Parameter 'userId' not found. Available parameters are [arg1, arg0, param1, param2]
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

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

    四、Mapper接口动态代理实现原理

    待续

  • 相关阅读:
    战神引擎传奇假设教程
    为自己量身打造一个 Rust 项目模板/脚手架
    图像处理之matlab中imnoise函数用法详解
    Vite - 配置 - 不同的环境执行不同的配置文件
    第一百四十六回 跟手指移动的小球
    PCL内置点云类型
    假如面试官让你手撕顺序表,该如何快速准确的交出一份让面试官满意的答卷?
    基于FDB方法的供给需求优化算法改进——基于工程设计问题的综合研究
    springboot基于SpringBoot的冬奥会科普平台springboot21
    浅谈keras.preprocessing.text
  • 原文地址:https://blog.csdn.net/weixin_44735928/article/details/126295821