mybatis动态sql

动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发送变化。
动态sql的实现,使用的是mybatis提供的标签,<if>,<where>,<foreach>
<if>是判断条件的,
语法<if test=”判断java对象的属性值”> 语法 </if>

mybatis动态sql-if标签

Mybatis动态sql_User

接口
List<User> selectStudentIf(User user);

Mapper文件
<!--if
<if test="使用参数java对象的属性值作为判断条件,语法规则 属性=xx">
-->
<select id="selectStudentIf" resultType="org.example.daomain.User">
SELECT * FROM TEST1
WHERE
<if test="p_name !=null and p_name!=''">
p_name =#{p_name}
</if>
<if test="address !='SS'">
and address = #{address}
</if>

</select>

测试类
@Test
public void testSelectStudents(){
/**使用mybatis的动态代理机制,使用sqlSession.getMapper(dao接口)
* getMapper能够获得dao接口的实现类对象
**/
SqlSession sqlSession = MyBatisUtils.getSqlSessionAuto();
UserDao dao = sqlSession.getMapper(UserDao.class);
User user =new User();
user.setP_name("小红");
user.setAddress("北京");
//调用dao的方法,执行数据库的操作
List<User> users =dao.selectStudentIf(user);
users.forEach(u-> System.out.println("用户:"+u));
}

Mybatis动态sql_java_02

执行顺序,从上往下
小问题
当第一个if不成立,第二if成立时,会造成语法错误
小技巧

Mybatis动态sql_sql_03

解决小技巧:

Mybatis动态sql_sql_04

mybatis动态sql-where标签

<where>用来包含 多个<if>的,当多个if有一个成立的,<where>会自动增加一个where关键字,并去掉if中多余的and ,or等。

接口
//where
List<User> selectStudentWhere(User user);

Mapper
<select id="selectStudentWhere" resultType="org.example.daomain.User">
SELECT * FROM TEST1
<where>
<if test="p_name !=null and p_name!=''">
p_name =#{p_name}
</if>
<if test="address !='SS'">
and address = #{address}
</if>
</where>
</select>

测试类
//where
@Test
public void selectStudentWhere(){
/**使用mybatis的动态代理机制,使用sqlSession.getMapper(dao接口)
* getMapper能够获得dao接口的实现类对象
**/
SqlSession sqlSession = MyBatisUtils.getSqlSessionAuto();
UserDao dao = sqlSession.getMapper(UserDao.class);
User user =new User();
user.setP_name("小红");
user.setAddress("北京");
//调用dao的方法,执行数据库的操作
List<User> users =dao.selectStudentWhere(user);
users.forEach(u-> System.out.println("用户:"+u));
}

Mybatis动态sql_sql_05

mybatis动态sql-foreach标签

<foreach>循环java中的数组,list集合的。主要用在sql的in语句中。
学生id是 1 2 3的三个学生
SELECT * FROM TEST1 WHERE p_id in (1,2,3)

<foreach collection="" item="" open="" close="" separator=""></foreach>
Collection:表示接口中的方法参数的类型,如果是数组使用array,如果是list集合使用list
Item:自定义的,表示数组和集合成员的变量
Open:循环开始时的字符
Close:循环结束时的字符
Separator:集合成员之间的分隔符

foreach用法1

Mybatis动态sql_mybatis_06

接口
//foreach用法1
List<User> selectFor(List<Integer> idlist);

Mapper
<select id="selectFor" resultType="org.example.daomain.User">
SELECT * FROM TEST1 WHERE p_id IN
<foreach collection="list" item="p_id" open="(" close=")" separator=",">
#{p_id}
</foreach>
</select>

测试类
@Test
public void selectFor(){
SqlSession sqlSession = MyBatisUtils.getSqlSessionAuto();
UserDao dao = sqlSession.getMapper(UserDao.class);
List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<User> users =dao.selectFor(list);
users.forEach(u -> System.out.println(u));
}

Mybatis动态sql_User_07

foreach用法2

接口
//foreach用法2 使用User对象
List<User> selectForTwo(List<User> userlist);

Mapper
<!--//foreach用法2使用对象-->
<select id="selectForTwo" resultType="org.example.daomain.User">
SELECT * FROM TEST1 WHERE p_id IN
<foreach collection="list" item="User" open="(" close=")" separator=",">
#{User.p_id}
</foreach>
</select>

测试类
@Test
public void selectForTwo(){
SqlSession sqlSession = MyBatisUtils.getSqlSessionAuto();
UserDao dao = sqlSession.getMapper(UserDao.class);
List<User> userslist =new ArrayList<>();
User u1 =new User();
u1.setP_id(1);

User u2 =new User();
u2.setP_id(2);

userslist.add(u1);
userslist.add(u2);

List<User> users = dao.selectForTwo(userslist);
users.forEach(u-> System.out.println(u));
}

Mybatis动态sql_mybatis_08

Mybatis动态sql_sql_09

动态sql-代码片段

Sql代码片段,就是多次复用的sql语法
步骤
定义:<sql id=”自定义名称唯一”>sql语句</sql>
使用:<include refid=”id的值”/>

案例
<sql id="SELCETSQL">
SELECT * FROM TEST1 WHERE p_id IN
</sql>

<select id="selectForTwo" resultType="org.example.daomain.User">
<include refid="SELCETSQL"/>
<foreach collection="list" item="User" open="(" close=")" separator=",">
#{User.p_id}
</foreach>
</select>

Mybatis动态sql_List_10