Mybatis入门简版(补充)
一、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>
最新文章
- android TextView 文字垂直的设置
- eclipse打开出错 Error: opening registry key &#39;Software\JavaSoft\Java Runtime Environment&#39;
- codechef 两题
- area标签circle/rect/poligon坐标
- hdu 1575 Tr A (矩阵快速幂入门题)
- JS焦点图,JS 多个页面放多个焦点图
- DataGridView如何快速导出Excel
- HDU 2554 N对数的排列问题
- hadoop 学习笔记 (十) mapreduce2.0
- Android热修复框架汇总整理(Hotfix)
- 内置对象Cookie和Session有何不同【常见面试题】
- react native中使用echarts
- Docker for .Net Developers(part1:Docker基本概念介绍)
- plsql的特殊复制
- linux 音频编程
- 大数据自学6-Hue集成环境操作Hbase
- mycat 多个逻辑库加读写分离
- 能让你聪明的工作DEAL四法则,来自《每周工作四小时》书籍
- Linux终端没有GUI,使用matplotlib绘图
- 阿帕奇web服务器下载部署安装运行
热门文章
- 小白专场-多项式乘法与加法运算-python语言实现
- .NET框架之“小马过河”
- Android如何管理sqlite
- 解决The mysql extension is deprecated and will be removed
- 转载unity编辑器xml数据库插件
- .Net基础篇_学习笔记_第五天_流程控制while循环002
- Winform中实现读取xml配置文件并动态配置ZedGraph的RadioGroup的选项
- Cookie的临时存储和定时存储
- 重学js之JavaScript 面向对象的程序设计(创建对象)
- Spring Boot (三): ORM 框架 JPA 与连接池 Hikari