Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了
参考的官方文档,描述如下:
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。 通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
<select id="findAll" resultType="user" parameterType="user">
select *
from person
<where>
<if test="id!=0">
id=#{id}
</if>
<if test="name!=null">
and name=#{name}
</if>
<if test="sex!=0">
and sex=#{sex};
</if>
</where>
</select>
<if>
判断传入的参数是否符合判断,如果符合则执行标签内的sql语句<select id="findByIds" resultType="user" parameterType="user">
select *
from person
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
<foreach>
标签属性含义: <sql id="selectPerson">select * from person</sql>
<select id="findAll" resultType="user">
<include refid="selectPerson"></include>
</select>
public class DateTypeHandler extends BaseTypeHandler<Date> {
// 实现java类型转换成数据库类型
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
long time = date.getTime();
preparedStatement.setLong(i,time);
}
// 从数据库类型转换成java类型
@Override
public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
long aLong = resultSet.getLong(s);
Date date = new Date(aLong);
return date;
}
// 从数据库类型转换成java类型
@Override
public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
long aLong = resultSet.getLong(i);
Date date = new Date(aLong);
return date;
}
// 从数据库类型转换成java类型
@Override
public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
long aLong = callableStatement.getLong(i);
Date date = new Date(aLong);
return date;
}
}
MyBatis 可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据
<resultMap>
配置<resultMap id="studentMap" type="student">
<!--
column 代表为sql语句查询出来的列名
property 代表为实体类中的属性名
两者关系为 一个查询出来的属性 一个接收查询出来的属性
-->
<id property="studentId" column="sid"></id>
<result column="studentName" property="studentName"></result>
<result column="sexId" property="sexId"></result>
<!-- 实体类内部的属性 -->
<!-- <result column="teacherId" property="teacher.teacherId"></result>-->
<!-- <result column="teacherName" property="teacher.teacherName"></result>-->
<!--
property :实体类中声明的属性名称(private Teacher teacher)
javaType :实体类中声明的属性类型(Teacher)
-->
<association property="teacher" javaType="teacher">
<id column="teacherId" property="teacherId"></id>
<result column="teacherName" property="teacherName"></result>
</association>
</resultMap>
<select id="queryAll" resultMap="studentMap">
select *,s.studentId sid from student s,teacher t WHERE s.teacherId = t.teacherId
</select>
<resultMap>
+<collection>
做配置<resultMap id="teacherMap" type="teacher">
<id column="teacherId" property="teacherId"></id>
<result column="teacherName" property="teacherName"></result>
<!-- collection使用与association大体一致 -->
<collection property="studentList" ofType="student">
<id property="studentId" column="sid"></id>
<result column="studentName" property="studentName"></result>
<result column="sexId" property="sexId"></result>
</collection>
</resultMap>
<select id="queryOneForNum" resultMap="teacherMap">
SELECT * FROM student s,teacher t WHERE s.teacherId = t.teacherId
</select>
<resultMap>
+<collection>
做配置
近年来,注解开发越来越流行,Mybatis也可以使用注解开发方法,这样我们就可以减少编写Mapper映射文件了。
常用注解列表:
注解名 | 功能 |
---|---|
@Insert | 实现新增 |
@Update | 实现更新 |
@Delete | 实现删除 |
@Select | 实现查询 |
@Result | 实现结果集封装 |
@Results | 可以与@Result一起使用,封装多个结果集 |
@One | 实现一对一结果集封装 |
@Many | 实现一对多结果集封装 |
使用注解开发时需要配置mappers
<mappers>
<!-- 指定接口所在的包 -->
<package name="com.demonode.mapper"/>
</mappers>
扫描接口所在包后,直接在接口上使用注解进行开发
@Mapper
public interface PersonMapper {
@Select("select * from person")
public List<Person> findAll();
@Select("select * from person where id = #{id}")
public Person findOne(int id);
@Insert("insert into person values(null ,#{name},#{sex},null)")
public void addPerson(Person person);
@Update("update person set name=#{name},sex=#{sex} where id=#{id}")
public void updatePerson(Person person);
@Delete("delete from person where id=#{id}")
public void delPerson(int id);
}
<resultMap>
来实现,使用注解后,我们可以是以哦那个@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置注解 | 说明 |
---|---|
@Results | 代替的是标签该注解中可以使用单个@Result注解,也可以使用@Result集合。使用格式:@Results({@Result(),@Result()}) 或 @Results(@Result()) |
@Result | 代替了标签和标签。 |
@Select(
"select *,s.studentId sid from student s,teacher t WHERE s.teacherId = t.teacherId"
)
@Results({
@Result(column = "sid",property = "studentId"),
@Result(column = "studentName",property = "studentName"),
@Result(column = "sexId",property = "sexId"),
@Result(column = "teacherId",property = "teacher.teacherId"),
@Result(column = "teacherName",property = "teacher.teacherName"),
})
public List<student> findAll();
@Select("select * from student")
@Results({
@Result(column = "sid",property = "studentId"),
@Result(column = "studentName",property = "studentName"),
@Result(column = "sexId",property = "sexId"),
@Result(
property = "teacher",// 实例对象(属性名称)
column = "teacherId",// 查询数据的 列
javaType = teacher.class,// 接收的类型
one = @One(select = "com.demonode.mapper.StudentMapper.findOne")// 调用的方法
)
})
public List<student> findAll();
@Select("select * from teacher")
@Results({
@Result(column = "teacherId",property = "teacherId"),
@Result(column = "teacherName",property = "teacherName"),
@Result(
property = "studentList",// 实例对象(属性名称)
column = "teacherId",// 查询数据的 列
javaType = List.class,// 接收的类型
many = @Many(
select = "com.demonode.mapper.StudentMapper.findOneTeacher"
)// 调用的方法
)
})
public List<teacher> findTeacherAndStudent();