通過mybatis提供的各種標籤方法實現動態拼接sql,這就是動態sql。
IF 標籤
接口
public interface UserDao {
public List<User> selectUserBySexAndUserName (User user) ;
}
Mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >
<select id="selectUserBySexAndUserName" parameterType="User" resultType="User">
select * from user
where
<!-- test裏面填判斷條件 -->
<if test="sex != null and sex != ''">
sex = #{sex}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
</select>
</mapper>
test
@Test
public void testFun2 () throws IOException
{
//加載核心配置文件
String resource = "SqlMapConfig.xml" ;
InputStream in = Resources.getResourceAsStream(resource) ;
//創建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;
//創建SqlSession
SqlSession sqlSession = ssf.openSession() ;
UserDao userDao = sqlSession.getMapper(UserDao.class) ;
User user = new User () ;
user.setSex("1");
user.setUsername("張三丰");
List <User> list = userDao.selectUserBySexAndUserName(user);
for ( User u : list )
{
System.out.println(u);
}
}
若此時將setSex 註釋掉那麼 SQL語句就無法執行 如何解決?
用where 標籤
Where標籤
可以去掉sql中影響執行的and,前提:and必須在語句的前面
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >
<select id="selectUserBySexAndUserName" parameterType="User" resultType="User">
select * from user
<!-- 根據性別和名字查詢用戶 where 可以去掉語句前的and.
前提是此語句中的and影響SQL的執行
比如說此案例中的sex字段,如果此字段爲空,
那麼此時的sql語句就變爲 select * from user where and username = #{username}
如果你用了where標籤,那麼標籤就可以幫你把and去掉,讓sql語句可以執行,注意只有and在語句的前面,
where字段纔會生效
-->
<where>
<!-- test裏面填判斷條件 -->
<if test="sex != null and sex != ''">
sex = #{sex}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
</where>
</select>
</mapper>
SQL片段
即將重複的sql語句部分抽取出來,留作共用
用到兩個標籤
sql
include
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >
<sql id="select">
select * from user
</sql>
<select id="selectUserBySexAndUserName" parameterType="User" resultType="User">
<!-- 引用抽取出來的sql片段 -->
<include refid="select"></include>
<where>
<!-- test裏面填判斷條件 -->
<if test="sex != null and sex != ''">
sex = #{sex}
</if>
<if test="username != null and username != ''">
and username = #{username}
</if>
</where>
</select>
</mapper>
foreach標籤
從字面上也能看出這是一個循環遍歷標籤,用於遍歷要傳遞到sql語句的參數
需求:根據多個id查詢用戶
分爲四種情況
1.傳遞一個數組進去
2.傳遞一個list集合
3.傳遞一個包裝類,類裏面包含一個list
4.傳遞一個包裝類,類裏面包含一個數組
先考慮第三種
傳遞一個包裝類,類裏面包含一個list
bean
public class Users {
private User user ;
List <Integer> list ;
Integer [] ids ;
public List<Integer> getList() {
return list;
}
public void setList(List<Integer> list) {
this.list = list;
}
public Integer[] getIds() {
return ids;
}
public void setIds(Integer[] ids) {
this.ids = ids;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String username;// 用戶姓名
private String sex;// 性別
private Date birthday;// 生日
private String address;// 地址
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
接口
public interface UserDao {
//根據多個id查詢用戶信息
// public List<User> selectUserByIds ( Integer [] ids ) ;
// public List<User> selectUserByIds ( List <Integer> ids ) ;
public List<User> selectUserByIds ( Users users ) ;
}
mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空間,用於隔離sql -->
<!-- 寫SQL語句 -->
<mapper namespace="cn.itcast.dao.UserDao" >
<sql id="select">
select * from user
</sql>
<!-- 多個id查詢用戶 (1,2,3)-->
<select id="selectUserByIds" parameterType="users" resultType="user">
<include refid="select"></include>
<where>
id in
<foreach collection="list" item="id" separator="," open="(" close=")" >
#{id}
</foreach>
</where>
</select>
</mapper>
測試
@Test
public void testFun3 () throws IOException
{
//加載核心配置文件
String resource = "SqlMapConfig.xml" ;
InputStream in = Resources.getResourceAsStream(resource) ;
//創建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;
//創建SqlSession
SqlSession sqlSession = ssf.openSession() ;
UserDao userDao = sqlSession.getMapper(UserDao.class) ;
Users user = new Users () ;
List <Integer> list = new ArrayList <Integer> ();
list.add(1) ;
list.add(10) ;
list.add(12) ;
user.setList(list) ;
List<User> list2 = userDao.selectUserByIds(user);
for ( User u : list2 )
{
System.out.println(u);
}
}
傳遞一個包裝類,類裏面包含一個數組
bean
public class Users {
private User user ;
List <Integer> list ;
Integer [] ids ;
public List<Integer> getList() {
return list;
}
public void setList(List<Integer> list) {
this.list = list;
}
public Integer[] getIds() {
return ids;
}
public void setIds(Integer[] ids) {
this.ids = ids;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
xml
<!-- 多個id查詢用戶 (1,2,3)-->
<select id="selectUserByIds" parameterType="users" resultType="user">
<include refid="select"></include>
<where>
id in
<foreach collection="ids" item="id" separator="," open="(" close=")" >
#{id}
</foreach>
</where>
</select>
test
@Test
public void testFun4 () throws IOException
{
//加載核心配置文件
String resource = "SqlMapConfig.xml" ;
InputStream in = Resources.getResourceAsStream(resource) ;
//創建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;
//創建SqlSession
SqlSession sqlSession = ssf.openSession() ;
UserDao userDao = sqlSession.getMapper(UserDao.class) ;
Users users = new Users () ;
Integer [] arr = new Integer [] { 1 , 12 , 13 };
users.setIds(arr);
List<User> list2 = userDao.selectUserByIds(users);
for ( User user : list2 )
{
System.out.println(user);
}
}
下面考慮第一和第二種情況
傳遞list或數組,那麼在collection就要填入關鍵字 list 或 array 方可遍歷 ,注意遇到這種情況時parameterType 可以瞎寫或者不寫
array
@Test
public void testFun4 () throws IOException
{
//加載核心配置文件
String resource = "SqlMapConfig.xml" ;
InputStream in = Resources.getResourceAsStream(resource) ;
//創建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;
//創建SqlSession
SqlSession sqlSession = ssf.openSession() ;
UserDao userDao = sqlSession.getMapper(UserDao.class) ;
Users users = new Users () ;
Integer [] arr = new Integer [] { 1 , 15 , 16 };
users.setIds(arr);
List<User> list2 = userDao.selectUserByIds(arr);
for ( User user : list2 )
{
System.out.println(user);
}
}
<!-- 多個id查詢用戶 (1,2,3)-->
<select id="selectUserByIds" resultType="user">
<include refid="select"></include>
<where>
id in
<foreach collection="array" item="id" separator="," open="(" close=")" >
#{id}
</foreach>
</where>
</select>
list
@Test
public void testFun6 () throws IOException
{
//加載核心配置文件
String resource = "SqlMapConfig.xml" ;
InputStream in = Resources.getResourceAsStream(resource) ;
//創建SqlSessionFactory
SqlSessionFactory ssf = new SqlSessionFactoryBuilder ().build(in) ;
//創建SqlSession
SqlSession sqlSession = ssf.openSession() ;
UserDao userDao = sqlSession.getMapper(UserDao.class) ;
List <Integer> list = new ArrayList <Integer> ();
list.add(1) ;
list.add(10) ;
list.add(12) ;
List<User> list2 = userDao.selectUserByIds(list);
for ( User u : list2 )
{
System.out.println(u);
}
}
<!-- 多個id查詢用戶 (1,2,3)-->
<select id="selectUserByIds" resultType="user">
<include refid="select"></include>
<where>
id in
<!-- foreach標籤,進行遍歷 -->
<!-- collection:遍歷的集合,這裏是QueryVo的ids屬性 -->
<!-- item:遍歷的項目,可以隨便寫,,但是和後面的#{}裏面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在結尾處添加的sql片段 -->
<!-- separator:指定遍歷的元素之間使用的分隔符 -->
<foreach collection="list" item="id" separator="," open="(" close=")" >
#{id}
</foreach>
</where>
</select>