目录

一、创建用户、角色和权限表

二、创建实体类

三、使用XML方式

四、select用法——单表查询

1.配置UserMapper

2.写出对应的接口类

3.关于userMapper具体接口的实现的一些问题:

4.编写测试类

五、select用法——多表查询

情景一:根据用户id获取用户拥有的所有角色

情景二:多表联结时查询多个表的字段组合

六、insert用法

1.基本用法

2.使用JDBC方式返回主键递增的值:

3.使用selectKey返回主键的值

七、update的用法

八、delete的用法

九、多个接口参数的用法——@Param注解



一、创建用户、角色和权限表

具体建表流程就不再赘述了,在Navicat客户端用图形界面手动添加就可以了,我们共需要创建五个表:用户表、角色表、权限表、用户角色关系表、角色权限关系表

这里我们并没有运用表和表之间的外键关系,为的是方便后面增删改查时的直接操作,但是表和表之间的关系我们也会以业务逻辑的形式来限制!

我们需要导入一些数据:

INSERT INTO `tbl_user` VALUES (1, 'admin', '123456', 'admin@qq.com', '管理员', NULL, '2019-11-07 20:11:29');
INSERT INTO `tbl_user` VALUES (2, '测试用户', '123456', 'test@qq.com', '测试用户', NULL, '2019-11-07 20:12:29');
INSERT INTO `tbl_role` VALUES (1, '管理员', 1, 1, '2019-11-07 20:13:26');
INSERT INTO `tbl_role` VALUES (2, '普通用户A', 1, 2, '2019-11-07 20:18:12');
INSERT INTO `tbl_role` VALUES (2, '普通用户B', 1, 2, '2019-11-08 11:34:40');
INSERT INTO `tbl_privilege` VALUES (1, '用户管理', '/users');
INSERT INTO `tbl_privilege` VALUES (2, '角色管理', '/roles');
INSERT INTO `tbl_privilege` VALUES (3, '系统日志', '/logs');
INSERT INTO `tbl_privilege` VALUES (4, '人员维护', '/persons');
INSERT INTO `tbl_privilege` VALUES (5, '单位维护', '/companies');
INSERT INTO `tbl_user_role` VALUES (1, 2);
INSERT INTO `tbl_user_role` VALUES (1, 3);
INSERT INTO `tbl_user_role` VALUES (1001, 2);
INSERT INTO `tbl_role_privilege` VALUES (1, 3);
INSERT INTO `tbl_role_privilege` VALUES (1, 3);
INSERT INTO `tbl_role_privilege` VALUES (1, 2);
INSERT INTO `tbl_role_privilege` VALUES (2, 4);
INSERT INTO `tbl_role_privilege` VALUES (2, 5);

终于Copy完毕!

到此,我们数据库的工作就做好了

二、创建实体类

我们这里要把五张对应表格的实体类建立在之前的model包里,我们只介绍一个表,其他仿照即可,不再赘述

package com.mybatis.api.model;
import lombok.Data;
import java.util.Date;
@Data
public class User {private Long id;private String userName;private String passWord;private String email;private String slogn;private String avatar;private Date createTime;}

三、使用XML方式

关于这个配置我真的时心情糟透了,因为手动配置XML文件什么感觉呢?就像:

因为Mybatis中其实有自动生成XML文件的工具——Mybatis Generator(MyBatis代码生成器 MBG)现在因为咱们修仙等级还比较低无法给大家详细的介绍

你似乎没有忘记,在第一话的时候,我们调用XML文件的时候用的是sqlSession通过命名空间调用MyBatis方法,非常的麻烦,在实际项目中,我们都是利用MyBatis3.0里面的接口来调用方法,省去了很多代码;

好吧!既然我们只能手动创建就按照第一话的方法勉为其♂来创建五个表对应的MyBatis文件把!创建位置:src/main/resources下面的com.mybatis.api.mapper下,同时在src/main/java下面的com.mybatis.api.mapper下写上对应的接口实现类,注意搞清位置哦!我们这里还是以一个User表对应的XML配置文件和接口实现类为例!

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--   namespace定义了当前XML的命名空间-->
<mapper namespace="com.mybatis.api.mapper.UserMapper"></mapper>

对应的接口实现类:

package com.mybatis.api.mapper;public interface UserMapper {}

我们准备好五个表的配置文件和实现类后,我们要把UserMapper等五个类在mybatis-config.xml中配置在<mappers>下

    <mappers><mapper resource="com.mybatis.api.mapper\StudentMapper.xml"/><mapper resource="com.mybatis.api.mapper\UserMapper.xml"/><mapper resource="com.mybatis.api.mapper\RoleMapper.xml"/><mapper resource="com.mybatis.api.mapper\PrivilegeMapper.xml"/><mapper resource="com.mybatis.api.mapper\RolePrivilegeMapper.xml"/><mapper resource="com.mybatis.api.mapper\UserRoleMapper.xml"/></mappers>

到此所有的文件都创建好啦 如下:

四、select用法——单表查询

其实前面仅仅是一个基础配置,重头戏在后面呢,现在就让我们尝试实现数据库的select查询,如果说关于select的配置你狗了解了,那么后面的增删改也会变得更加容易一些。下面我们就以userMapper中的数据查询来做简单的介绍:

1.配置UserMapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--   namespace定义了当前XML的命名空间 MyBatis就是根据这个值将接口和Url联系起来的-->
<mapper namespace="com.mybatis.api.mapper.UserMapper"><resultMap id="userMap" type="com.mybatis.api.model.User"><id property="id" column="id"/><result property="userName" column="user_name"/><result property="passWord" column="password"/><result property="email" column="email"/><result property="avatar" column="avatar"/><result property="createTime" column="create_time"jdbcType="TIMESTAMP"/></resultMap>
<!--    查询某个用户的全部信息--><select id="selectById" resultMap="userMap">select * from tbl_user where id = #{id}</select>
<!--    查询所有user的所有信息--><select id="selectAll" resultType="com.mybatis.api.model.User">select * from tbl_user</select></mapper>

2.写出对应的接口类

package com.mybatis.api.mapper;
import com.mybatis.api.model.User;
public interface UserMapper {User selectById(Long id);List<User> selectAll();
}

3.关于userMapper具体接口的实现的一些问题:

(1)接口中的方法和XML文件怎么实现关联的呢?

XML中的select标签中的id属性值和定义的接口方法名是一样的。MyBatis就是通过这种方法将接口中的方法和定义中的SQL语句关联到一起。另外,因为接口中的方法是可以重载的,所以接口中可以出现多个同名但参数不同的方法,但是XML中的id是不可以重复的,所以接口中的所有方法发会对应着XML中的同一个id的方法

(2)select怎么实现值的传参的?

我们可以看到select语句后面出现“id=#{id}”,意思就是,这个id是由用户传进去的,这是MyBatis常见的传参方式

(3)resultMap标签是干嘛的?作用是什么?

resultMap主要用于配置Java对象的属性和查询结果列对应的关系,通过ResultMap中的配置colunm和property可以将查询列的值映射到type对象的属性上,当我们使用sql语句的时候,MyBatis就可以正确地把结果映射到User对象上。

(4)两个sql语句为什么一个返会的是User一个是List<User>呢?

第一个传参的方法返回的是查询某个用户的所有信息,查处结果仅仅是某条用户的信息;第二个方法则是查询整个User表返回,返回一个List显而易见咯;

(5)为什么两个查询方法,一个是resultMap,一个是resultType?什么区别呢?

不难发现,resultMap我们使用了别名,当使用resultMap做SQL语句返回结果类型处理时,通常需要在mapper.xml中定义resultMap进行pojo和相应表字段的对应;resultMap对于一对一表连接的处理方式通常为在主表的pojo中添加嵌套另一个表的pojo,然后在mapper.xml中采用association节点元素进行对另一个表的连接处理。

详细介绍请戳>>>>>这里

4.编写测试类

在第一话我们已经创建完毕一个测试类StudentMapperTest,显然我们可能还需要建立更多的类似的测试类,因此,我们可以利用java中的继承和封装来对代码进行进一步处理

(1)创建一个基础类 BaseMapperTest,然后其他测试类去继承这个基础类

package com.mybatis.api.mapper;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.BeforeClass;import java.io.IOException;
import java.io.Reader;public class BaseMapperTest {private static SqlSessionFactory sqlSessionFactory;@BeforeClasspublic static void init(){Reader reader = null;try {//Resources工具类将mybatis-config.xml读入Readerreader = Resources.getResourceAsReader("mybatis-config.xml");//通过SqlSessionFactoryBuilder建造类使用Reader创建SqlSessionFactory工厂对象sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);reader.close();} catch (IOException e) {e.printStackTrace();}}public SqlSession getSqlSession(){return  sqlSessionFactory.openSession();}
}

(2)第一话中我们创建好的StudentMapperTest类去继承BaseMapperTest类

package com.mybatis.api.mapper;
import com.mybatis.api.model.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;public class StudentMapperTest extends BaseMapperTest{@Testpublic void testSelectAll(){//通过sqlSessionFactory对象获取一个sqlSessionSqlSession sqlSession = getSqlSession();//查找到StudentMapper中的id="selectAll"方法,执行SQL查询List<Student> students  = sqlSession.selectList("selectAll");printStudentList(students);//一定要关闭,否则会因为连接没有关闭导致数据库连接次数过多,造成系统的崩溃sqlSession.close();}private void printStudentList(List<Student> students){for (Student student:students){System.out.printf("%4d%4s%4d%4s\n",student.getId(),student.getName(),student.getAge(),student.getGender());}}
}

(3)同样的方法,我们创建我们即将用到的UserMapperTest类

package com.mybatis.api.mapper;import com.mybatis.api.model.User;
import org.apache.ibatis.session.SqlSession;
import org.junit.Assert;
import org.junit.Test;import java.util.List;public class UserMapperTest extends BaseMapperTest{@Testpublic void testSelectById(){//获取sqlSessionSqlSession sqlSession = getSqlSession();//获取UserMapper接口UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//调用selectById方法,查询用户id=1的用户User user = userMapper.selectById(1l);//user不为空Assert.assertNotNull(user);//userName = adminAssert.assertEquals("admin" , user.getUserName());//不要忘记关闭sqlSessionsqlSession.close();}@Testpublic void testSelectAll(){SqlSession sqlSession = getSqlSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//调用selectAll方法查询所有的用户List<User> users = userMapper.selectAll();//结果不为空Assert.assertNotNull(users);//用户数量大于0个Assert.assertTrue(users.size()>0);//不要忘记关闭sqlSessionsqlSession.close();}
}

(4)运行结果分别如下:

DEBUG [main] = ==>  Preparing: select * from tbl_user where id = ?
DEBUG [main] = ==> Parameters: 1(Long)
TRACE [main] = <==    Columns: id, user_name, password, email, slogn, avatar, create_time
TRACE [main] = <==        Row: 1, admin, 123456, admin@qq.com, 管理员, null, 2019-11-07 20:11:29.0
DEBUG [main] = <==      Total: 1
DEBUG [main] = ==>  Preparing: select * from tbl_user
DEBUG [main] = ==> Parameters:
TRACE [main] = <==    Columns: id, user_name, password, email, slogn, avatar, create_time
TRACE [main] = <==        Row: 1, admin, 123456, admin@qq.com, 管理员, null, 2019-11-07 20:11:29.0
TRACE [main] = <==        Row: 2, 测试用户, 123456, test@qq.com, 测试用户, null, 2019-11-07 20:12:29.0
DEBUG [main] = <==      Total: 2

至此。关于select的最基本单表查询已经实现了!

这时候我们就要拥有一种迎♂而上的精神,深入发掘新的世界!

好啦!那我们开始吧!

五、select用法——多表查询

情景一:根据用户id获取用户拥有的所有角色

首先,我们在userMapper里面增加方法(别告诉我你不知道在哪儿!)

List<Role> selectRolesByUserId(Long userId);

我们可以先把SQL语句写在Navicat进行测试,如下:

然后,对应的我们在userMapper.ml下添加代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--   namespace定义了当前XML的命名空间 MyBatis就是根据这个值将接口和Url联系起来的-->
<mapper namespace="com.mybatis.api.mapper.UserMapper"><resultMap id="userMap" type="com.mybatis.api.model.User"><id property="id" column="id"/><result property="userName" column="user_name"/><result property="password" column="password"/><result property="email" column="email"/><result property="avatar" column="avatar"/><result property="createTime" column="create_time"jdbcType="TIMESTAMP"/></resultMap>
<!--    查询某个用户的全部信息--><select id="selectById" resultMap="userMap">select * from tbl_user where id = #{id}</select>
<!--    查询所有user的所有信息--><select id="selectAll" resultType="com.mybatis.api.model.User">select * from tbl_user</select><select id="selectRolesByUserId" resultType="com.mybatis.api.model.Role">SELECTtu.id,tu.user_name,tr.role_name,tr.enabled,tr.create_by,tr.create_time
FROMtbl_user tuINNER JOIN tbl_user_role tur ON tu.id = tur.user_idINNER JOIN tbl_role tr ON tur.role_id = tr.id
WHEREtu.id = #{userId}</select>
</mapper>

同样的,我们在UserMapperTest中编写测试类

@Testpublic void testSelectRolesByUserId() {//获取sqlSessionSqlSession sqlSession = getSqlSession();//获取UserMapper接口UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//调用selectById方法,查询用户id=1的用户List<Role> roles= userMapper.selectRolesByUserId(1l);//user不为空Assert.assertNotNull(roles);//用户数量大于0个Assert.assertTrue(roles.size()>0);//不要忘记关闭sqlSessionsqlSession.close();}

测试结果:

DEBUG [main] = ==>  Preparing: SELECT tu.id, tu.user_name, tr.role_name, tr.enabled, tr.create_by, tr.create_time FROM tbl_user tu INNER JOIN tbl_user_role tur ON tu.id = tur.user_id INNER JOIN tbl_role tr ON tur.role_id = tr.id WHERE tu.id = ?
DEBUG [main] = ==> Parameters: 1(Long)
TRACE [main] = <==    Columns: id, user_name, role_name, enabled, create_by, create_time
TRACE [main] = <==        Row: 1, admin, 普通用户B, 1, 2, 2019-11-08 11:34:40.0
TRACE [main] = <==        Row: 1, admin, 普通用户A, 1, 2, 2019-11-07 20:18:12.0
DEBUG [main] = <==      Total: 2

其实这里和前面的SQL的查询没有什么不同,仅仅是SQL语句的区别,所以如果你之前对SQL就有很大程度的了解,那么这个对你来说难度就很小了!其实情景二也是这样

情景二:多表联结时查询多个表的字段组合

前面我们已经多表连接查询的基本测试,但是我们select后面的数据都是一个表格里的属性,那如果我们需要获得多个表的属性并返回结果呢?比如:我们要查询role表中的所有字段,加上对应的user表中对应的字段;

(1)改写情景一的SQL语句

<select id="selectRolesByUserId" resultType="com.mybatis.api.model.Role">SELECTtr.id,tr.role_name,tr.enabled,tr.create_by,tr.create_time, tu.user_name,tu.email
FROMtbl_user tuINNER JOIN tbl_user_role tur ON tu.id = tur.user_idINNER JOIN tbl_role tr ON tur.role_id = tr.id
WHEREtu.id = 1
</select>

(2)然后直接运行我们情景一的测试类就可以了

DEBUG [main] = ==>  Preparing: SELECT tr.id, tr.role_name, tr.enabled, tr.create_by, tr.create_time, tu.user_name, tu.email FROM tbl_user tu INNER JOIN tbl_user_role tur ON tu.id = tur.user_id INNER JOIN tbl_role tr ON tur.role_id = tr.id WHERE tu.id = 1
DEBUG [main] = ==> Parameters:
TRACE [main] = <==    Columns: id, role_name, enabled, create_by, create_time, user_name, email
TRACE [main] = <==        Row: 3, 普通用户B, 1, 2, 2019-11-08 11:34:40.0, admin, admin@qq.com
TRACE [main] = <==        Row: 2, 普通用户A, 1, 2, 2019-11-07 20:18:12.0, admin, admin@qq.com
DEBUG [main] = <==      Total: 2

到此为止,我们已经把SELECT的最基本的查询功能介绍了,需要改写查询的结果,其实最重要的一点就是对XML文件中的SQL语句进行改写,当我们SELECT的需求改变时,只需要对SQL语句进行更改即可!

六、insert用法

1.基本用法

个人觉得,这是最简单的一种用法,其实在文章的开头,我们用sql语句进行数据的增添时就已经用到了insert,那么,我们怎么在代码里面通过传参的形式去insert数据呢?很简单的啦.......

好啦,停下来吧,我们 继续学习!

(1)在UserMapper下添加方法如下

public interface UserMapper {User selectById(Long id);List<User> selectAll();List<Role> selectRolesByUserId(Long userId);
//添加 insret方法int insert(User user);
}

(2)在UserMapper.xml中添加如下代码:

   <insert id="insert">INSERT INTO tbl_user ( id, user_name, password, email, slogn, avatar, create_time )
VALUES(#{id} ,#{userName},#{password},#{email},#{slogn},#{avatar},#{createTime,jdbcType=TIMESTAMP})</insert>

这里有可能会有宝宝提出!为啥你的createTime字段传参的形式和别人不一样呢?多了一个jdbcType=TIMESTAMP?这是因为对于一些特殊的数据类型,为了防止错误,我们通常建议指定具体的jdbcType值,而且,对于这里,我们指定不同的日期类型,最终返回的日期类型也会不同;

你可以尝试其他类型如:数据库分为:date,time,datetime对应的JDBC类型分别为:DATE ,TIME,TIMESTAMP

(3)编写测试类

@Testpublic void testInsert(){SqlSession sqlSession = getSqlSession();try{UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//创建一个user对象User user = new User();user.setUserName("test1");user.setPassword("123456");user.setEmail("test1@qq.com");user.setSlogn("测试1");user.setAvatar(null);user.setCreateTime(new Date());//将新建的对象插入数据库中(注意这里的返回值result是执行SQL影响的行数)int result = userMapper.insert(user);//只插入一条数据Assert.assertEquals(1,result);//id为null,没有给id赋值,并且没有配置回写id的值Assert.assertNotNull(user.getId());}finally {//为了不影响其他测试,这里选择回滚sqlSession.rollback();//不要忘记关闭sqlSessionsqlSession.close();}}

运行如果报错:

Fri Nov 08 21:20:50 CST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification

翻译:请注意:不建议在没有服务器身份验证的情况下建立SSL连接。根据MySQL 5.5.45+、5.6.26+和5.7.6+的要求,如果不设置显式选项,则必须建立默认的SSL连接。您需要通过设置useSSL=false显式地禁用SSL,或者设置useSSL=true并为服务器证书验证提供信任存储

请在myabatis-config.xml中的JDBC连接的地方,改写成:

 <property name="url" value="jdbc:mysql://localhost:3306/user?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"/>

运行测试类结果:


DEBUG [main] = ==>  Preparing: INSERT INTO tbl_user ( id, user_name, password, email, slogn, avatar, create_time ) VALUES (? ,?,?,?,?,?,?)
DEBUG [main] = ==> Parameters: null, test1(String), 123456(String), test1@qq.com(String), 测试1(String), null, 2019-11-08 17:53:20.224(Timestamp)
DEBUG [main] = <==    Updates: 1

虽然类是测试成功了,但是当我们的主键自增没有实现哇

原来我们没有实现返回主键递增的值,输出id,从运行结果不难看出主键值并没有递增,而是为null!

2.使用JDBC方式返回主键递增的值:

现在,我们来增加一个insert2方法,同样的步骤:

(1)在UserMapper下添加方法如下:

    int insert2(User user);

(2)在UserMapper下配置如下:

<insert id="insert2" useGeneratedKeys="true" keyProperty="id">INSERT INTO tbl_user ( id, user_name, password, email, slogn, avatar, create_time )
VALUES(#{id} ,#{userName},#{password},#{email},#{slogn},#{avatar},#{createTime,jdbcType=TIMESTAMP})</insert>

不难发现与上一次相比,这次代码加入了useGeneratedKeyskeyProperty两个属性

useGeneratedKeys:默认值为false,如果设置为true,MyBatis会使用JDBC的getGeneratedKeys方法来取出数据库内部生成的主键;

keyProperty:MyBatis使用JDBC的getGeneratedKeys方法获得主键值后,将值赋给keyProperty里的属性;

(3)我们加入输出方法,多次运行测试方法,发现id已经实现递增!

 System.out.println(user.getId());

3.使用selectKey返回主键的值

我们知道MySQL本身是支持主键自增的,但是对与其他数据库比如Oracle,它就不支持主键自增的功能,而是使用序列获得一个值然后将这个值赋给id,最后插入数据库!卧槽,好麻烦,是不是?当然,MyBatis也有相应的解决办法,那就是<selectKey>标签,适用于不提供自增的数据库。

可是俺不懂Orcle哈哈哈。。。。

那我们就简单看看它在MyBatis下怎么使用的吧!

    <insert id="insert3">INSERT INTO tbl_user ( id, user_name, password, email, slogn, avatar, create_time )
VALUES(#{id} ,#{userName},#{password},#{email},#{slogn},#{avatar},#{createTime,jdbcType=TIMESTAMP})<selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">SELECT LAST_INSERT_ID()</selectKey></insert>

和之前的insert2的配置比较一下,我们就不难看出他们的不同之处:resultType

keyColumn:仅对INSERT和UPDATE有用,通过生成的键值来设计表中列名;

resultType:设置返回值的类型;

order="AFTER" :      order后面的属性与数据库有关,属性是AFTER还是BEFORE关键是看“主键的值是在insert语句执行成功前还是成功后才获取的”,对的,你猜对了,对于MyBatis后面的属性是AFTER;而对于Oracle则是BEFORE;

至于测试结果,我们写了好多了,就不赘述辽!

七、update的用法

顾名思义,uodate就是用来更新数据库数据的!就是:“改” 咯,废话不说,上代码!

(1)在UserMapper下添加方法如下:

    int updateById(User user);

(2)在UserMapper下配置如下:

    <update id="updateById">UPDATE tbl_user
SET user_name = #{userName},password = #{password},email = #{email},slogn = #{slogn},avatar = #{avatar},create_time = #{createTime,jdbcType=TIMESTAMP}
WHEREid = #{id}</update>

(3)编写测试类

 @Testpublic void testUpdateById(){SqlSession sqlSession = getSqlSession();try{UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//从数据库查询到user对象:adminUser user = userMapper.selectById(1l);Assert.assertEquals("admin" ,user.getUserName());//修改用户名和邮箱user.setUserName("admin_test");user.setEmail("admin_test@qq.com");//更新数据int result = userMapper.updateById(user);//只更新一条数据Assert.assertEquals(1,result);//根据id查寻修改过的数据user = userMapper.selectById(1l);//修改后的名字是admin_testAssert.assertEquals("admin_test",user.getUserName());}finally {//为了不影响其他测试类,这里选择数据的回滚sqlSession.rollback();//不要忘记关闭sqlSessionsqlSession.close();}}

输出结果:

DEBUG [main] = ==>  Preparing: select * from tbl_user where id = ?
DEBUG [main] = ==> Parameters: 1(Long)
TRACE [main] = <==    Columns: id, user_name, password, email, slogn, avatar, create_time
TRACE [main] = <==        Row: 1, admin, 123456, admin@qq.com, 管理员, null, 2019-11-07 20:11:29.0
DEBUG [main] = <==      Total: 1
DEBUG [main] = ==>  Preparing: UPDATE tbl_user SET user_name = ?,password = ?,email = ?,slogn = ?, avatar = ?,create_time = ? WHERE id = ?
DEBUG [main] = ==> Parameters: admin_test(String), 123456(String), admin_test@qq.com(String), 管理员(String), null, 2019-11-07 20:11:29.0(Timestamp), 1(Long)
DEBUG [main] = <==    Updates: 1
DEBUG [main] = ==>  Preparing: select * from tbl_user where id = ?
DEBUG [main] = ==> Parameters: 1(Long)
TRACE [main] = <==    Columns: id, user_name, password, email, slogn, avatar, create_time
TRACE [main] = <==        Row: 1, admin_test, 123456, admin_test@qq.com, 管理员, null, 2019-11-07 20:11:29.0
DEBUG [main] = <==      Total: 1

明显可以看出数据库中的admin的部分信息已经修改成功!

八、delete的用法

delete用法和update用法差不多,你还记得我们最开始建表的时候嘛,我们并没有采用建外键的形式来进行表与表之间的约束,就是为了delete这里介绍的时候可以更方便一些,如果说你删除的某一条数据它的子表有数据,那么就会报外键冲突的错误!类似下面这样的错误:

既然我们没有建外键,那么不废话了,LittleMan!Come on ! !♂

(1)在UserMapper下添加方法如下:

    int deleteById(Long id);

(2)在UserMapper下配置如下:

    <delete id="deleteById">DELETE FROM tbl_user WHERE id = #{id}</delete>

(3)编写测试类

    @Testpublic void testDeleteById(){SqlSession sqlSession =getSqlSession();try{UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//查询一个user对象User user = userMapper.selectById(1l);//此时该user对象还存在Assert.assertNotNull(user);//删除Assert.assertEquals(1,userMapper.deleteById(1l));//此时已经删除Assert.assertNull(userMapper.selectById(1l));}finally {sqlSession.rollback();sqlSession.close();}}

测试结果:

DEBUG [main] = ==>  Preparing: select * from tbl_user where id = ?
DEBUG [main] = ==> Parameters: 1(Long)
TRACE [main] = <==    Columns: id, user_name, password, email, slogn, avatar, create_time
TRACE [main] = <==        Row: 1, admin, 123456, admin@qq.com, 管理员, null, 2019-11-07 20:11:29.0
DEBUG [main] = <==      Total: 1
DEBUG [main] = ==>  Preparing: DELETE FROM tbl_user WHERE id = ?
DEBUG [main] = ==> Parameters: 1(Long)
DEBUG [main] = <==    Updates: 1
DEBUG [main] = ==>  Preparing: select * from tbl_user where id = ?
DEBUG [main] = ==> Parameters: 1(Long)
DEBUG [main] = <==      Total: 0

九、多个接口参数的用法——@Param注解

其实我们之前介绍的所有接口都是单一参数传参,如:delete。而update和insert的参数则是一个JavaBean类型,它们的XML文件中的SQL语句会有多个参数;

怎样使javaBeam呢?通常情况下,如果是传的参数数目比较多的,我们可以使用javaBean而且用起来也比较方便;但是如果说是仅仅传参个数是两到三个,就没必要了!

我们用什么呢?通常是使用Map类型和@Param注解!这里我们先举例介绍一下@Param注解:

情景:根据用户id和enable状态获得用户角色

我们先用原来的方法进行测试:

(1)在UserMapper下添加方法如下:

    List<Role> selectRolesByIdE(Long userId,Integer enable);

(2)在UserMapper下配置如下:

    <select id="selectRolesByIdE" resultType="com.mybatis.api.model.Role">
SELECT*
FROMtbl_user uINNER JOIN tbl_user_role ur ON u.id = ur.user_idINNER JOIN tbl_role r ON ur.role_id = r.id
WHEREu.id = #{userId} AND r.enabled= #{enabled}</select>

(3)编写测试类

 @Testpublic void testSelectRolesByIdE(){SqlSession sqlSession = getSqlSession();try{UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<Role> list = userMapper.selectRolesByIdE(1l,1);Assert.assertNotNull(list);Assert.assertTrue(list.size()>0);}finally {sqlSession.close();}}

结果报错:

Caused by: org.apache.ibatis.binding.BindingException: Parameter 'userId' not found. Available parameters are [0, 1, param1, param2]
    at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:168)
    at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:45)
    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)
    at org.apache.ibatis.executor.BaseExecutor.createCacheKey(BaseExecutor.java:212)
    at org.apache.ibatis.executor.CachingExecutor.createCacheKey(CachingExecutor.java:139)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120)
    ... 29 more
这个错误表示,XML可用的参数只有0、1、Param1、Param2,并没有userId,这四个值都是MyBatis根据参数的位置自定义的名字,因此,我们只要吧#{userId}改为#{0}或#{Param1},#{enable}改为#{1}或#{Param2}即可!但是!这不是很麻烦吗?只是后就用到了@Param注解。

我们只需改写一下UserMapper中的方法

  List<Role> selectRolesByIdE(@Param("userId") Long id,@Param("enabled") Integer enabled);

运行结果:

DEBUG [main] = ==>  Preparing: SELECT * FROM tbl_user u INNER JOIN tbl_user_role ur ON u.id = ur.user_id INNER JOIN tbl_role r ON ur.role_id = r.id WHERE u.id = ? AND r.enabled= ?
DEBUG [main] = ==> Parameters: 1(Long), 1(Integer)
TRACE [main] = <==    Columns: id, user_name, password, email, slogn, avatar, create_time, user_id, role_id, id, role_name, enabled, create_by, create_time
TRACE [main] = <==        Row: 1, admin, 123456, admin@qq.com, 管理员, null, 2019-11-07 20:11:29.0, 1, 3, 3, 普通用户B, 1, 2, 2019-11-08 11:34:40.0
TRACE [main] = <==        Row: 1, admin, 123456, admin@qq.com, 管理员, null, 2019-11-07 20:11:29.0, 1, 2, 2, 普通用户A, 1, 2, 2019-11-07 20:18:12.0
DEBUG [main] = <==      Total: 2

致谢!再次致谢刘增辉大佬的《MyBatis 从入门到精通》感谢!此处@刘增辉先生

Mybaits:凡人修仙秘籍——第二话:MyBatis 的增删改查相关推荐

  1. mybatis实现增删改查xml配置和后端Java编程完整教程

    mybatis实现增删改查xml配置和后端编程教程 SqlMapConfig.xml <?xml version="1.0" encoding="UTF-8&quo ...

  2. mybatis完整增删改查入门实例

    mybatis完整增删改查入门实例 编程步骤 ①创建Java工程. ②导入jar包. ③创建sqlMapConfig.xml配置文件,这是mybatis的入口. ④创建数据库,数据库表user_c,插 ...

  3. idea使用mybatis写增删改查

    idea应用mybatis写增删改查 entity层 private Integer id;private String userCode;private String userName;privat ...

  4. Spring+SpringMVC+Mybatis实现增删改查--(五)SSM修改员工页面搭建

    Spring+SpringMVC+Mybatis实现增删改查--(五)SSM修改员工页面搭建 修改员工: 1.在index.jsp页面点击"编辑"弹出编辑对话框 2.去数据库查询部 ...

  5. MyBatis的增删改查操作

    MyBatis的增删改查操作 简单实现一下MyBatis的增删改查,并且在控制台输出结果. 文章目录 MyBatis的增删改查操作 MyBatis的简单入门 一.查询操作 二.增加操作 三.修改操作 ...

  6. MyBatis实现增删改查功能(总)

    文章目录 MyBatis实现增删改查功能(总) 一.创建数据库.表.数据 二.MyBatis的Maven项目创建 三.MyBatis的Maven模块创建 四.配置jar包pom.xml 五.MyBat ...

  7. Mybatis实现增删改查

    文章目录 Mybatis实现增删改查 一.mybatis的配置 1.1 添加相应的jar包 1.2 配置mybatis.xml文件 1.3 创建数据库 1.4 创建实体类 1.5 创建接口实现的方法 ...

  8. springboot+springm vc+mybatis实现增删改查案例!

    大家好,我是雄雄,欢迎关注微信公众号[雄雄的小课堂]. 前言 最近这几天都在看关于springboot的内容,每天新会获得点新收获,并且都总结发在公众号中:最后经过不懈努力,不断查找相关网页,解决各种 ...

  9. (Mybatis)增删改查实现

    文章目录 namespace 增删改查 1. Select 2. Insert 3. Update 4. Delete 万能Map 模糊查询 namespace namespace一定要与mapper ...

最新文章

  1. 2020年春天故事之巧遇史上最奇葩SAP用户
  2. 前端那么多框架,我们到底学哪一个
  3. boost::math::tools::luroth_expansion用法的测试程序
  4. 推荐 10 本好书,并送上 110 本!
  5. 修改密码导致应用程序池无法启动
  6. war包发布找不见路径 weblogic getResource 与getRealPath
  7. Ubuntu Sublime Text 3 搜狗拼音
  8. 虚拟机linux gedit,Linux系统中把gedit改造成TextMate的方法
  9. 前端模拟数据(mock数据)的方法二:使用在线mock平台(fastmock)
  10. 喜马拉雅下载文件名批量修改
  11. 小说PHP最新源码,2019最新PTCMS小说精美多风格四套全新版源码+模板
  12. 数学建模模板(让你也能写论文的模板)
  13. 微信小程序开源源码汇总
  14. mysql插入微信名称中的特殊字符
  15. 频域处理:傅里叶变换及小波变换
  16. 腾讯云Ubuntu18.04配置OpenPCDet深度学习环境
  17. C++中类(class)和结构(struct)的区别
  18. 51单片机 AT24C04+蜂鸣器+Proteus仿真
  19. Python YouTube频道的终极清单
  20. Linux九阴真经之大伏魔拳残卷3(LVS)

热门文章

  1. 2023中国智慧医院建设、装备及应用展览会
  2. 我的世界哪个服务器有无限手套,我的世界:MC独有的六大源石代表生物,玩家:就差无限手套了...
  3. 2018 年春节总结
  4. 如何挖掘项目中的亮点(多方向带案例)
  5. 网络推广与策划心得,网络营销与策划的实践收获
  6. 《观远数据安全白皮书》首发,打开数据安全保护新思路
  7. IREP_SOA Integration SOAP概述(概念)
  8. 我对Backlog的理解
  9. Dreamweaver CS4序列号
  10. vs2010报错The ‘RadLangSvc.Package, RadLangSvc.VS, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89