转载

Mybatis之增删改查

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

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

<!-- 节点名称取决于需要执行的操作 -->
	<!-- 例如增加操作应该使用insert节点 -->
	<!-- id属性(*)的值是Java接口中的方法名称 -->
	<!-- parameterType属性的值是参数类型
	-->
	<!-- 节点中间编写SQL语句 -->
	<insertid="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:配置自增主键在表中对应的字段 
-->
<insertid="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 节点中定义返回类型,只有在查询数据的时候才会定义返回类型
  • UserMapper.java 中添加一个接口方法
//根据id删除数据,返回受影响的行数,返回1,如果删除失败返回0
IntegerdeleteUserById(int id);
  • UserMapper.xml 中配置 <delete> 节点
<!-- 删除用户数据根据id
	Integer deleteUserById(int id)
	parameterType: 指定参数类型,这里也可以不需要指定
 -->
<deleteid="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) 方法获取的

修改数据

  • 在修改数据的时候,mybatis自动返回受影响的行数,因此我们不需要定义返回类型,默认的返回数据就是受影响的行数

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

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

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

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

<!-- 修改密码
	Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
 -->
<updateid="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 将会通过处理异常来判断哪里是出错了,并给出友好的提示

查询数据

单条数据的查询

  • 根据 id 的查询返回的查询结果就是单条数据,比如: select * from user where id=1
  • 单条记录的查询在编写 接口方法 的时候,只需要返回一个 实体类对象 即可
/**
 * 根据id查询用户信息
 * @param id  用户id
 * @return 返回User对象
 */
UserfindUserById(Integer id);
  • UserMapper.xml 中配置 <select> 节点
    • 需要使用 resultType 指定返回的类型,因为参数是基本类型,因此不需要使用 parameterType 指定参数类型
<selectid="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类型
 -->
 
 <selectid="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();
}
原文  https://chenjiabing666.github.io/2018/05/04/Mybatis之增删改查/
正文到此结束
Loading...