映射元文件
cache
– 该命名空间的缓存配置。cache-ref
– 引用其它命名空间的缓存配置。resultMap
– 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。sql
– 可被其它语句引用的可重用语句块。insert
– 映射插入语句。update
– 映射更新语句。delete
– 映射删除语句。select
– 映射查询语句。
select
参数类型为long,结果类型为Map
<select id="selectMap" parameterType="long" resultType="map"> 这里的long和map都是系统预定义的别名
select * from t_users where id=#{id}
</select>
修改接口
public interface UserMapper {
Map<String,Object> selectMap(Long id);
}
调用
@Test
public void testSelectMap() {
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
Map<String, Object> res = userMapper.selectMap(1L);
System.out.println(res);
session.close();
}
id | 在命名空间中唯一的标识符,可以被用来引用这条语句。对应Mapper接口中的方法名称 |
---|---|
parameterType | 将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。 |
resultType | 期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合中元素的类型UserBean,而不是集合本身的类型List。 resultType 和 resultMap 之间只能同时使用一个。一般用于列名称和对象属性名称一致时 |
resultMap | 对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。 |
表定义
create table t_users(
id bigint primary key auto_increment,
username varchar(20) not null unique,
password varchar(20) not null,
birth datetime default now(),
sex boolean default 1,
salary numeric(8,2)
)engine=innodb default charset utf8;
实体 类定义
@Data
public class UserBean implements Serializable {
private Long id;
private String username;
private String password;
private Date birth;
private Boolean sex;
private Double salary;
}
引入列名称和属性名称一一对应【名称对应,没有顺序的概念】,所以使用resultType指定返回类型。如果有不对应的内容则返回为null
<select id="load" parameterType="long" resultType="com.yan.entity.UserBean">
select * from t_users where id=#{id}
</select>
假设列名和属性名称不一致,则需要使用resultMap定义对应关系
create table t_users(
id bigint primary key auto_increment,
username varchar(20) not null unique,
password varchar(20) not null,
birth datetime default now(),
sex boolean default 1,
salary numeric(8,2)
)engine=innodb default charset utf8;
实体类定义
@Data
public class UserBean implements Serializable {
private Long id1;
private String username2;
private String password3;
private Date birth4;
private Boolean sex5;
private Double salary6;
}
由于表中的列名称和实体类中的属性名称不一致,所以需要通过resultMap声明对应关系
<resultMap id="userMapper" type="com.yan.entity.UserBean">
<id column="id" property="id1" javaType="long"/>
<result column="username" property="username2" javaType="java.lang.String"/>
<result column="password" property="password3"/>
<result column="birth" property="birth4" jdbcType="DATE"/>
<result column="sex" property="sex5"/>
<result column="salary" property="salary6"/>
</resultMap>
resultMap
元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets
数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap
能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
resultMap的子标签
id
– 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能result
– 注入到字段或 JavaBean 属性的普通结果
子标签的属性
property | 映射到列结果的字段或属性。如果 JavaBean 有这个名字的属性(property),会先使用该属性。否则 MyBatis 将会寻找给定名称的字段(field)。 无论是哪一种情形,你都可以使用常见的点式分隔形式进行复杂属性导航。 比如,你可以这样映射一些简单的东西:“username”,或者映射到一些复杂的东西上:“address.street.number”。 |
---|---|
column | 数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。 |
javaType | 一个 Java 类的全限定名,或一个类型别名(关于内置的类型别名,可以参考上面的表格)。 如果你映射到一个 JavaBean,MyBatis 通常可以推断类型。然而,如果你映射到的是 HashMap,那么你应该明确地指定 javaType 来保证行为与期望的相一致。 |
jdbcType | JDBC 类型,所支持的 JDBC 类型参见这个表格之后的“支持的 JDBC 类型”。 只需要在可能执行插入、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 编程,你需要对可以为空值的列指定这个类型。 |
resultMap的属性
id | 当前命名空间中的一个唯一标识,用于标识一个结果映射。 |
---|---|
type | 类的完全限定名, 或者一个类型别名,用于指定返回值的类型。 |
autoMapping | 如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。 |
引入resultMap
<select id="selectAll" resultMap="userMapper"> 其中userMapper就是<resultMap>的id
select * from t_users
</select>
insert
<insert id="save" parameterType="com.yan.entity.UserBean" useGeneratedKeys="true" keyProperty="id">
insert into t_users(username,password) values(#{username},#{password})
</insert>
在oracle中没有auto_increment,子增长需要依赖sequence序列对象
<insert id="insertUser" parameerType="com.yan.entity.UserBean">
<selectKey keyProperty="id" resultType="long" order="BEFORE"> 对应的属性名为id,对应的类型为long,执行时机为insert语句之前
select seq1.nextval from dual oracle中的sql语句,用于执行查询一个自增长的id值
</selectKey>
insert into t_users(id, username, password) values (#{id}, #{username}, #{password})
</insert>
selectKey 元素的属性
keyProperty | selectKey 语句结果应该被设置到的目标属性。如果生成列不止一个,可以用逗号分隔多个属性名称。 |
---|---|
keyColumn | 返回结果集中生成列属性的列名。如果生成列不止一个,可以用逗号分隔多个属性名称。 |
resultType | 结果的类型。通常 MyBatis 可以推断出来,但是为了更加准确,写上也不会有什么问题。MyBatis 允许将任何简单类型用作主键的类型,包括字符串。如果生成列不止一个,则可以使用包含期望属性的 Object 或 Map。 |
order | 可以设置为 BEFORE 或 AFTER 。如果设置为 BEFORE ,那么它首先会生成主键,设置 keyProperty 再执行插入语句。如果设置为 AFTER ,那么先执行插入语句,然后是 selectKey 中的语句 - 这和 Oracle 数据库的行为相似,在插入语句内部可能有嵌入索引调用。 |
update 和 delete
<delete id="remove" parameterType="long">
delete from t_users where id=#{id}
</delete>
<update id="modify" parameterType="com.yan.entity.UserBean">
update t_users set username=#{username},password=#{password} where id=#{id}
</update>
##sql
这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值
<sql id="cols">
id,username,password,birth,sex,salary
</sql>
<select id="load" parameterType="long" resultType="com.yan.entity.UserBean">
select <include refid="cols"></include> from t_users where id=#{id}
</select>
在日志系统中查看执行的sql语句为
com.yan.dao.UserMapper.load ==> Preparing: select id,username,password,birth,sex,salary from t_users where id=?
com.yan.dao.UserMapper.load ==> Parameters: 3(Long)
com.yan.dao.UserMapper.load <== Columns: id, username, password, birth, sex, salary
com.yan.dao.UserMapper.load <== Row: 3, 小吕2, 266666, 2021-04-19 10:12:28, 1, null
com.yan.dao.UserMapper.load <== Total: 1