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

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片段 –>

<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项目等。

IT文库 » MyBatis(三)配置文件,输入输出映射,动态SQL
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址