Mybatis的增删改查

Mybatis的增删改查

  • 本人独立博客:https://chenjiabing666.github.io/

增长数据<insert>

  • 在增长数据的时候,mybatis默认返回的是受影响的行数,所以不须要指定ResultType指定返回类型
  • UserMapper.java接口中添加方法
/**
    @param user User对象
*/
Integer reg(User user);
  • UserMapper.xml文件中添加<insert>节点java

    • #{}中填写的是User对象的属性名称

<!-- 节点名称取决于须要执行的操做 -->
    <!-- 例如增长操做应该使用insert节点 -->
    <!-- id属性(*)的值是Java接口中的方法名称 -->
    <!-- parameterType属性的值是参数类型 
    -->
    <!-- 节点中间编写SQL语句 -->
    <insert id="reg"
        parameterType="cn.tedu.spring.entity.User">
        INSERT INTO user (
            username, password
        ) VALUES (
            #{username}, #{password}
        )
    </insert>
  • 测试
@Test
    public void testReg() {
        //加载Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //获取UserMapper的bean,这个是spring经过扫描mapper.xml文件自动为mybatis自动建立的,首字母小写
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        
        //新建User对象
        User user = new User();
        user.setUsername("Tom1");
        user.setPassword("123456");
        
        //调用reg(user),进行添加,返回的是受影响的行数
        Integer affectedRows
            = userMapper.reg(user);
        
        System.out.println(
            "affectedRows=" + affectedRows);
        ac.close();
    }

在Mybatis中增长数据时获取自增主键的id

  • 首先mybatis在处理增长数据的功能时,只是返回受影响的行数,因此在持久层中并不会返回新增长的
  • 若是须要获取自增主键Id,首先,在XML映射的<insert>节点中须要添加2个属性
    • useGeneratedKeys :设置是否返回自增主键,若是为true则返回,默认为false
    • keyProperty : 配置自增主键在表中对应的字段 ,由于有时候在表中的自增主键的字段可能不是id,所以须要指定
<!-- 节点名称取决于须要执行的操做 -->
    <!-- 例如增长操做应该使用insert节点 -->
    <!-- id属性(*)的值是Java接口中的方法名称 -->
    <!-- parameterType属性的值是参数类型 
        useGeneratedKeys: 指定是否返回自增主键,默认为false
        keyProperty:配置自增主键在表中对应的字段 
    -->
    <insert id="reg"
        parameterType="cn.tedu.spring.entity.User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (
            username, password
        ) VALUES (
            #{username}, #{password}
        )
    </insert>
  • 此时的mybatis执行insert方法以后,便是调用reg(user),返回的仍是受影响的行数,并非此时的自增主键id的值。而是在调用这个方法的时候将id封装到指定的方法参数中,便是封装到user中了,所以只有调用者才能够获取id,而持久层没法获取
@Test
    public void testReg() {
        //加载Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //获取UserMapper的bean,这个是spring经过扫描mapper.xml文件自动为mybatis自动建立的,首字母小写
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        
        //新建User对象,此时并无设置id的值
        User user = new User();
        user.setUsername("Tom1");
        user.setPassword("123456");
        
        //调用reg(user),进行添加,返回的是受影响的行数,可是此时已经将id封装到参数User对象中了
        Integer affectedRows
            = userMapper.reg(user);
        
        System.out.println(
            "affectedRows=" + affectedRows);
        //直接获取Uesr对象中的id值,这个是自增主键返回的值
        System.out.println("id = "+user.getId());
        ac.close();
    }

删除数据<delete>

  • 在删除数据的时候,自动会返回受影响的行数,不须要在delete节点中定义返回类型,只有在查询数据的时候才会定义返回类型git

  • UserMapper.java中添加一个接口方法github

//根据id删除数据,返回受影响的行数,返回1,若是删除失败返回0
    Integer deleteUserById(int id);
  • UserMapper.xml中配置<delete>节点
<!-- 删除用户数据根据id
        Integer deleteUserById(int id)
        parameterType: 指定参数类型,这里也能够不须要指定
     -->
    <delete id="deleteUserById" parameterType="int">
        delete from user where id=#{id}
    </delete>
  • 删除数据是不可逆的,一般不会真正的删除数据,咱们会使用备份,日志等手段来保存数据,在许多软件上看到的删除也许都是修改操做,一般在表中有一个字段is_deleted标记是否删除,若是执行删除,那么就会设置其值为true表示已经删除了,那么此时将不会显示在客户端,让客户觉得已经被删除了

Mybaits参数规则

  • mybatis默认支持一个参数,便是定义的接口方法中只能有一个参数
  • 若是须要支持多个参数,那么须要使用@Param()注解
  • 若是接口方法中的参数类型是基本类型的能够不用parameterType指定类型,若是不是基本类型的,规范要求须要使用parameterType指定类型,可是能够不写

@Param()

  • mybatis默认支持一个参数,便是定义的接口方法中只能有一个参数
  • 在设计java接口方法时,若是须要指定多个参数,那么必须使用@Param()
  • 若是想要支持多个参数,须要使用@Param()来指定参数,好比Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
    • 其中@Param("key")中的value在配置增删改查的时候是使用#{key}表达式取出的
  • mybaits在处理过程当中,本质上是使用了Map对参数进行了封装的。便是@Param("")注解中给出的参数值是Map中的key,调用方法时给出的参数值是Map中的value值,而最终在XML文件中使用#{}获取值,实际上是使用Map中的get(key)方法获取的

修改数据<update>

  • 在修改数据的时候,mybatis自动返回受影响的行数,所以咱们不须要定义返回类型,默认的返回数据就是受影响的行数spring

  • UserMapper.java接口中定义根据id修改数据的方法spring-mvc

    • 使用@Param()注解来标记多个参数

/**
     * 修改密码
     * @param id  id
     * @param newPassword  新密码
     * @return  受影响的行数
     */
    Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
  • UserMapper.xml中添加<update>节点mybatis

    • 其中#{}表达式中的字段为@Param("value")中的value

<!-- 修改密码
        Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
     -->
    <update id="ChangePassword">
        update user set password=#{newPassword} where id=#{id}
    </update>
  • 测试方法
@Test
    public void testChangePassword() {
        //加载Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //获取UserMapper的bean,这个是spring经过扫描mapper.xml文件自动为mybatis自动建立的,首字母小写
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        //调用删除的方法
        int affectRow=userMapper.ChangePassword(3, "12345895");
        System.out.println(affectRow);
        ac.close();
    }

案例:修改用户密码

用户提供数据

  • 旧密码:oldPassword
  • 新密码:newPassword

步骤

  1. 经过id查找用户信息
    1. 不可使用select * from user where id=? and password=?,由于这个是不区分大小写的,咱们应该先根据id获取用户信息,再比较password
    2. UserserviceImpl中完成验证逻辑,若是用户不存在,那么抛出用户不存在的异常,若是存在就验证原密码和是否匹配
  2. 用户信息存在,那么就要验证用户输入的oldPassword和用户信息中的原密码是否相同了,若是不相同,抛出密码不匹配的异常,若是相同,那么就能够修改密码
  3. 修改密码

实现

  • 咱们编写了一个UserService中编写逻辑
public void ChangePasssword(Integer id, String oldPassword,
            String newPassword) throws UserNotFoundException, PasswordNotMatchException{
        User user=this.findUserById(id);  //获取用户信息
        if (user==null) {   //若是用户信息不存在
                throw new UserNotFoundException("操做失败,用户信息不存在");
        }else { //用户存在,则判断原密码
            if (user.getPassword().equals(oldPassword)) {//若是密码匹配
                
                userMapper.ChangePassword(id, newPassword);  //修改密码
            }else {   //原密码不匹配
                    throw new PasswordNotMatchException("操做失败,原密码不正确");
            }
        }
    }
  • 那么在Controller中若是要调用这个ChangePasssword将会经过处理异常来判断哪里是出错了,并给出友好的提示

查询数据<select>

单条数据的查询

  • 根据id的查询返回的查询结果就是单条数据,好比:select * from user where id=1
  • 单条记录的查询在编写接口方法的时候,只须要返回一个实体类对象便可
/**
     * 根据id查询用户信息
     * @param id  用户id
     * @return 返回User对象
     */
    User findUserById(Integer id);
  • UserMapper.xml中配置<select>节点
    • 须要使用resultType指定返回的类型,由于参数是基本类型,所以不须要使用parameterType指定参数类型
<select id="findUserById" resultType="cn.tedu.spring.entity.User">
        select * from user where id=#{id}
    </select>

多条记录的查找

  • 有些查找语句返回的是多条记录,那么咱们可使用List<>集合来接收返回的结果,不能直接使用实体类对象来接收
  • UserMapper.java中定义接口方法
/**
     * 根据密码查找用户
     * @param password 用户密码
     * @return 返回的是一个用户的集合
     */
    List<User> findUserByPassword(String password);
  • UserMapper.xml中添加<select>节点
    • 这里的resultType虽然返回的是User集合,可是这里的类型仍是须要写User类型
    • 因为参数是基本类型,所以不须要使用parameterType
<!-- 
        List<User> findUserByPassword(String password);
        resultType: 虽然返回的是User集合,可是这里的类型仍是须要写User类型
     -->
     
     <select id="findUserByPassword" resultType="cn.tedu.spring.entity.User">
        select * from user where password=#{password}
     </select>
  • 测试
@Test
    public void testFindUserByPassword() {
        //加载Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //获取UserMapper的bean,这个是spring经过扫描mapper.xml文件自动为mybatis自动建立的,首字母小写
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        //获取User集合
        List<User> users=userMapper.findUserByPassword("12345895");
        System.out.println(users);
        ac.close();
    }

总结

  1. xxMapper.xml中配置的节点的id要和xxMapper.java中的方法名相同
  2. mybatis默认支持一个参数,可是咱们可使用@Param("")指定多个参数,不过在使用#{}取值的时候要和@Param("")中的参数一致
  3. 获取自增主键并非做为方法的返回值,而是在调用方法的时候将自增主键的值设置在方法参数的对象中,那么此时的调用者就能够获取到自增主键的值
  4. 增长,修改,删除,方法返回的永远是受影响的行数
  5. **在定义实体类属性的时候,尽可能使用包装类,好比Integer age**
  6. 只要是<select>节点,那么必须写返回类型resultType,不管是基本型仍是其余类型
相关文章
相关标签/搜索