案例2:输入映射
需求:查询条件复杂,需要传入一个复杂的pojo。
一般情况下,在select标签中parameterType为User就可以满足大部分需求。
这里创建一个更加灵活的类UserQueryVo
public class UserQueryVo { //传入多个id private List<Integer> ids; //在这里包装所需要的查询条件 //UserCustom继承了User类 private UserCustom userCustom; //getter and setter.... }
UserMapper.java中添加
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
UserMapper.xml中添加
<select id="findUserList" parameterType="com.legion.hello.UserQueryVo" resultType="com.legion.hello.UserCustom"> select * from user where sex=#{userCustom.sex} and address like '%${userCustom.address}%' </select>
注意${}和#{} 的区别:like后面使用${}而不是#{}。
使用#{},生成Sql的时候,参数带引号。使用${}参数不带引号。
测试代码:
@Test public void testFindUserList() throws Exception{ SqlSession session=sqlSessionFactory.openSession(); UserMapper userMapper=session.getMapper(UserMapper.class); UserQueryVo u=new UserQueryVo(); UserCustom uc=new UserCustom(); uc.setSex("1"); uc.setAddress("河南"); u.setUserCustom(uc); List<UserCustom> list=userMapper.findUserList(u); System.out.println(list); }
案例3:输出映射。
一般情况下,select 标签中resultType为UserCustom满足大部分需求。(甚至可以是int类型)
需求:比如MySQL查询SELECT id,username FROM USER;返回
但是MySQL使用这种语法查询,SELECT id USERID,username NAMES FROM USER;
返回
这种情况下,返回的列名和pojo的属性名不一样。解决方案:通过定义一个resultMap对列名和pojo属性名做映射关系。
在UserMapper.java 中添加
public User findUserByIdResultMap(int id)throws Exception;
在UserMapper.xml添加
<resultMap type="com.legion.hello.User" id="myrm"> <!-- id表示查询结果唯一标识,result普通名映射 column查询的列名,property表示pojo中的属性名 --> <id column="USERID" property="id" /> <result column="NAMES" property="username" /> </resultMap> <select id="findUserByIdResultMap" parameterType="int" resultMap="myrm"> select id USERID,username NAMES from user where id=#{value} </select>
测试代码:
@Test public void testFindUserByIdResultMap()throws Exception{ SqlSession session=sqlSessionFactory.openSession(); UserMapper u=session.getMapper(UserMapper.class); User user=u.findUserById(24); System.out.println(user); }
动态SQL
案例1:
对输入参数进行判断,然后进行查询条件的语句拼接。
UserMapper.xml中原来select id为findUserList的代码是
<select id="findUserList" parameterType="com.legion.hello.UserQueryVo" resultType="com.legion.hello.UserCustom"> select * from user where sex=#{userCustom.sex} and address like '%${userCustom.address}%' </select>
现在改成
<select id="findUserList" parameterType="com.legion.hello.UserQueryVo" resultType="com.legion.hello.UserCustom"> <!-- where会自动去掉第一个and --> select * from user <where> <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!=''"> and sex=#{userCustom.sex} </if> <if test="userCustom.address!=null and userCustom.address!=''"> and address like '%${userCustom.address}%' </if> </if> </where> </select>
在测试代码
@Test public void testFindUserList() throws Exception{ SqlSession session=sqlSessionFactory.openSession(); UserMapper userMapper=session.getMapper(UserMapper.class); UserQueryVo u=new UserQueryVo(); //UserCustom uc=new UserCustom(); //uc.setSex("1"); //uc.setAddress("河南"); //u.setUserCustom(uc); List<UserCustom> list=userMapper.findUserList(u); System.out.println(list); }
中是否设置UserCustom对象,是否设置sex和address,系统会根据条件生成不同的sql 语句(where 后面的语句)。
案列2:使用sql片段
将上述配置修改成sql片段,然后再引用。
<sql id="hi"> <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!=''"> and sex=#{userCustom.sex} </if> <if test="userCustom.address!=null and userCustom.address!=''"> and address like '%${userCustom.address}%' </if> </if> </sql> <select id="findUserList" parameterType="com.legion.hello.UserQueryVo" resultType="com.legion.hello.UserCustom"> <!-- where会自动去掉第一个and --> select * from user <where> <include refid="hi"></include> </where> </select>
案例3:foreach解析
需求:SELECT * FROM USER WHERE id=1 OR id= 10 OR id=22 OR id=24 OR id=26
在UserQueryVoid有一个List<Integer> ids 对象,包含需要查询的id,foreach解析就是要根据ids拼接上面的sql语句。
sql片段修改成
<sql id="hi"> <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!=''"> and sex=#{userCustom.sex} </if> <if test="userCustom.address!=null and userCustom.address!=''"> and address like '%${userCustom.address}%' </if> <if test="ids!=null"> <!-- 使用 foreach遍历传入ids collection:指定输入 对象中集合属性 item:每个遍历生成对象中 open:开始遍历时拼接的串 close:结束遍历时拼接的串 separator:遍历的两个对象中需要拼接的串 --> <foreach collection="ids" item="user_id" open="and (" close=")" separator="or"> id=#{user_id} </foreach> </if> </if> </sql>
测试代码
@Test public void testFindUserList() throws Exception{ SqlSession session=sqlSessionFactory.openSession(); UserMapper userMapper=session.getMapper(UserMapper.class); UserQueryVo u=new UserQueryVo(); UserCustom uc=new UserCustom(); uc.setSex("1"); uc.setAddress("河南"); List<Integer> ids=new ArrayList<Integer>(); ids.add(1); ids.add(10); ids.add(22); ids.add(24); ids.add(26); u.setIds(ids); u.setUserCustom(uc); List<UserCustom> list=userMapper.findUserList(u); System.out.println(list); }
可以看到拼接的sql语句是
select * from user WHERE sex=? and address like '%河南%' and ( id=? or id=? or id=? or id=? or id=? )