普通传参
重要配置
主配置类
#指定mybatis映射文件的地址
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml
#别名
type-aliases-package: mybatisdemo1/entity
#驼峰 resultType (这个的不一样(数据库 user_name) 实体类(userName))
configuration:
mapUnderscoreToCamelCase: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
接口
Message getMessageById(@Param("id") Long id);
映射文件
namespace:mapper 接口的全限定名称
<mapper namespace="mybatisdemo1.mapper.MessageMapper">
<sql id="allMessage">
id,msg_id,status,content,deleted,create_time,update_time
</sql>
<select id="getMessageById" parameterType="long" resultType="mybatisdemo1.entity.Message">
select
<include refid="allMessage"/>
from
tb_message
where id = #{id}
</select>
自定义结果映射
接口
MessageVO getMessageVOById(Long id);
<!-- 自定义结果映射-->
<!--使用resultMap定义列和属性的关系-->
<!--定义resultMap
id:给resultMap的映射关系起个名称,唯一值
type:java类型的全限定名称
-->
<!-- column = 数据库字段, property 属性名 将数据库查出字段放入属性名字段中-->
<resultMap id="getvoMessage" type="mybatisdemo1.entity.MessageVO">
<id column="id" property="idVo"/>
<result column="msg_id" property="msgIdVo"/>
</resultMap>
<select id="getMessageVOById" parameterType="long" resultMap="getvoMessage">
select
<include refid="allMessage"/>
from
tb_message
where id = #{id}
</select>
Map传参
Message getMessageByMap(Map<String, Object> params);
<!-- map传参-->
<!--
使用Map传递参数,
在mapper文件中,获取map的值,是通过key获取的,语法:#{key}
-->
<select id="getMessageByMap" parameterType="map" resultType="mybatisdemo1.entity.Message">
select
<include refid="allMessage"/>
from
tb_message
where id = #{id} and msg_id = #{msgId}
</select>
实体传参
直接写字段名获取值
Message getMessageByMessage(Message message);
<select id="getMessageByMessage" resultType="mybatisdemo1.entity.Message">
select
<include refid="allMessage"/>
from
tb_message
where id = #{id} and msg_id = #{msgId}
</select>
批处理插入
<foreach item="item" index="index" collection="list|array|map key" open="(" separator="," close=")">
参数值
</foreach>
<insert id="addBatch">
insert into dept_emp(emp_no,dept_no,from_date,to_date) values
<foreach collection="list" item="deptEmp" separator=",">
(#{deptEmp.employee.empNo}, #{deptEmp.deptNo},#{deptEmp.fromDate},#{deptEmp.toDate})
</foreach>
</insert>
级联(一对一association 一对多collection)
这里我只对id 和messageDetail放入resultMap 其他属性没有放入resultMap中
使用select所指定的方法,以column作为参数,最后封装到property里
<!-- 一对一级联查询-->
<!-- 先查询需要级联的属性-->
<select id="getDetail" parameterType="String" resultType="mybatisdemo1.entity.MessageDetail">
select * from tb_message_detail where msg_id = #{msgId}
</select>
<resultMap id="detail" type="mybatisdemo1.entity.Message">
<id column="id" property="id"/>
<result column="msg_id" property="msgId"/>
<!-- 一对一association 一对多collection-->
<!-- msg_id作为入参 传入select所指定的方法中 最后保存到messageDetail里 -->
<association property="messageDetail" column="msg_id"
select="mybatisdemo1.mapper.MessageMapper.getDetail"/>
</resultMap>
<select id="getMessageAndDetailById" parameterType="long" resultMap = "detail">
select * from tb_message where id = #{id}
</select>
#{}与${}的比较
#{}:
-
使用的PrepareStatement对象,执行sql语句,效率高。
-
使用的PrepareStatement对象,能避免sql语句, sql语句执行更安全。
-
#{} 常常作为 列值使用的, 位于等号的右侧, #{}位置的值和数据类型有关的。
${}:
-
使用Statement对象,执行sql语句,效率低
-
${}占位符的值,使用的字符串连接方式, 有sql注入的风险。 有代码安全的问题
-
${} 数据是原样使用的, 不会区分数据类型。
-
${} 常用作 表名或者列名, 在能保证数据安全的情况下使用 ${}
缓存
一级缓存
一级缓存是 SqlSession级别 的缓存。其中每一个 SqlSession 的内部都会有一个一级缓存对象。
查询条件不同,增删改,手动清空缓存都会清空一级缓存
二级缓存
二级缓存是namespace级别的。开始时查出数据放在一级缓存中,当一次会话关闭就会自动保存到二级缓存中
全局配置
<setting name="cacheEnabled" value="true"/> <!-- 开启二级缓存-->
映射文件
<cache></cache>
实体类实现序列化接口