1 动态SQL
XML版本
<select id="findSelective" parameterType="cn.xdl.ydma.entity.User">
select *
from user
<where>
<if test="name != null">
name=#{name,jdbcType=VARCHAR},
</if>
<if test="nickName != null">
and nick_name=#{nickName,jdbcType=VARCHAR},
</if>
<if test="sex != null">
and sex=#{sex,jdbcType=VARCHAR},
</if>
</where>
</select>
注解版本
public String findSelective(User record) {
SQL sql = new SQL();
sql.SELECT("*");
sql.FROM("user");
if(record.getName() != null) {
sql.WHERE("name = #{name,jdbcType=VARCHAR}");
}
if(record.getNickName() != null) {
sql.WHERE("nick_name=#{nickName,jdbcType=VARCHAR}");
}
if(record.getSex() != null) {
sql.WHERE("sex=#{sex,jdbcType=VARCHAR}");
}
return sql.toString();
}
2 关联查询映射
注解版本
使用one=@One或many=@Many加载关联表数据
首先需要在实体类中,追加关联属性,用于存储关联表数据;
public class Direction {
private Integer id;
private String name;
//用于存储关联的学科数据
private List subjects;
//set和get方法
}
然后再查询语句中,对关联属性使用@One或@Many描述映射;
@Select({
"select",
"id, name",
"from direction"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
@Result(column="name", property="name", jdbcType=JdbcType.VARCHAR),
@Result(property="subjects",javaType=List.class,column="id",
many=@Many(select="cn.xdl.ydma.dao.SubjectMapper.selectByDirectionId"))
})
List<Direction> selectAll();
SubjectMapper中的selectByDirectionId方法定义
@Select({
"select",
"id, name, direction_id",
"from subject",
"where direction_id = #{direction_id,jdbcType=INTEGER}"
})
@Results({
@Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
@Result(column="name", property="name", jdbcType=JdbcType.VARCHAR),
@Result(column="direction_id", property="directionId", jdbcType=JdbcType.INTEGER)
})
List<Subject> selectByDirectionId(Integer direction_id);
XML版本
n+1个SQL加载
<select id="selectAll" resultMap="BaseResultMap1">
select
<include refid="Base_Column_List" />
from direction
</select>
<resultMap id="BaseResultMap1" type="cn.xdl.ydma.entity.Direction">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<!-- 描述subjects关联属性的加载 -->
<collection property="subjects" javaType="java.util.List" column="id"
select="cn.xdl.dyma.dao.SubjectMapper.selectByDirectionId">
</collection>
</resultMap>
1个join SQL加载
<select id="selectAll1" resultMap="BaseResultMap2">
select d.id did,d.name dname,s.id sid,s.name sname,s.direction_id
from direction d join subject s on(d.id=s.direction_id)
</select>
<resultMap id="BaseResultMap1" type="cn.xdl.ydma.entity.Direction">
<id column="did" jdbcType="INTEGER" property="id" />
<result column="dname" jdbcType="VARCHAR" property="name" />
<collection property="subjects" javaType="java.util.List"
ofType="cn.xdl.ydma.entity.Subject">
<id column="sid" jdbcType="INTEGER" property="id" />
<result column="sname" jdbcType="VARCHAR" property="name" />
<result column="direction_id" jdbcType="VARCHAR" property="directionId" />
</collection>
</resultMap>
@Many等价于< collection>作用,@One等价于< association>。< association>使用方法与< collection>相似。
3 MyBatis缓存
MyBatis缓存有两级,一级缓存是SqlSession级别的,二级缓存是SqlSessionFactory级别的。 MyBatis缓存针对查询有效,对于增删改同步缓存。缓存淘汰策略使用的是最近最少使用原则LRU。
SqlSession一级缓存(默认是开启)
使用同一个SqlSession执行sql多次,只查询DB一次,其他都从缓存获取。(缓存的是对象,sql参数不同会查询DB)
@Test
public void test3() {
SqlSession sqlSession = factory.openSession();
DirectionMapper dao = sqlSession.getMapper(DirectionMapper.class);
Direction d1 = dao.selectByPrimaryKey(1);
System.out.println(d1);
//sqlSession.clearCache();//清除缓存
Direction d2 = dao.selectByPrimaryKey(1);
System.out.println(d2);
sqlSession.close();
}
SqlSessionFactory二级缓存(默认是关闭)
一级缓存必须是同一个sqlsession对象,遇到不同的sqlsession对象查询无效。如果需要在多个不同的sqlsession对象之间共享缓存数据,可以开启二级缓存。
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
在SQL定义文件中添加
//XML SQL使用
<cache></cache>
//注解SQL使用
@CacheNamespace//等价于XML中使用二级缓存的标记
提示:SpringBoot默认已经打开了二级缓存的开启设置,不用再定义< setting>参数了。