zoukankan      html  css  js  c++  java
  • Mybatis的增删改查

    Mybatis的增删改查

    增加数据<insert>

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

      • #{}中填写的是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节点中定义返回类型,只有在查询数据的时候才会定义返回类型

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

    	//根据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自动返回受影响的行数,因此我们不需要定义返回类型,默认的返回数据就是受影响的行数

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

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

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

      • 其中#{}表达式中的字段为@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,无论是基本型还是其他类型
  • 相关阅读:
    SDUST OJ 时间类的加、减法赋值运算
    POJ 2823 (滑动窗口)
    POJ 2229 计数DP
    POJ 1995 (快速幂)
    poj 3009 (深搜求最短路)
    C++ 学习笔记之 STL 队列
    C++ 学习笔记之 引用
    Anaconda3使用
    Ubuntu 18.04安装Conda、Jupyter Notebook、Anaconda
    Ubuntu 18.04安装 pyenv、pyenv-virtualenv、virtualenv、Numpy、SciPy、Pillow、Matplotlib
  • 原文地址:https://www.cnblogs.com/Chenjiabing/p/9010372.html
Copyright © 2011-2022 走看看