个人笔记,如有错误,恳请批评指正。
修改配置文件deptMapper.xml,添加
<!-- 动态Sql语句 --><!-- 根据多个条件生成动态的sql语句,查询信息 --><!-- 弊端:当不存在条件时,会查询所有的数据,改用choose可以解决问题 --><select id="selectDeptUseIf" parameterType="Dept" resultMap="deptResultMap"><!-- 若字段名与属性名一致可以直接用resultType="Dept" --> select * from dept where 1=1 <!-- 直接写属性,不需要#{},and不能丢 --> <if test="deptId!=null">and dept_id = #{deptId}</if> <if test="deptAddress!=null">and dept_address = #{deptAddress}</if> <if test="deptName!=null">and dept_name = #{deptName}</if></select>修改DeptDaoImpl.java,添加selectListUseIf方法:
//根据参数使用配置文件的IF语句自动填充查询的过滤条件 public List<Dept> selectDeptUseIf(Dept dept){ List<Dept> list = null; try { session = MybatisSessionFactory.getSession(); list = session.selectList("cn.ustb.entity.DeptMapper.selectDeptUseIf", dept); session.commit(); } catch (Exception e) { e.PRintStackTrace(); session.rollback(); } return list; }修改配置文件deptMapper.xml,添加
<!-- 动态Where条件 ,一般也需要与if结合使用,与纯if比较,省略了where 1=1--><!-- 如果需要去掉1=1,可用where --><select id="selectDeptUseWhere" parameterType="Dept" resultMap="deptResultMap"> select * from dept <where> <if test="deptId!=null">and dept_id = #{deptId}</if> <if test="deptAddress!=null">and dept_address = #{deptAddress}</if> <if test="deptName!=null">and dept_name = #{deptName}</if> </where></select>修改配置文件deptMapper.xml,添加
<!-- choose 用choose时,前面的条件符合就不再执行之后的条件--><select id="selectDeptUseChoose" parameterType="Dept" resultMap="deptResultMap"> select * from dept <where> <choose> <when test="deptId != null">and dept_id = #{deptId}</when> <when test="deptAddress != null">and dept_address = #{deptAddress}</when> <when test="deptName != null">and dept_name = #{deptName}</when> <otherwise>1=2</otherwise> </choose> </where></select>修改配置文件deptMapper.xml,添加
<!-- 动态set语句可以用来更新数据 --><update id="updateDeptUseSet" parameterType="Dept"> update dept <set> <if test="deptAddress!=null">dept_address = #{deptAddress}</if> <if test="deptName!=null">dept_name = #{deptName}</if> </set> where dept_id = #{deptId}</update>修改配置文件deptMapper.xml,添加
<!-- 若要查询多个id的数据 --><!-- 定义根据多个部门ID查询部门相关部门信息的SQL语句 ,resultMap的值是指集合里元素的类型,parameterType不用指定 --><!-- foreach --><select id="selectDeptUseForeach" resultMap="deptResultMap"> select * from dept where dept_id in (<!-- collection="array或list",array用来对应参数为数组,list对应参数为 集合 --> <foreach collection="array" item="deptId" separator=","> #{deptId} </foreach> )</select>修改配置文件deptMapper.xml,添加
<insert id="insertDeptUseInclude" parameterType="Dept"> insert into dept <include refid="key"></include> values <include refid="value"></include></insert><sql id="key"> <trim suffixOverrides="," prefix="(" suffix=")"> <if test="deptName!=null">dept_name,</if> <if test="deptAddress!=null">dept_address,</if> </trim></sql><sql id="value"> <trim suffixOverrides="," prefix="(" suffix=")"> <if test="deptName!=null">#{deptName},</if> <if test="deptAddress!=null">#{deptAddress},</if><!-- #{} necessary --> </trim></sql>(重点加入级联的查询语句),并映射文件信息到mybatis-config.xml中: DeptMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.ustb.entity.DeptMapper"> <resultMap type="Dept" id="deptResultMap"> <id column="dept_id" property="deptId" /> <result column="dept_name" property="deptName" /> <result column="dept_address" property="deptAddress" /> </resultMap></mapper>EmpMapper.xml,配置多对一的关联
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.ustb.entity.EmpMapper"> <resultMap type="Emp" id="empResultMap"> <id column="emp_id" property="empId"/> <result column="emp_name" property="empName"/> <result column="emp_age" property="empAge"/> <result column="emp_gender" property="empGender"/> <association property="dept" column="dept_id" resultMap="cn.ustb.entity.DeptMapper.deptResultMap"></association> </resultMap> <select id="selectEmp" parameterType="string" resultMap="empResultMap"> select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id where e.emp_name = #{empName} </select></mapper>DeptMapper.xml文件,配置resultMap(重点是collection配置)和查询SQL语句:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.ustb.entity.DeptMapper"> <resultMap type="Dept" id="deptResultMap"> <id column="dept_id" property="deptId" /> <result column="dept_name" property="deptName" /> <result column="dept_address" property="deptAddress" /> <collection property="emps" resultMap="cn.ustb.entity.EmpMapper.empResultMap"></collection><!-- 没有column --> </resultMap> <select id="selectDept" parameterType="String" resultMap="deptResultMap"> select d.*,e.* from dept d inner join emp e on d.dept_id = e.dept_id where d.dept_name = #{deptName} </select></mapper>不用配置对一关联
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.ustb.entity.EmpMapper"> <resultMap type="Emp" id="empResultMap"> <id column="emp_id" property="empId"/> <result column="emp_name" property="empName"/> <result column="emp_age" property="empAge"/> <result column="emp_gender" property="empGender"/></resultMap></mapper>DeptMapper.xml *值得注意的是,如果在各自的resultMap相互配置了引用,在查询时会导致堆栈溢出的异常。解决的办法是在映射文件中分割resultMap,在查询时查询一方的同时避免迭代。*
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.ustb.entity.DeptMapper"> <!-- 缓存的第二级开关,写上即开启 --> <!-- 一级默认开启,二级默认关闭,三级默认开启 --> <cache eviction="LRU" size="2" readOnly="false"></cache> <resultMap type="Dept" id="deptResultMap"> <id column="dept_id" property="deptId" /> <result column="dept_name" property="deptName" /> <result column="dept_address" property="deptAddress" /> </resultMap> <resultMap type="Dept" id="deptExtResultMap" extends="deptResultMap"> <collection property="emps" resultMap="cn.ustb.entity.EmpMapper.empResultMap"></collection><!-- resultMap是empResultMap而不是empExtResultMap,即没有配置多的属性,避免了相互查询时的内存溢出 --> </resultMap> <select id="selectDept" parameterType="String" resultMap="deptExtResultMap" useCache="true"><!-- 缓存的三级开关 语句级,默认开启 --> select d.*,e.* from dept d inner join emp e on d.dept_id = e.dept_id where d.dept_name = #{deptName} </select> <select id="selectDeptById" parameterType="string" resultMap="deptExtResultMap"> select d.*,e.* from dept d inner join emp e on d.dept_id = e.dept_id where d.dept_id = #{deptId} </select></mapper>EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.ustb.entity.EmpMapper"> <resultMap type="Emp" id="empResultMap"> <id column="emp_id" property="empId" /> <result column="emp_name" property="empName" /> <result column="emp_age" property="empAge" /> <result column="emp_gender" property="empGender" /> </resultMap> <resultMap type="Emp" id="empExtResultMap" extends="empResultMap"> <association property="dept" column="dept_id" resultMap="cn.ustb.entity.DeptMapper.deptResultMap"></association> <!-- 同样,引用的是deprResultMap,没有配置多的属性 --> </resultMap> <select id="selectEmp" parameterType="string" resultMap="empExtResultMap"> select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id where e.emp_name = #{empName} </select></mapper>DeptDaoImpl.java,查询部门员工信息,返回类型为List,关键代码:
public List<Dept> selectDeptEmpList(Dept dept){ SqlSession session=null; List<Dept> deps=null; try{ session=MyBatisUtil.getSession(); deps=session.selectList("cn.ustb.entity.DeptMapper.selectDeptEmpList",dept); session.commit(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); session.rollback(); }finally{ MyBatisUtil.closeSession(); } return deps; }EmpDaoImpl.java查询员工及其所在部门信息,返回类型为List< Emp >,关键代码
public List<Emp> selectEmpDeptList(Emp emp){ SqlSession session=null; List<Emp> emps=null; try{ session=MyBatisUtil.getSession(); emps=session.selectList("cn.ustb.entity.EmpMapper.selectEmpDeptList",emp); session.commit(); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); session.rollback(); }finally{ MyBatisUtil.closeSession(); } return emps; }Mybatis和hibernate一样,也使用缓存;缓存分为一级缓存和二级缓存,一级缓存指在SqlSession内共享数据;二级缓存能被所有的SqlSession共享。
在mybatis-config.xml的主配置文件中进行配置:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <settings> <!-- 默认有启用全局缓存的,禁用可以把value设为false,如果这里设为false,Mapper.xml或SQL语句级的缓存配置不再起作用 --> <setting name="cacheEnabled" value="true"/> </settings><!—省略其它配置信息 --></configuration>使用二级缓存机制:需要开启全局缓存,文件级缓存 ,语句级缓存,才能使用二级缓存。默认情况下文件级缓存没有开启。
<!-- 缓存的第二级开关,写上即开启 --> <!-- 一级默认开启,二级默认关闭,三级默认开启 --> <cache eviction="LRU" size="2" readOnly="false"></cache>关于二级缓存的配置,在使用者手册中有详细说明,摘取如下内容:
可用的回收算法如下: • LRU – 最近最少使用:移出最近最长时间内都没有被使用的对象。 • FIFO – 先进先出:移除最先进入缓存的对象。 • SOFT – 软引用: 基于垃圾回收机制和软引用规则来移除对象(空间内存不足时才进行回收)。 • WEAK – 弱引用: 基于垃圾回收机制和弱引用规则(垃圾回收器扫描到时即进行回收)。 默认使用LRU。
flushInterval :设置任何正整数,代表一个以毫秒为单位的合理时间。默认是没有设置,因此 没有刷新间隔时间被使用,在语句每次调用时才进行刷新。 Size:属性可以设置为一个正整数,您需要留意您要缓存对象的大小和环境中可用的内存空间。 默认是1024。 readOnly:属性可以被设置为true 或false。只读缓存将对所有调用者返回同一个实例。因此这些对象都不能被修改,这可以极大的提高性能。可写的缓存将通过序列化来返回一个缓存对象的拷贝。这会比较慢,但是比较安全。所以默认值是false。
在相关的Mapper.xml文件中配置SQL查询,关键代码如下(示例):
<!-- useCache默认值为true,设为false时缓存不起作用 --> <select id="selectOne" parameterType="int" resultMap="deptResultMap" useCache="true" > select * from dept where dept_id=#{id} </select>如果 MyBatis 使用 XML 配置,那不可避免地会遇到一些对 XML 来说是特殊的字符。如小于号 “<”,因此要进行转义。主要有两个方式:
下面是五个在 XML 文档中预定义好的转义实体: - <; < 小于号 - >; > 大于号 - &; & - &apos; ’ 单引号 - "; ” 双引号 - 小于等于“<=”,其转义为:<;= - 大小等于“>=”,转义为:>;=
CDATA 部件以”
<select id= "selectBlog_use_collection" resultMap= "blogResult" ><![CDATA[ SELECT id , title, author_id as authored FROM BLOG WHERE ID > 0 and ID < 10 ]]> </select>“
新闻热点
疑难解答