一、Mybatis 中$与#的区别

#相当于对数据 加上 双引号,$相当于直接显示数据

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order
by "111", 如果传入的值是id,则解析成的sql为order by "id".

2.
$将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,  如果传入的值是id,则解析成的sql为order by id.

3.
#方式能够很大程度防止sql注入。

4.$方式无法防止Sql注入。

5.$方式一般用于传入数据库对象,例如传入表名.

6.一般能用#的就别用$.

MyBatis排序时使用order
by 动态参数时需要注意,用$而不是#

二、Mybatis映射文件里的<selectkey>

我们在数据库插入一条数据(主键是数据库生成)的时候,经常是需要返回插入这条数据的(数据库生成的)主键。

比如插入用户信息JavaBean时,id不需要我们设置(自增),那么插入后,我们想马上得这个JavaBean的ID。

可以下面这样改:

<insert id="saveUser" parameterType="cn.itcast.mybatis.pojo.User">
<selectKey keyColumn="id" keyProperty="id" order="AFTER"
resultType="int">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO `user`
(username,birthday,sex,address) VALUES
(#{username},#{birthday},#{sex},#{address})
</insert>

其中:

selectKey
标签实现主键返回 
keyColumn:

主键对应的表中的哪一列

keyProperty:

主键对应的pojo中的哪一个属性

order:

设置在执行insert语句前执行查询id的sql,还是在执行insert语句之后执行查询id的sql

MySQL填AFTER ,Oracle填BEFORE

resultType:

设置返回的id的类型

三、映射xml文件中的resultMap

1.介绍

resultType可以指定将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功

如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系
,resultMap实质上还需要将查询结果映射到pojo对象中。

比如对于数据库里user_id这种字段,逆向工程会生成userId属性的pojo


2.使用(由resultType改用resultMap

<!-- resultMap最终还是要将结果映射到pojo上,type就是指定映射到哪一个pojo -->

	<!-- id:设置ResultMap的id -->
<resultMap type="cn.ssm.pojo.order" id="orderResultMap">
<result property="userId" column="user_id" />//只要写那个不一样的就行了!
</resultMap> <!-- 查询所有的订单数据 -->
<select id="queryOrderAll" resultMap="orderResultMap">
SELECT id, user_id,
number,
createtime, note FROM `order`
</select>

其中:property:主键在pojo中的属性名,column:主键在数据库中的列名

四、动态SQL(基于OGNL表达式)

1.if标签

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
WHERE 1=1
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</select>

2.where标签

上面的例子里,还得写个1=1 防止出现 where and 这种错误情况。其实这种情况可以通过where标签解决

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>

3.SQL片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段,如下:

<!-- 声明sql片段 -->
<sql id="userFields">
id, username, birthday, sex, address
</sql> <!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user"> <!-- 使用include标签加载sql片段;refid是sql片段id -->
SELECT <include refid="userFields" /> FROM `user` <where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>

如果要使用别的Mapper.xml配置的sql片段,可以在refid里面加上对应的Mapper.xml的namespace

4.foreach标签

向sql传递数组或List,mybatis使用foreach解析,比如:

根据多个id查询用户信息

查询sql:

SELECT * FROM user WHERE id IN (1,10,24)

<!-- 根据ids查询用户 -->
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM `user`
<where>
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>

五、多表查询


多表查询的时候通常会要返回多个表的数据,即多个pojo的部分数据。


5.1一对一查询(两张表)


此时要么采取新建pojo(继承一个pojo再加上新需要的)去包裹查出来的数据,要么在原pojo里组合另外一个pojo(作为成员对象),即继承和组合
两种方法。

5.1.1采用继承的方法(正常采用resultType即可)

5.1.2采用组合的方式

那么此时多个pojo会有相同属性,如何映射?采取resultMap


pojo可能会要改成下面这样:


那么此时查询结果对pojo的映射得改改了

<resultMap type="order" id="orderUserResultMap">
<id property="id" column="id" />
<result property="userId" column="user_id" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" /> <!-- association :配置一对一属性 -->
<!-- property:order里面的User属性名 -->
<!-- javaType:属性类型 -->
<association property="user" javaType="user">
<!-- id:声明主键,表示user_id是关联查询对象的唯一标识-->
<id property="id" column="user_id" />
<result property="username" column="username" />
<result property="address" column="address" />
</association> </resultMap> <!-- 一对一关联,查询订单,订单内部包含用户属性 -->
<select id="queryOrderUserResultMap" resultMap="orderUserResultMap">
SELECT
o.id,o.user_id,o.number,o.createtime,o.note,u.username,u.address
FROM
`order` o
LEFT JOIN `user` u ON o.user_id = u.id
</select>

5.2一对多查询

如下:



那么映射文件如下:

<resultMap type="user" id="userOrderResultMap">
<!-- 配置主键,将主键相同的记录映射到一个集合里去-->
<id property="id" column="id" />
<result property="username" column="username" />
<result property="birthday" column="birthday" />
<result property="sex" column="sex" />
<result property="address" column="address" /> <!-- 配置一对多的关系 -->
<collection property="orders" javaType="list" ofType="order">
<!-- 配置主键,是关联Order的唯一标识 -->
<id property="id" column="oid" />
<result property="number" column="number" />
<result property="createtime" column="createtime" />
<result property="note" column="note" />
</collection>
</resultMap> <!-- 一对多关联,查询订单同时查询该用户下的订单 -->
<select id="queryUserOrder" resultMap="userOrderResultMap">
SELECT
u.id,u.username,u.birthday,u.sex,u.address,o.id oid,o.number,o.createtime,o.note
FROM
`user` u
LEFT JOIN `order` o ON u.id = o.user_id
</select>

最新文章

  1. android TextView 文字垂直的设置
  2. eclipse打开出错 Error: opening registry key &#39;Software\JavaSoft\Java Runtime Environment&#39;
  3. codechef 两题
  4. area标签circle/rect/poligon坐标
  5. hdu 1575 Tr A (矩阵快速幂入门题)
  6. JS焦点图,JS 多个页面放多个焦点图
  7. DataGridView如何快速导出Excel
  8. HDU 2554 N对数的排列问题
  9. hadoop 学习笔记 (十) mapreduce2.0
  10. Android热修复框架汇总整理(Hotfix)
  11. 内置对象Cookie和Session有何不同【常见面试题】
  12. react native中使用echarts
  13. Docker for .Net Developers(part1:Docker基本概念介绍)
  14. plsql的特殊复制
  15. linux 音频编程
  16. 大数据自学6-Hue集成环境操作Hbase
  17. mycat 多个逻辑库加读写分离
  18. 能让你聪明的工作DEAL四法则,来自《每周工作四小时》书籍
  19. Linux终端没有GUI,使用matplotlib绘图
  20. 阿帕奇web服务器下载部署安装运行

热门文章

  1. 小白专场-多项式乘法与加法运算-python语言实现
  2. .NET框架之“小马过河”
  3. Android如何管理sqlite
  4. 解决The mysql extension is deprecated and will be removed
  5. 转载unity编辑器xml数据库插件
  6. .Net基础篇_学习笔记_第五天_流程控制while循环002
  7. Winform中实现读取xml配置文件并动态配置ZedGraph的RadioGroup的选项
  8. Cookie的临时存储和定时存储
  9. 重学js之JavaScript 面向对象的程序设计(创建对象)
  10. Spring Boot (三): ORM 框架 JPA 与连接池 Hikari