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