高效开发:详解mybatis的select,insert,delete,update返回值。

Posted 爱奇志

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高效开发:详解mybatis的select,insert,delete,update返回值。相关的知识,希望对你有一定的参考价值。

select

User user = new User();
user.setName("l2");
user.setPassword("444");
int i =  userMapper.addUser(user);
System.out.println(i);
<select id="getUserById" parameterType="Integer" resultType="User">
    select * from t_user where id = #{id};
</select>

select的返回值没什么好说的,写的不是有resultType还有resultMap嘛,那就是返回值了。

User user = userMapper.getUserById(1);
System.out.println(user.toString());

测试的数据也比较简单。这个就没什么说的了。

insert

<insert id="addUser" parameterType="User">
    INSERT INTO `db_ssm`.`t_user` (`id`, `name`, `password`)
    VALUES
      (null, #{name}, #{password}) ;
</insert>

insert也比较简单,测试的贴上来。

User user = new User();
user.setName("l2");
user.setPassword("444");
int i =  userMapper.addUser(user);
System.out.println(i);

貌似也比较简单,也没什么说的了。

等等,好像忘记了本文的中心思想了,没错,说的就是insert。

insert 如果成功的话返回值是1,因为我只插入了一条数据。为什么要提数据的事呢,是因为据说这个insert返回的就是插入的数据的条数。如果插入多条数据的话…… 想入非非中。可能就不是1了啊。这个我就不试了,遇到的时候再试。

这是验证的结果。

那有的人要问了,如果插入出错了呢。

重新模拟插入错误的,

        User user = new User();
//        user.setName("l2222");
        user.setPassword("111");
        int i =  userMapper.addUser(user);
        System.out.println(i);

注释掉name,

在我的数据库中name是不可以为空的。

所以硬要插入的话肯定会出错的。下面演示结果。

华丽的出错了,瞬间把我原来以为结果会是0的想法冲击的粉碎。

正是我想要的结果。

所以

insert 的结果,如果成功返回的是1(可能是这个1是影响的条数),失败返回的是exception,而不是0。

身为社会有识青年,怎么能容忍异常的呢。我先简单的处理一下。

User user = new User();
user.setPassword("33333");
int i = 0;
try {
    i = userMapper.addUser(user);
} catch (Exception e) {
    i = -1;
} finally {
}
System.out.println(i);

这样一搞,如果插入成功的话返回的是1,如果不成功的话返回的是-1。

岂不妙哉,我都佩服自己的聪明才智了。但是我不能排除有没有可能返回0,所有如果返回的数字不小于1判定为插入成功。

但是一般情况下,我们插入成功了,就要在页面上马上用ajax展示出来。但是遗憾的是,我们的这个user怎么能没有id呢,没有id有怎么查,怎么删,怎么改。所以我们在插入的时候要是可以得到id就更好了。

<insert id="addUser1" parameterType="User" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO `db_ssm`.`t_user` (`id`, `name`, `password`)
    VALUES
      (null, #{name}, #{password}) ;
</insert>

看到后面 的两个数据了吗?

(1) useGeneratedKeys=“true” 这是必须的。
(2) keyProperty=“id” 这是id就是绑定的id,那我就疑惑了,这绑定的哪个id啊。令人头疼。你这个返回值明明是int,难道返回的就是这个id。

这个先看测试的文件

User user = new User();
user.setName("1222");
user.setPassword("44122224");
int i = 0;
try {
    i = userMapper.addUser1(user);
    sqlSession.commit();
} catch (Exception e) {
    System.out.println("add error");
} finally {
}
System.out.println(user.toString());
 
System.out.println(i);

看到这到是明白了,原来不是把id当成返回值啊,原来它是把

parameterType=“User” 这是user的id设置成了插入的id。

进来的是没有id的user,出去的是有id的user,真是太厉害了,没想到不仅把返回值改变了,连参数都发生了改变,真是太神奇了。亮瞎了我眼。这思想的境界之高,我等真是不能望其项背。

返回值还是插入的条数。

哦,弄到这,mybatis插入的返回值我是了解的差不多了。

insert报错1:外键约束(插入从表,主表中没有对应数据)

错误:插入从表,主表中没有对应数据
正确姿势:先插入主表,再插入从表

ica_classify 表中主键 ica_classify_id 为 website_commodity_information 表的外键

表结构略

在使用mybatis往表website_commodity_information 中插入数据的时候,外键约束报错

### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`cweb/website_commodity_information`, CONSTRAINT `website_commodity_information_ibfk_3` FOREIGN KEY (`ica_classify_id`) REFERENCES `ica_classify` (`ica_classify_id`) ON UPDATE CASCADE)

这个问题遇到了两次,这次长点记性记录一下

插入数据时website_commodity_information表中的`ica_classify_id的值

必须是与ica_classify表中某一主键相对应,否则就会报错。

这块因为只注意到一个表 没注意到关联表没有数据所以出现了问题

delete

<delete id="deleteUser" parameterType="Integer" >
    delete from t_user where id = #{id}
</delete>

我先找个你肯定删不掉的为难你

int i = 0;
try {
    i = userMapper.deleteUser(222222);
    sqlSession.commit();
} catch (Exception e) {
    System.out.println("delete error");
} finally {
}
System.out.println(i);

我让你删id是222222的,我还没创建呢,看你怎么删

删不掉的就返回个0啊,好简单,为什么 不说This can’t be deleted,一点都不智能。

int i = 0;
try {
    i = userMapper.deleteUser(14);
    sqlSession.commit();
} catch (Exception e) {
    System.out.println("delete error");
} finally {
}
System.out.println(i);

那试试正常的id= 14

哦,删除正常的返回是1。

delete删除外键约束报错(删除主表,从表中依赖这行数据)

错误:删除主表,从表中依赖这行数据
正确姿势:先删除从表依赖的这个数据行的记录,然后才能删除主表中这个数据行

例子1

我给你个删都删不动的,你怎么搞。

如果删有外键约束的会报错。哈哈哈。

FK_test FOREIGN KEY (name) REFERENCES t_user (name)

例子2

定义了外键,就是给俩个表建立联系,删除的时候,数据库会会查看删除的数据会不会导致表结构的破坏,若会破坏,则不能删除。

解决办法,将外键屏蔽
设置如下:SET FOREIGN_KEY_CHECKS = 0;
具体例子:

这个是俩个表的结构,test3关联了test2的id主键。

当直接删除test2_id = 1 的数据,因为会test3中含有test2_id = 1的数据,删除时报异常。
先设置在删除,就可以了,删除后记得在设置回来。

update

写到这已经累了,不想写了,但是还有一点,赶紧写完得了。

<update id="updateUser" parameterType="User">
    update t_user set name = #{name}, password = #{password} where id = #{id}
</update>

测试 成功

User user = new User();
user.setId(9);
user.setName("121111");
user.setPassword("11111");
int i = 0;
try {
    i = userMapper.updateUser(user);
    sqlSession.commit();
} catch (Exception e) {
    System.out.println("delete error");
} finally {
}
System.out.println(i);

成功是1,失败是0

update修改外键约束报错(修改主表,从表中依赖这行数据)

错误:修改主表,从表中依赖这行数据
正确姿势:先删除从表依赖的这个数据行的记录,然后才能修改主表中这个数据行

错误是异常

总结

成功是1,失败是0,错误是异常。一定要捕捉异常。不然项目就崩了。

selectinsertdeleteupdate
能找到,满足where条件model返回影响行数1返回影响行数1返回影响行数1
找不到,不满足where条件null不存在这种情况返回影响行数0返回影响行数0
报错(sql层面的错误)不存在这种情况主键冲突、唯一索引冲突、非空字段未赋值、外键约束报错(插入从表,主表中存在这个值)外键约束报错(删除主表,从表中存在引用这个数据行)外键约束报错(修改主表,从表中存在引用这个数据行)

以上是关于高效开发:详解mybatis的select,insert,delete,update返回值。的主要内容,如果未能解决你的问题,请参考以下文章

在mybatis的@Select中用not in 时

Mybatis 注解开发传入List 两种方式接收方式 在IN场景中

Mybatis 教程之Mybatis注解开发

select-sql语句in的用法,在mybatis中sql中in是怎么用的

mybatis-plus @Select select in 查询实现

Mybatis的@Select注解怎么在没有xml文件时使用in查询,