映射器的配置元素有select/insert/update/delete/sql/resultMap/cache/cache-ref八个常用的,parameterMap基本不用,也不建议使用。

MyBatis3官方文档:http://www.mybatis.org/mybatis-3/zh/configuration.html

本blog实例代码:https://github.com/JeeLearner/learning-ssmr   chapter05和chapter05.2

一、select元素

在工作中用的最多的是id,parameterType、resultType、resultMap。如果要设置缓存,还会使用到flushCache、useCache。其它的都不常用。

1.自动映射和驼峰映射

在mybatis-config.xml中settings元素中,autoMapping代表自动映射,默认值PARTIAL;mapUnderscoreToCamelCase代表驼峰映射,默认值false。

2.传递多个参数

(1)使用map传递参数。可读性差,维护困难,摒弃。

(2)@Param注解传递多个参数。参数小于等于5个,可使用。比用JavaBean更好。

(3)参数大于5个时,使用JavaBean方式。

(4)混合使用。

public interface RoleDao {public List<Role> findRolesByMap(Map<String, Object> parameterMap);public List<Role> findRolesByAnnotation(@Param("roleName") String rolename, @Param("note") String note);public List<Role> findRolesByBean(RoleParams roleParam);public List<Role> findByMix(@Param("params") RoleParams roleParams, @Param("page") PageParams pageParams);
}
<?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="com.ssmr.chapter05.dao.RoleDao"><select id="findRolesByMap" parameterType="map" resultType="role">select id, role_name as roleName, note from t_rolewhere role_name like concat('%', #{roleName}, '%')and note like concat('%', #{note}, '%')</select><select id="findRolesByAnnotation" resultType="role">select id,role_name as roleName, note from t_rolewhere role_name like concat('%', #{roleName}, '%')and note like concat('%', #{note}, '%')</select><select id="findRolesByBean" parameterType="com.ssm.chapter5.param.RoleParams"resultType="role">select id, role_name as roleName, note from t_rolewhere role_name like concat('%', #{roleName}, '%')and note like concat('%',#{note}, '%')</select><select id="findByMix" resultType="role">select id, role_name as roleName, note from t_rolewhere role_name like concat('%',#{params.roleName}, '%')and note like concat('%', #{params.note}, '%')limit #{page.start}, #{page.limit}</select>
</mapper>

3.使用resultMap映射结果集

id是标识,type代表哪个类作为其映射的类,可以是别名或全限定名。

子元素id代表resultMap的主键,而result代表其属性。

<?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="com.ssmr.chapter05.dao.RoleDao"><resultMap id="roleMap" type="role"><id property="id" column="id" /><result property="roleName" column="role_name" /><result property="note" column="note" /></resultMap><select id="getRoleUseResultMap" parameterType="long" resultMap="roleMap">select id, role_name, note from t_role where id = #{id}</select>
</mapper>

4.分页参数RowBounds

只需给接口增加一个RowBounds参数即可。

public interface RoleDao {public List<Role> findRolesByRowBounds(@Param("roleName") String rolename, @Param("note") String note, RowBounds rowBounds);
}
<select id="findByRowBounds" resultType="role">select id, role_name as roleName, notefrom t_rolewhere role_name like concat('%',#{params.roleName}, '%')and note like concat('%', #{params.note}, '%')limit #{page.start}, #{page.limit}
</select>

测试:

public class Main {public static void main(String[] args) {testRowBounds();}public static void testRowBounds(){SqlSession sqlSession = null;try {Logger log = Logger.getLogger(Main.class);sqlSession = SqlSessionFactoryUtil.openSqlSession();RoleDao roleDao = sqlSession.getMapper(RoleDao.class);//offset属性是偏移量,即从第几行开始读取记录//limit是限制条数RowBounds rowBounds = new RowBounds(0, 20);List<Role> roleList = roleDao.findRolesByRowBounds("role_name", "note", rowBounds);System.out.println(roleList.size());} catch (Exception e) {e.printStackTrace();}finally {if(sqlSession != null){sqlSession.close();}}}
}


二、insert元素

<insert id="insertRole" parameterType="role">insert into t_role(role_name, note) values(#{roleName},#{note})
</insert>

主键回填:

useGeneratedKeys:获取数据库生成的主键,默认false。代表采用JDBC的Statement对象的getGeneratedKeys方法返回主键。

keyProperty代表将用哪个POJO的属性去匹配这个主键。

<insert id="insertRole" parameterType="role" useGeneratedKeys="true" keyProperty="id">insert into t_role(role_name, note)values(#{roleName},#{note})
</insert>

自定义主键:

规则:当角色表记录为空时id设置为1;不为空时,id设置为当前id加3。

keyProperty指定了采用哪个属性作为POJO的主键

resultType代表将返回一个long类型的结果集

order设置为BEFORE说明它将于当前定义的SQL前执行。

order设置为AFTER说明它会在插入语句之后执行。比如一些插入语句内部可能有嵌入索引调用。

<insert id="insertRole" parameterType="role"><selectKey keyProperty="id" resultType="long" order="BEFORE">select if (max(id) = null, 1, max(id) + 3)from t_role</selectKey>insert into t_role2(id, role_name, note) values(#{id}, #{roleName},#{note})
</insert>


三、update元素和delete元素

<update id="updateRole" parameterType="role">update t_role set role_name = #{roleName}, note = #{note}where id = #{id}
</update><delete id="deleteRole" parameterType="long">delete from t_role where id = #{id}
</delete>


四、sql元素

sql元素的作用在于可以定义一条SQL的一部分。

1.基本用法:

<resultMap id="roleMap" type="role"><id property="id" column="id" /><result property="roleName" column="role_name" /><result property="note" column="note" />
</resultMap><sql id="roleCols">id, role_name, note
</sql>
<select id="getRoleUseResultMap" parameterType="long" resultMap="roleMap">select <include refid="roleCols"/>from t_rolewhere id = #{id}
</select>

2.支持变量传递:

在include元素中定义了一个命名为alias的变量,其值是SQL中表t_role的别名r。然后sql元素就可以使用这个变量名了。

<sql id="roleCols">${alias}.id, ${alias}.role_name, ${alias}.note
</sql>
<select id="getRoleUseResultMap" parameterType="long" resultMap="roleMap">select <include refid="roleCols"><property name="alias" value="r"/></include>from t_role rwhere id = #{id}
</select>


五、参数

1.概述

<insert id="insertRole" parameterType="role" useGeneratedKeys="true" keyProperty="id">insert into t_role(role_name, note)values(#{roleName, typeHandler=org.apache.ibatis.type.StringTypeHandler},#{note})
</insert>

事实上mybatis会根据javaType和jdbcType自动检测使用哪个typeHandler。但是我们可以自定义typeHandler。

#{age, javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}

mybatis也提供了一些对控制数值的精度支持。如下只保留两位有效数字。

#{width, javaType=double,jdbcType=NUMERIC,numericScale=2}

2.存储过程参数支持

参数类型:输入参数、输出参数、输入输出参数

#{id, mode=IN}
#{roleName, mode=OUT}
#{note, mode=INOUT}

六、resultMap元素

1.resultMap元素构成

<resultMap><constructor><idArg/><arg/></constructor><id/><result/><association/><collection/><discriminator>< case/></discriminator>
</resultMap>

constructor元素用于配置构造方法。一个POJO可能不存在没有参数的构造方法,可以使用constructor进行配置。假设Role不存在没有参数的构造方法,它的构造方法声明为public Role(Integer id, String roleName)。那么需要配置结果集,如下:

<resultMap ......><constructor><idArg column="id" javaType="int"/><arg column="role_name" javaType="string"/></constructor>......
</resultMap>

2.使用map存储结果集

一般而言,任何select语句都可以使用map存储:

<select id="findColorByNote" parameterType="string" resultType="map">select id, color, notefrom t_colorwhere note like concat('%', #{note}, '%')
</select>

但是map可读性差,更多时候会使用POJO方式。

3.使用POJO存储结果集

resultMap元素的子元素id表示这个对象的主键,property代表着POJO的属性名称。

<resultMap id="roleMap" type="role"><id property="id" column="id"/><result property="roleName" column="role_name"/><result property="note" column="note"/>
</resultMap><select id="getRoleUseResultMap" parameterType="long" resultMap="roleMap">select id, role_name, notefrom t_rolewhere id = #{id}
</select>

七、级联

1.概述

association一对一级联

collection一对多级联

discriminator鉴别器级联

2.简单DEMO示例

级联实例完整版DEMO:级联DEMO

public class Employee {private Long id;private String realName;//涉及鉴别器级联private SexEnum sex = null;private Date birthday;private String mobile;private String email;private String position;private String note;//工牌按一对一级联private WorkCard workCard;//雇员任务,一对多级联private List<EmployeeTask> employeeTaskList = null;
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.ssmr.chapter05.dao.EmployeeDao"><resultMap id="employeeMap" type="com.ssmr.chapter05.pojo.Employee"><id column="id" property="id" /><result column="real_name" property="realName" /><result column="sex" property="sex"typeHandler="com.ssmr.chapter05.typehandler.SexTypeHandler" /><result column="birthday" property="birthday" /><result column="mobile" property="mobile" /><result column="email" property="email" /><result column="position" property="position" /><result column="note" property="note" /><!--雇员工牌表一对一级联--><association property="workCard" column="id"select="com.ssmr.chapter05.dao.EmployeeTaskDao.getEmployeeTaskByEmpId"/><!--雇员和雇员任务一对多级联--><collection property="employeeTaskList" column="id"fetchType="eager"select="com.ssmr.chapter05.dao.EmployeeTaskDao.getEmployeeTaskByEmpId"/><!--鉴别器级联--><discriminator javaType="long" column="sex"><case value="0" resultMap="maleHealthFormMapper" /><case value="1" resultMap="femaleHealthFormMapper"/></discriminator></resultMap><resultMap id="femaleHealthFormMapper" type="com.ssmr.chapter05.pojo.FemaleEmployee" extends="employeeMap"><!--女性和女性体检表一对一级联--><association property="femaleHealthForm" column="id"select="com.ssmr.chapter05.dao.FemaleHealthFormDao.getFemaleHealthForm"/></resultMap><resultMap id="maleHealthFormMapper" type="com.ssmr.chapter05.pojo.MaleEmployee" extends="employeeMap"><!--男性和男性体检表一对一级联--><association property="maleHealthForm" column="id"select="com.ssmr.chapter05.dao.MaleHealthFormDao.getMaleHealthForm"/></resultMap><select id="getEmployee" parameterType="long" resultMap="employeeMap">select id, real_name as realName, sex, birthday, mobile, email, position,notefrom t_employeewhere id = #{id}</select>
</mapper>

3.N+1问题

级联完成后,只要加载主信息,一些关联信息也会同时加载,有些我们是暂时不用的,这会造成浪费,服务器压力也会增大,这就是N+1问题。解决方法就是延迟加载。mybatis提供了延迟加载的功能。

4.延迟加载

在MyBatis的配置文件mybatis-config.xml中settings配置中存在两个元素可以配置级联:

lazyLoadingEnabled 延迟加载的全局开关,默认false。

aggressiveLazyLoading  延迟加载的层级开关。版本3.4.1(包含)之前默认true,之后为false。

这两个属性都是全局配置。如果不开启的话会把级联的所有数据加载;如果都开启,就是加载层级数据,如雇员下有雇员任务和工卡,aggressiveLazyLoading为true的话就会将这两个级联数据都加载出来,为false的话就都不加载出来。现在我们只想加载雇员任务而不加载工卡。怎么办呢?

<settings><!--延迟加载的开关--><setting name="lazyLoadingEnabled" value="true"/><!--层级延迟加载的开关。版本3.4.1(包含)之前为true,之后为false--><setting name="aggressiveLazyLoading" value="false"/>
</settings>

fetchType属性会处理全局定义无法处理的问题。fetchType出现在级联元素(association、collection。注意:discriminator没有这个属性)中,它存在两个值:

eager:获得当前的pojo后立即加载对应的数据。

lazy:获得当前pojo后延迟加载对应的数据。

fetch属性会忽略全局配置项lazyLoadingEnabled和aggressiveLazyLoading。

5.另一种级联

这种方式会消除N+1问题,但是会引入其他问题:SQL复杂、配置复杂、一次性取出数据会浪费内存、维护困难。

这里请读者点击链接自行查看:另一种级联DEMO

6.多对多级联

往往会拆分成两个一对多的级联。

1.POJO

public class Role{private Long id;private String roleName;private String note;//关联用户信息,一对多关联private List<User> userList;/** getter/setter **/
}  
public class User {private Long id;private String userName;private String realName;private SexEnum sex;private String moble;private String email;private String note;// 关联角色对象,一对多关联private List<Role> roleList;/** getter/setter **/
}  

2.mapper.xml  在映射器设置fetchType为lazy,这样就不会立即加载数据进来

<?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="com.ssmr.chapter05.dao.RoleDao"><resultMap type="com.ssmr.chapter05.pojo.Role" id="roleMapper"><id column="id" property="id" /><result column="role_name" property="roleName" /><result column="note" property="note" /><collection property="userList" column="id"fetchType="lazy"select="com.ssmr.chapter05.mapper.UserMapper.findUserByRoleId" /></resultMap><select id="getRole" parameterType="long" resultMap="roleMapper">select id, role_name, notefrom t_rolewhere id = #{id}</select><select id="findRoleByUserId" parameterType="long" resultMap="roleMapper">select r.id, r.role_name, r.notefrom t_role r, t_user_role urwhere r.id = ur.role_id and ur.user_id = #{userId}</select>
</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssmr.chapter05.mapper.UserMapper"><resultMap type="com.ssmr.chapter05.pojo.User" id="userMapper"><id column="id" property="id" /><result column="user_name" property="userName" /><result column="real_name" property="realName" /><result column="sex" property="sex"typeHandler="com.ssmr.chapter05.typehandler.SexTypeHandler" /><result column="mobile" property="moble" /><result column="email" property="email" /><result column="position" property="position" /><result column="note" property="note" /><collection property="roleList" column="id"fetchType="lazy"select="com.ssmr.chapter05.mapper.RoleMapper.findRoleByUserId" /></resultMap><select id="getUser" parameterType="long" resultMap="userMapper">select id, user_name, real_name, sex, moble, email, notefrom t_userwhere id =#{id}</select><select id="findUserByRoleId" parameterType="long" resultMap="userMapper">select u.id, u.user_name, u.real_name, u.sex, u.moble, u.email, u.notefrom t_user u , t_user_role urwhere u.id = ur.user_id and ur.role_id =#{roleId}</select>
</mapper>

八、缓存

1.概述

MyBatis分为一级缓存和二级缓存。

一级缓存是在SqlSession上的缓存,二级缓存是在SqlSessionFactory上的缓存。默认情况下,也就是没有任何配置的情况下,MyBatis系统会开启以及缓存,也就是对SqlSession层面的缓存,这个缓存不需要POJO对象可序列化。

2.一级缓存

对同一对象进行两次获取,如果第二次的SQL和参数都没有变化,并且缓存没有超时或者声明需要刷新时,那么它就会从缓存中取数据。

public static void testOneLevelCache() {SqlSession sqlSession = null;Logger logger = Logger.getLogger(Test.class);try {sqlSession = SqlSessionFactoryUtil.openSqlSession();RoleDao2 roleDao2 = sqlSession.getMapper(RoleDao2.class);Role2 role = roleDao2.getRole(1L);logger.info("再获取一次POJO......");Role2 role2 = roleDao2.getRole(1L);} catch(Exception ex) {ex.printStackTrace();} finally {if (sqlSession != null) {sqlSession.close();}}
}

3.二级缓存

对于不同的SqlSession对象,一级缓存是不能共享的。如下代码会执行两次SQL:

public static void testTwoLevelCache() {SqlSession sqlSession = null;SqlSession sqlSession2 = null;Logger logger = Logger.getLogger(Test.class);try {sqlSession = SqlSessionFactoryUtil.openSqlSession();sqlSession2 = SqlSessionFactoryUtil.openSqlSession();RoleDao2 roleDao2 = sqlSession.getMapper(RoleDao2.class);Role2 role2 = roleDao2.getRole(1L);//需要提交,如果是一级缓存,MyBatis才会缓存对象到SqlSessionFactory层面sqlSession.commit();logger.info("不同sqlSession再获取一次POJO......");RoleDao2 roleDao22 = sqlSession2.getMapper(RoleDao2.class);Role2 role22 = roleDao22.getRole(1L);//需要提交,MyBatis才缓存对象到SQLSessionFactorysqlSession2.commit();} catch(Exception e) {logger.info(e.getMessage(), e);} finally {if (sqlSession != null) {sqlSession.close();}if (sqlSession2 != null) {sqlSession.close();}}
}

为了使SqlSession对象之间共享相同的缓存,有时候需要开启二级缓存。

开启二级缓存只需要在RoleMapper.xml中加入下面代码:

<cache/>

这个时候MyBatis会序列化和反序列化对应的POJO,也就要求POJO是一个可序列化的对象,那么它就必须实现java.io.Serializable接口。对角色类Role对象进行缓存,那么就需要它实现Serializable接口。

4.缓存配置项、自定义和引用

测试二级缓存,只配置cache元素,加入这个元素后,MyBatis就会将对应的命名空间内所有select元素SQL查询结果进行缓存,而其中的insert、delete、update语句在操作时会刷新缓存。

<cache blocking=""readOnly=""   eviction=""flushInterval=""type=""size=""
/>

(1)type自定义缓存类,实现Cache接口即可。

在现实中,我们可以使用Redis、MongoDB或者其它常用的缓存,假设存在一个Redis的缓存实现类com.ssmr.chapter05.cache.RedisCache.那么可以这样配置:

<cache type="com.ssmr.chapter05.cache.RedisCache."><property name="host" value="localhost"/>
</cache>

这样配置后,MyBatis会启用缓存,同时调用setHost(String host)方法,去设置配置的内容。
(2)对于一些语句也需要自定义。比如对于一些查询并不想要它进行任何缓存,这时就可以通过配置改变。

<select ... flushCache="false" useCache="true"/>
<insert ... flushCache="true"/>
<update ... flushCache="true"/>
<delete ... flushCache="true"/>

以上是默认配置。flushCache代表是否刷新缓存。useCache属性是select特有的,代表是否需要使用缓存。

注意:这些缓存配置都是在一个映射器内配置的,如果其他映射器需要使用同样的配置,则可以引入缓存的配置:

<cache-ref namespace="com.ssmr.chapter05.dao.RoleDao"/>

九、存储过程

1.简述

存储过程是数据库预先编译好,放在数据库内存中的一个程序片段,性能高,可重复使用。

三种类型参数:输入参数IN、输出参数OUT、输入输出参数INOUT。

2.IN和OUT参数存储过程

这里使用Oracle数据库。

(1)场景:根据角色名称进行模糊查询其总数,然后把总数和查询日期返回给调用者。

(2)准备

存储过程如下:

CREATE OR REPLACE
PROCEDURE count_role(p_role_name IN VARCHAR,count_total OUT INT,exec_date OUT DATE)
IS
BEGIN
SELECT COUNT(*) INTO count_total FROM t_role WHERE role_name LIKE '%' || p_role_name || '%';
SELECT SYSDATE INTO exec_date FROM DUAL;
END;

创建一个POJO:

public class PdCountRoleParams {private String roleName;private int total;private Date execDate;/** getter/setter **/
}

(3)使用

<select id="countRole" parameterType="com.ssmr.chapter05.pojo.PdCountRoleParams" statementType="CALLABLE">{call count_role(#{roleName, mode=IN, jdbcType=VARCHAR},#{total, mode=OUT, jdbcType=INTEGER},#{execDate, mode=OUT, jdbcType=DATE})}
</select>

statementType为CALLABLE,说明它是在使用存储过程,不这样声明就会抛异常。

在属性上通过model设置了其输入或者输出参数,指定对应jdbcType,这样mybatis就会使用对应的typeHandler去处理对应的类型转换。

3.游标的使用

如果把jdbcType声明为CURSOR,那么它就会使用ResultSet对象处理对应的结果。

(1)场景:同样根据角色名称模糊查询角色表的数据,但要求分页查询,于是存在start和end两个参数。为了知道是否存在下一页,还会要求查出总数。

(2)准备

存储过程:

CREATE OR REPLACE
PROCEDURE find_role(p_role_name IN VARCHAR,p_start IN INT,p_end IN INT,r_count OUT INT,ref_cur OUT sys_refcursor)
AS
BEGIN
SELECT COUNT(*) INTO r_count FROM t_role WHERE role_name LIKE '%' || p_role_name || '%';
OPEN ref_cur FOR
SELECT id,role_name,note FROM(SELECT id,role_name,note,rownum AS row1 FROM t_role aWHERE a.role_name LIKE '%' || p_role_name || '%' AND rownum <=p_end)
WHERE row1>p_start;
END find_role;

定义存储游标的POJO:

参数是和存储过程一一对应的,而游标是由roleList去存储的,使用时只需为其提供映射关系即可。

public class PdFindRoleParams {private String roleName;private int start;private int end;private int total;private List<Role> roleList;/** getter/setter **/
}

(3)使用

<resultMap type="com.ssmr.chapter05.pojo.Role" id="roleMapper"><id column="id" property="id" /><result column="role_name" property="roleName" /><result column="note" property="note" />
</resultMap>
<select id="findRole" parameterType="com.ssmr.chapter05.param.PdFindRoleParams" statementType="CALLABLE">{call find_role(#{roleName, mode=IN, jdbcType=VARCHAR},#{start, mode=IN,jdbcType=INTEGER},#{end, mode=IN, jdbcType=INTEGER},#{total, mode=OUT,jdbcType=INTEGER},#{roleList,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=roleMap})}
</select>

为了使得ResultSet对应能够映射POJO,设置resultMap为roleMap。

深入MyBatis开发之mybatis映射器相关推荐

  1. Mybatis 强大的结果映射器ResultMap

    1. 前言 resultMap 元素是 MyBatis 中最重要最强大的元素.它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC ...

  2. Could not find resource——mybatis 找不到映射器xml文件

    今天用IDEA写Mybatis的时候,测试报了如图所示的错,恶心死我了,后来解决了,总结一下,防止下回跳坑,当然,也是做一个分享,如果有朋友遇到这个错,希望有所帮助 Error parsing SQL ...

  3. 享学课堂Java开发之Mybatis训练营

    目录: ┣━━1.MyBatis开发不得不知的重点 ┃    ┣━━01 mybatis开发重点知识.pdf ┃    ┣━━1.MyBatis开发重点知识.docx ┃    ┣━━2019.08. ...

  4. panic 苹果aop_Go Web开发之Revel - 拦截器

    一个拦截器是一个框架在调用action方法前或后调用的函数. 它允许一种AOP的形式, 它经常被用于做下面几种事情: Request logging Error handling Stats keep ...

  5. MyBatis学习之映射器Mapper(接口映射器+xml映射文件)

    Table of Contents 01 MyBatis映射器: 1.1 接口映射器+xml映射器 1.2 接口映射器+注解 02 接口映射器+xml映射器  方式 2.1 mybatis配置文件 引 ...

  6. [MyBatis日记](3)映射器配置文件与映射器接口

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/SunnyYoona/article/details/50659993 前一篇文章([MyBatis日 ...

  7. 【MyBatis】 ---- 映射器(接口+XML文件)

    目录 一. 配置元素 1. select元素 2. insert元素 3. sql元素 4. resultMap元素 5. resultMap元素中的级联 (代码github) 一.映射器的配置元素 ...

  8. mybatis映射器${}和#{}的区别

    mybatis映射器${}和#{}的区别 转载于:https://www.cnblogs.com/liyuchen/p/7850185.html

  9. mybatis的mapper.xml文件中含有中文注释时运行出错,mybatis配置优化和别名优化 mybatis配置之映射器说明

    记录一个发现的小问题,刚刚在UserMapper.xml文件中有一段中文注释掉的内容: <!-- <resultMap id="Usermap" type=" ...

最新文章

  1. SpringBoot 学习 | raibaby halo 之安装部署 - Ali0th
  2. MPB:林科院袁志林组-利用acdSf3/acdSr4引物快速鉴定产ACC脱氨酶细菌
  3. DataBinding初探 数据绑定的用法 ,import 集合类型,绑定的表达式,访问集合类型2...
  4. 基于TensorFlow的2个机器学习简单应用实例
  5. [python爬虫] BeautifulSoup和Selenium简单爬取知网信息测试
  6. c语言添加变量到数据库+a+ +b+ 的方法,《C程序设计基础》模拟考试题(含答案)...
  7. linux 系统调优查看排除方法
  8. VB程序打包再安装之后不含源码
  9. 安卓手机通话录音软件
  10. 傅里叶变换的矩阵分析
  11. 女性手游市场,金矿还是深坑?
  12. AES16位密钥加密解密
  13. php 内网/外网ip判断
  14. pod、pvc删不掉怎么办?
  15. 太阳系行星运行图-java多媒体实验
  16. 达梦中的连接查询方式
  17. Ruoyi若依前后端分离框架【若依登录详细过程】
  18. Turtle图形绘制(绘制奥运五环)
  19. 用计算机命令合成机械头像,PHOTOSHOP合成的逼真机械头像
  20. 按键精灵模拟键盘批量输入英文大小写

热门文章

  1. vue启动项目8080端口被占用
  2. 若依RuoYi框架数据库权限控制表解析
  3. 如何从神品屋下载废柴道士2并放入kindle
  4. 树莓派的有线网络和无线网络设置
  5. 技术前沿与经典文章35:诸葛亮千古奇文——全篇仅86字,道尽成大器秘诀
  6. git本地仓库和远程仓库关联问题
  7. Revit幕墙:这些命令在幕墙嵌板中的妙用及快速幕墙
  8. 疯子网页采集器之测试发布教程
  9. 2019河北省大学生程序设计竞赛题解(一)
  10. linux控制工业设备,恩智浦推用于工业领域的Linux发行版 助力工厂自动化