MyBatis-15MyBatis动态SQL之【bind】

xiaoxiao2021-02-28  11

概述用法示例 1.增加接口方法2.配置动态SQL3.单元测试

概述

bind标签可以使用OGNL表达式创建一个变量并将其绑定到上下文中。


用法

我们用之前的一个例子作为讲解

<select id="selectSysUsersAdvancedWithWhere" resultType="com.artisan.mybatis.xml.domain.SysUser"> SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a <where> <if test="userName != null and userName != '' "> and user_name like concat('%',#{userName},'%') </if> <if test="userEmail != null and userEmail != '' "> and user_email = #{userEmail} </if> </where> </select>

使用concat函数连接字符串,在MySQL中,这个函数支持多个参数,但是在Oracle中只支持两个参数。 由于不同数据库之间的语法差异,如果更换了数据库,有些SQL语句可能就需要重写。 针对这种情况,可以使用bind标签来避免由于更换数据库带来的一些麻烦。 我们将上面的语句改为bind方式,如下

<select id="selectSysUserByAdvancedCondition" resultType="com.artisan.mybatis.xml.domain.SysUser"> SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a <where> <if test="userName != null and userName != '' "> <!-- and user_name like concat('%',#{userName},'%') --> <bind name="userNameLike" value=" '%' + userName + '%' "/> and user_name like #{userNameLike} </if> <if test="userEmail != null and userEmail != '' "> and user_email = #{userEmail} </if> </where> </select>

bind标签的两个属性都是不选项,name为绑定到上下文的变量名,value为OGNL表达式,创建一个bind标签后,就可以在下面直接使用了。 使用bind拼接字符串不仅可以避免因更换数据库而修改SQL,也能预防SQL注入。


示例

1.增加接口方法

/** * * * @Title: selectSysUserByAdvancedCondition * * @Description: 演示bind用法 * * @param sysUser * @return * * @return: List<SysUser> */ List<SysUser> selectSysUserByAdvancedCondition(SysUser sysUser);

2.配置动态SQL

<select id="selectSysUserByAdvancedCondition" resultType="com.artisan.mybatis.xml.domain.SysUser"> SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a <where> <if test="userName != null and userName != '' "> <!-- and user_name like concat('%',#{userName},'%') --> <bind name="userNameLike" value=" '%' + userName + '%' "/> and user_name like #{userNameLike} </if> <if test="userEmail != null and userEmail != '' "> and user_email = #{userEmail} </if> </where> </select>

3.单元测试

@Test public void selectSysUserByAdvancedConditionTest() { logger.info("selectSysUserByAdvancedConditionTest"); // 获取SqlSession SqlSession sqlSession = getSqlSession(); List<SysUser> userList = null; try { // 获取UserMapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); logger.info("===========1.当用户只输入用户名时,需要根据用户名模糊查询==========="); // 模拟前台传参 1.当用户只输入用户名时,需要根据用户名模糊查询 SysUser sysUser = new SysUser(); sysUser.setUserName("ad"); // 调用selectSysUserByAdvancedCondition,根据查询条件查询用户 userList = userMapper.selectSysUserByAdvancedCondition(sysUser); // 根据数据库sys_user表中的记录,可以匹配到admin, 期望userList不为空 Assert.assertNotNull(userList); // 根据查询条件,期望只有1条数据 Assert.assertTrue(userList.size() == 1); logger.info("userList:" + userList); // 为了测试 匹配多条记录的情况,我们将id=1001这条数据的userName 由test 改为artisan sysUser.setUserName("i"); // 调用selectSysUserByAdvancedCondition,根据查询条件查询用户 userList = userMapper.selectSysUserByAdvancedCondition(sysUser); // 根据数据库sys_user表中的记录,可以匹配到admin和artisan, 期望userList不为空 Assert.assertNotNull(userList); // 根据查询条件,期望只有2条数据 Assert.assertTrue(userList.size() == 2); logger.info("userList:" + userList); logger.info("===========2.当用户只输入邮箱使,根据邮箱进行完全匹配==========="); // 模拟前台传参 2.当用户只输入邮箱使,根据邮箱进行完全匹配 sysUser.setUserEmail("admin@artisan.com"); userList = userMapper.selectSysUsersAdvanced(sysUser); Assert.assertNotNull(userList); Assert.assertTrue(userList.size() == 1); logger.info(userList); sysUser.setUserEmail("1admin@artisan.com"); userList = userMapper.selectSysUserByAdvancedCondition(sysUser); Assert.assertTrue(userList.size() == 0); logger.info("===========3.当用户同时输入用户名和密码时,用这两个条件查询匹配的用户==========="); // 模拟组合查询条件,存在记录的情况 sysUser.setUserName("i"); sysUser.setUserEmail("admin@artisan.com"); userList = userMapper.selectSysUserByAdvancedCondition(sysUser); Assert.assertNotNull(userList); Assert.assertEquals("admin@artisan.com", sysUser.getUserEmail()); Assert.assertTrue(userList.size() == 1); logger.info(userList); logger.info("===========4.当用户同时输入无法匹配的用户名和密码==========="); // 模拟组合查询条件,不存在记录的情况 sysUser.setUserName("x"); sysUser.setUserEmail("admin@artisan.com"); userList = userMapper.selectSysUserByAdvancedCondition(sysUser); Assert.assertTrue(userList.size() == 0); logger.info(userList); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); logger.info("sqlSession close successfully "); } }

日志

2018-04-24 20:57:44,130 INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully 2018-04-24 20:57:44,133 INFO [main] (BaseMapperTest.java:29) - reader close successfully 2018-04-24 20:57:44,137 INFO [main] (UserMapperTest.java:861) - selectSysUserByAdvancedConditionTest 2018-04-24 20:57:44,155 INFO [main] (UserMapperTest.java:870) - ===========1.当用户只输入用户名时,需要根据用户名模糊查询=========== 2018-04-24 20:57:44,840 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Preparing: SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a WHERE user_name like ? 2018-04-24 20:57:44,931 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters:
转载请注明原文地址: https://www.6miu.com/read-2100093.html

最新回复(0)