MyBatis框架(6)動態sql
阿新 • • 發佈:2018-12-14
什麼是動態sql:
mybatis的核心,對sql進行靈活的操作,通過對錶達式的判斷,對sql靈活的拼接
在之前小案例的基礎上我們先進行簡單的實現一下:
if:
在UserMapper.xml檔案中找到:
<!-- 動態sql --> <!-- 綜合查詢 --> <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" > select * from user<where> <if test="userCustomer!=null"> <if test="userCustomer.sex!=null and userCustomer.sex!='' "> and user.sex=#{userCustomer.sex} </if> <if test="userCustomer.username!=null and userCustomer.username!=''"> and user.username like'%${userCustomer.username}%' </if> </if> </where> </select>
注意:where標籤可以自動去掉條件中的第一個 and
測試類: //此時值傳入username這一個值//動態sql //高階查詢 @Test public void testfindBySelect() throws Exception{ SqlSession sqlSession= getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserView userView = new UserView(); UserCustomer userCustomer = new UserCustomer(); //userCustomer.setSex(1); userCustomer.setUsername("小明"); userView.setUserCustomer(userCustomer); List<User> user = mapper.findBySelect(userView); for(User u : user){ System.out.println(u); } sqlSession.close(); }
結果:
DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]] DEBUG [main] - ==> Preparing: select * from user WHERE user.username like '%小明%' DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 3 User [id=16, username=張小明, birthday=null, sex=1, address=河南鄭州] User [id=22, username=陳小明, birthday=null, sex=1, address=河南鄭州] User [id=25, username=陳小明, birthday=null, sex=1, address=河南鄭州]在if中判斷此時,之傳入了一個username進行查詢。
SQL片段:
把實現動態sql判斷的程式碼塊抽取出來,組成一個sql片段,在需要的時候可以直接引用,重用性高 定義一個sql片段,基於上面的程式碼進行測試和實踐: 在UserMapper.xml檔案中: 定義sql片段:<!-- sql片段 --> <!-- id唯一,是sql片段的唯一標識 --> <!-- 基於單表定義sql片段,這樣的話sql片段的可重用性才高,在sql片段中不要包括where --> <sql id="selectBySql"> <if test="userCustomer!=null"> <if test="userCustomer.sex!=null and userCustomer.sex!='' "> and user.sex=#{userCustomer.sex} </if> <if test="userCustomer.username!=null and userCustomer.username!=''"> and user.username like '%${userCustomer.username}%' </if> </if> </sql>
引用sql片段:
<!-- 動態sql --> <!-- 綜合查詢 --> <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" > select * from user <where> <!-- 引用sql片段 --> <include refid="selectBySql"></include> </where> </select>
測試程式碼同上次測試程式碼!
foreach標籤:
假設我們同時查詢多個id
select from user where id = 1 or id = 10 or id = 12 在UserMapper.xml檔案中,對之前的程式碼進行加工修改: 此時,在測試的時候,我只是測試foreach裡面的內容,所以,對程式碼進行了修改<!-- sql片段 --> <!-- id唯一,是sql片段的唯一標識 --> <!-- 基於單表定義sql片段,這樣的話sql片段的可重用性才高,在sql片段中不要包括where --> <sql id="selectBySql"> <if test="userCustomer!=null"> <if test="userCustomer.sex!=null and userCustomer.sex!='' "> and user.sex=#{userCustomer.sex} </if> <if test="userCustomer.username!=null and userCustomer.username!=''"> and user.username like '%${userCustomer.username}%' </if> </if> <!-- foreach --> <!-- 測試 --> <!-- select from user where id = 1 or id = 10 or id = 12 --> <!-- collection:指定輸入物件的集合 --> <!-- item:每個遍歷生成成的物件 --> <!-- open:開始遍歷時 拼接的串 --> <!-- close:結束遍歷時 拼接的串 --> <!-- separator:遍歷時兩個物件中需要拼接的串 --> <foreach collection="ids" close=")" item="userId" open="1=1 and (" separator="or"> id=#{userId} </foreach> </sql> <!-- 動態sql --> <!-- 綜合查詢 --> <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" > select * from user <where> <!-- 引用sql片段 --> <include refid="selectBySql"></include> </where> </select>
測試程式碼:
//foreach //動態sql //高階查詢 @Test public void testfindBySelect() throws Exception{ SqlSession sqlSession = getSqlSessionFactory().openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); UserView userView = new UserView(); //foreach List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(2); ids.add(30); userView.setIds(ids); List<User> users = mapper.findBySelect(userView); for(User user : users){ System.out.println(user); } sqlSession.close(); }
結果:
DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]] DEBUG [main] - ==> Preparing: select * from user WHERE 1=1 and ( id=? or id=? or id=? ) DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer), 30(Integer) DEBUG [main] - <== Total: 2 User [id=1, username=王五, birthday=null, sex=2, address=null] User [id=30, username=Ma, birthday=null, sex=1, address=安徽]對於 SELECT * FROM USER WHERE id IN(1,2,30)來說 只需要修改下面的測試程式碼,其餘的測試程式碼均不變
<foreach collection="ids" close=")" item="userId" open="1=1 and id in(" separator=","> id=#{userId} </foreach>sql只接收一個數組引數,這時sql解析引數的名稱mybatis固定為array,如果陣列是通過一個pojo傳遞到sql則引數的名稱為pojo中的屬性名。 index:為陣列的下標。 item:為陣列每個元素的名稱,名稱隨意定義 open:迴圈開始 close:迴圈結束 separator:中間分隔輸出