美文网首页程序员大数据 爬虫Python AI SqlJava学习笔记
MyBatis(三)配置文件,输入输出映射,动态SQL

MyBatis(三)配置文件,输入输出映射,动态SQL

作者: RonaldoWang | 来源:发表于2017-02-28 00:02 被阅读553次

    1.在SqlMapConfig.xml文件中加载db.properties

    如果不写db.properties的话,那么也可以直接给value赋值,但是,这样写的话,后果就是维护起来变得麻烦,如果下次改了密码等信息,还需要在xml中寻找对应的value,代码一多的话,会很容易出错且效率不高。相反,可以直接寻找相应的properties文件。

    db.properties代码:

    db.driver=com.mysql.jdbc.Driver
    db.url=jdbc:mysql://localhost:3306/student
    db.username=root
    db.password=root
    

    "="号左边是键,尽量使用XX.XX.XX的形式,这样更清晰。

    还有一个注意的地方:

    <font color=#ff0000 size=4>加载的顺序</font>

    <font color=#ff0000 size=4>1、 先加载properties中property标签声明的属性

    2、 再加载properties标签引入的java配置文件中的属性

    3、 parameterType的值会和properties的属性值发生冲突。</font>

    <properties resource="db.properties">
          <property name="driver" value="com.mysql.jdbc.Driver"/>
    </properties>
    

    2.SqlMapConfig中Mapper的加载

    • 第一种方式:使用相对于类路径的资源,通过resource标签直接拿到对应的mapper

      <mapper resource="mapper/student.xml" />

    • 第二种方式:注册指定包下的所有映射文件。通过加载Mapper接口去加载配置文件必须在同目录下且文件名相同

      <package name="com.yu.mybatis" />

    3.全局配置文件

    <font color=#ff0000 size=4>SqlMapConfig.xml的配置内容和顺序如下(顺序不能乱)</font>:

    Properties(属性)

    Settings(全局参数设置)

    typeAliases(类型别名)

    typeHandlers(类型处理器)

    objectFactory(对象工厂)

    plugins(插件)

    environments(环境信息集合)

    environment(单个环境信息)

    mappers(映射器)


    以typeAliases(类型别名)举例

    <typeAliases>
      <typeAlias type="com.yu.domain.Student" alias="s"/>
    </typeAliases>
    

    4.输入映射(parameterType)

    1.简单pojo
    <!--更新数据 -->
    <update id="updateStudent" parameterType="com.yu.domain.Student">
        update student set
        name=#{name} ,age=#{age} ,hobby=#{hobby} where
        id=#{id}
    </update>
    
    2.包装pojo类型

    1)创建包装类

    public class StudentWrapper {
     public Student getStudent() {
        return student;
    }
    
    public void setStudent(Student student) {
        this.student = student;
    }
    
    private Student student;
     
    }
    

    2)映射文件

    <!-- 包装类型 -->
    <select id="getStudentListByWrapper" parameterType="com.yu.domain.StudentWrapper"
        resultType="com.yu.domain.Student">
        select name from student where name=#{student.name}
    </select>
    

    3)Mapper接口

    public interface StudentMapper {
    public List<Student> getStudentListByWrapper(StudentWrapper studentWrapper)throws Exception;
    }
    

    4)测试

    @Test
    public void testSelectStudentListByWrapper() throws Exception {
        SqlSession session = sqlSessionFactory.openSession();
        // 拿到代理对象
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        StudentWrapper studentWrapper = new StudentWrapper();
        Student students = new Student();
        students.setName("Ronaldo");
    
        studentWrapper.setStudent(students);
        List<Student> studentListByWrapper = mapper.getStudentListByWrapper(studentWrapper);
        System.out.println(studentListByWrapper);
        session.close();
    }
    

    5.输出映射(resultType,resultMap)

    • resultType

    <font color=#ff0000 size=4>使用resultType进行结果映射时,需要查询出的列名和映射的对象的属性名一致,才能映射成功。

    如果查询的列名和对象的属性名全部不一致,那么映射的对象为空。
    如果查询的列名和对象的属性名有一个一致,那么映射的对象不为空,但是只有映射正确那一个属性才有值。

    如果查询的sql的列名有别名,那么这个别名就是和属性映射的列名。</font>:**

    这里就不贴代码了。自行测试,debug一下。。。

    • resultMap

    使用resultMap进行结果映射时,不需要查询的列名和映射的属性名必须一致。但是需要声明一个resultMap,来对列名和属性名进行映射。

    映射文件:

    <!-- ResultMap的使用 -->
    <select id="getStudentListByResultMap" parameterType="com.yu.domain.StudentWrapper"
        resultMap="myResultMapId">
        select name name_ from student where name=#{student.name}
    </select>
    

    resultMap的值引用上面定义resultMap的id属性

    6.动态SQL

    在mybatis中,它提供了一些动态sql标签,可以让程序员更快的进行mybatis的开发,这些动态sql可以通过sql的可重用性。

    常用的动态sql标签:if标签、where标签、sql片段、foreach标签

    If标签/where标签

    <select id="getStudentByDnynaicSql" parameterType="com.yu.domain.StudentWrapper"
        resultType="com.yu.domain.Student">
    
        select * from student
        //where默认去掉第一个AND
        <where>
            <if test="student!=null">
            <if test="student.name!=null and student.name!=''">
                name=#{student.name}
            </if>
    
            <if test="student.age!=null and student.age!=''">
                and age=#{student.age}
            </if>
        </if>
        </where>
    </select>
    

    Mapper接口:

    public List<Student> getStudentByDnynaicSql(StudentWrapper studentWrapper) throws Exception;
    

    测试代码:

        public void getStudentByDnynaicSql() throws Exception {
        SqlSession session = sqlSessionFactory.openSession();
        // 拿到代理对象
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        StudentWrapper studentWrapper = new StudentWrapper();
        Student students = new Student();
        //students.setName("Ronaldo");
        students.setAge(20);
        studentWrapper.setStudent(students);
        List<Student> studentListByWrapper = mapper.getStudentByDnynaicSql(studentWrapper);
        System.out.println(studentListByWrapper);
        session.close();
    }
    

    此时我将students.setName("Ronaldo");注释掉。

    少了name=?原因是if语句中做了判断。

    SQL片段

    Sql片段可以让代码有更高的可重用性

    Sql片段需要先定义后使用


    <sql id="sqlSection">
    <if test="student!=null">
    <if test="student.name!=null and student.name!=''">
    name=#{student.name}
    </if>

            <if test="student.age!=null and student.age!=''">
                and age=#{student.age}
            </if>
        </if>
    </sql>
    

     <select id="getStudentByDnynaicSql" parameterType="com.yu.domain.StudentWrapper"
        resultType="com.yu.domain.Student">
    
        select * from student
        <where>
            <include refid="sqlSection"></include>
        </where>
    </select>
    

    使用sql标签定义sql片段,用include标签引入sql片段

    foreach

    1) 修改包装pojo

    public class StudentWrapper {
     public Student getStudent() {
        return student;
    }
    
    public void setStudent(Student student) {
        this.student = student;
    }
    
    private Student student;
    private List<Integer> list;
    public List<Integer> getList() {
        return list;
    }
    
    public void setList(List<Integer> list) {
        this.list = list;
    }
     
    }
    

    2)映射文件:

    <!-- foreach标签 -->
    <select id="selectStudentByforeach" resultType="com.yu.domain.Student" 
        parameterType="com.yu.domain.StudentWrapper"> 
         select * from student 
         <where>
         <foreach collection="list" item="items" open="And 
        (" close=")" separator="or">
        age=#{items} 
        </foreach>
         </where>
     </select>
    

    Mapper接口:

    public List<Student> selectStudentByforeach(StudentWrapper studentWrapper) throws Exception;
    

    测试:

    @Test
    public void getStudentByDnynaicSql() throws Exception {
        SqlSession session = sqlSessionFactory.openSession();
        // 拿到代理对象
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        StudentWrapper studentWrapper = new StudentWrapper();
        List<Integer> list=new ArrayList<>();
        list.add(10);
        list.add(20);
        studentWrapper.setList(list);
         List<Student> selectStudentByforeach = mapper.selectStudentByforeach(studentWrapper);
        System.out.println(selectStudentByforeach);
        session.close();
    }
    

    6.mybatis与hibernate的区别及各自应用场景

    Mybatis技术特点:

    1、 通过直接编写SQL语句,可以直接对SQL进行性能的优化;

    2、 学习门槛低,学习成本低。只要有SQL基础,就可以学习mybatis,而且很容易上手;

    3、 由于直接编写SQL语句,所以灵活多变,代码维护性更好。

    4、 不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。

    Hibernate技术特点:

    1、 标准的orm框架,程序员不需要编写SQL语句。

    2、 具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。

    3、 学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。

    4、 程序员不能自主的去进行SQL性能优化。

    Mybatis应用场景:

    需求多变的互联网项目,例如电商项目。

    Hibernate应用场景:

    需求明确、业务固定的项目,例如OA项目、ERP项目等。

    相关文章

      网友评论

        本文标题:MyBatis(三)配置文件,输入输出映射,动态SQL

        本文链接:https://www.haomeiwen.com/subject/gzwtgttx.html