03-MyBatis动态Sql

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linzhaoliangyan/article/details/88658573

  * 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。

 * 传统JDBC组合复杂的sql语句  

 *  动态查询
   * 从多个查询条件中随机选择若干个组合成一个DQL语句进行查询,这一过程叫做动态查询。

public List<Student> getStudentsByParams(HashMap<String,Object> map){
        Connection connection = null;
        PreparedStatement pst = null;
        ResultSet rs = null;
        // 用jdbc连接数据库获取数据
        try {
            // 1 加载数据库驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2 通过驱动类获取的数据库的链接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/hx01?characterEncoding=utf-8",
                    "root", "root");
            // 3 定义SQL语句
            //  // 关键是"where 1=1",不需要再判断追加的查询条件前是否需要添加and,统一在前面添加and
            String sql = "SELECT * FROM student WHERE 1=1";
            StringBuilder sb=new StringBuilder();
            sb.append(sql);
            if(map==null || map.size()==0){
                // 没有传递参数查询所有
                pst = connection.prepareStatement(sql);
            }else{
                for(Map.Entry<String,Object> entry:map.entrySet()){
                    sb.append(" and "+entry.getKey()+"=? ");
                }
                String sqlBuilder=sb.toString();
                System.out.println(sqlBuilder);
                pst = connection.prepareStatement(sqlBuilder);

                int index=1;
                for(Map.Entry<String,Object> entry:map.entrySet()){
                    pst.setObject(index,entry.getValue());
                    index++;
                }
            }
            rs = pst.executeQuery();
            List<Student> students=new ArrayList<Student>();
            while (rs.next()) {
                Student student=new Student();
                student.setSid(rs.getInt(1));
                student.setCno(rs.getInt(2));
                student.setSname(rs.getString(3));
                student.setSsex(rs.getString(4).charAt(0));
                student.setSage(rs.getInt(5));
                student.setColleage(rs.getString(6));
                students.add(student);
            }
            return students;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 8 释放资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (pst != null) {
                try {
                    pst.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

* 测试

@Test
    public void test1(){
        StudentDao studentDao=new StudentDao();
        HashMap<String,Object> map=new HashMap<String,Object>();
        // 模拟输入的条件
        map.put("ssex","男");
        map.put("sage","22");
        map.put("colleage","物理系");
        List<Student> students = studentDao.getStudentsByParams(map);
        System.out.println(students);
    }

    * mybatis动态sql

        * 使用Mybatis的动态SQL     

public interface StudentMapper {

    /**
     * 通过动态参数查询:动态sql
     * @param map
     * @return
     */
    public List<Student> getStudentsByParams(HashMap<String,Object> map);
}

<?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">
<mapper namespace="com.hx.hx02.mapper.StudentMapper">
    <select id="getStudentsByParams" parameterType="hashMap" resultType="com.hx.hx02.bean.Student">
        SELECT * FROM student where
        <if test="ssex !=null">
             ssex=#{ssex}
        </if> and
        <if test="sage !=null">
            sage=#{sage}
        </if> and
        <if test="colleage !=null">
            colleage=#{colleage}
        </if>
    </select>

</mapper>

 @Test
    public void test7(){
        SqlSession session = MyBatisUtils.getSqlSession();
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        HashMap<String,Object> map=new HashMap<String,Object>();
        // 模拟输入的条件
        map.put("ssex","男");
        map.put("sage","22");
        map.put("colleage","物理系");
        List<Student> students = mapper.getStudentsByParams(map);
        System.out.println(students);
        session.close();
    }

 假如没有ssex参数:SQL语句会变成如下
SELECT * FROM student where and sage=? and colleage=? 

扫描二维码关注公众号,回复: 5596200 查看本文章

* 解决方法:使用where标签(自动处理多余的and|or)

<?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">
<mapper namespace="com.hx.framework.dao.StudentMapper">
    <select id="getStudentsByParams" parameterType="hashMap" resultType="com.hx.framework.bean.Student">
        SELECT * FROM student
        <where>
            <if test="ssex !=null">
              and ssex=#{ssex}
            </if>
            <if test="sage !=null">
              and sage=#{sage}
            </if>
            <if test="colleage !=null">
              and colleage=#{colleage}
            </if>
        </where>
    </select>
</mapper>

 * set 标签    

 /**
     * 根据学生学号动态更新学生姓名,性别,年龄,学院
     * @param student
     */
    public void updateStudent(Student student);

UPDATE student SET sname='小小',ssex='女',sage=22,colleage='物理系' WHERE sid=100002;


<update id="updateStudent" parameterType="com.hx.hx02.bean.Student">
        UPDATE student SET
        <if test="sname!=null">
            sname=#{sname},
        </if>
       <if test="ssex!=''">
                ssex=#{ssex},
        </if>
        <if test="sage!=0">
                sage=#{sage},
         </if>
        <if test="colleage!=null">
            colleage=#{colleage}
        </if>
        <where>
            <if test="sid !=null">
                sid=#{sid}
            </if>
        </where>
    </update>

@Test
    public void test8(){
        SqlSession session = MyBatisUtils.getSqlSession();
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        Student student=new Student();
        student.setSid(100002);
        student.setSname("大明");
        student.setSsex('男');
        student.setColleage("计算机系");
        student.setSage(23);
        mapper.updateStudent(student);
        session.commit();
        session.close();
    }

  * 问题分析

  * 当不设置colleage的时候,sage后面多个逗号
    sql:
    UPDATE student SET sname=?, ssex=?, sage=?, WHERE sid=? 

  * 解决方案使用set标签

<update id="updateStudent" parameterType="com.hx.hx02.bean.Student">
        UPDATE student
        <set>
            <if test="sname!=null">
                sname=#{sname},
            </if>
            <if test="ssex!=''">
                ssex=#{ssex},
            </if>
             <if test="sage!=0">
                sage=#{sage},
            </if>
            <if test="colleage!=null">
                colleage=#{colleage}
            </if>
        </set>
        <where>
            <if test="sid !=null">
                sid=#{sid}
            </if>
        </where>
    </update>

  * 易错点提醒

<if test="ssex!=null">
                ssex=#{ssex},
</if>
 <if test="sage!=null">
                sage=#{sage},
  </if>
  int:0
  char:''
  没有设置值,不是为null

 * foreach       

  -- 通过动态学号数组数组查询学生信息
SELECT * FROM student WHERE sid IN(100001,100002,100003);

/**
     * 通过动态学号数组数组查询学生信息
     * @param ids
     * @return
     */
    public List<Student> getStudentsByIds(int[] ids);

    /**
     * 通过动态学号数组数组查询学生信息
     * @param ids
     * @return
     */
    public List<Student> getStudentsByListIds(List<Integer> ids);


 <select id="getStudentsByIds" parameterType="int" resultType="com.hx.hx02.bean.Student">
        SELECT * FROM student WHERE sid IN
        <foreach collection="array" item="id"  index="index" separator="," open="(" close=")">
              ${id}
        </foreach>
       SELECT * FROM student WHERE sid IN(100001,100002,100003);
    </select>

    <select id="getStudentsByListIds" parameterType="list" resultType="com.hx.hx02.bean.Student">
        SELECT * FROM student WHERE sid IN
        <foreach collection="list" item="id"  index="index" separator="," open="(" close=")">
            ${id}
        </foreach>
    </select>


 @Test
    public void test9(){
        SqlSession session = MyBatisUtils.getSqlSession();
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        int[] ids={100001,100002,100003};
        List<Student> students = mapper.getStudentsByIds(ids);
        System.out.println(students);
        session.close();
    }

    @Test
    public void test10(){
        SqlSession session = MyBatisUtils.getSqlSession();
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Integer> ids=new ArrayList<Integer>();
        ids.add(100001);
        ids.add(100002);
        ids.add(100003);
        List<Student> students = mapper.getStudentsByListIds(ids);
        System.out.println(students);
        session.close();
    }

 * choose/when

        * 参考   

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

猜你喜欢

转载自blog.csdn.net/linzhaoliangyan/article/details/88658573