动态SQL中#和$的区别
为了性能考虑,相同的预编译sql可以重复利用,其次,${}在预编译之前已经被预编译替换了,这会存在sql注入问题,例如sql:
Select * from ${tableName} where name=#{name};
如果我们的参数tableName 为user,delete user;那么sql动态解析阶段之后,预编译之前的sql将变为:
Select * from user;delete user; --wehre name=?
动态参数时需要注意,用${} 比如
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号
$将传入的数据直接显示生成在sql中
在使用mybatis的时候,尽量的使用#方式
springboot 集成mybatis
# Mybatis配置
#mybatis:
# mapperLocations: classpath:mapper/**/*.xml
# configLocation: classpath:mybatis.xml
mybatis:
configLocation: classpath:mybatis.xml
typeAliasesPackage: com.fs.*.model
mapper-locations: classpath:mapper/**/*.xml
问题总结
1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。
设想:使用数据库连接池管理数据库连接。
2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。
设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。
3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
设想:将sql语句及占位符号和参数全部配置在xml中。
4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。
设想:将查询的结果集,自动映射成java对象。
MyBatis执行流程
1:resultMap结果映射集
定义映射规则 主要级联查询,
查询语句有三个 参数 id 参数类型和返回值类型 (一般返回的时我们的实体类,也可以返回一个map集合但是可读性差)
一对一关联映射
//一对一的映射查询 əˌsəʊʃiˈeɪʃn
<mapper namespace="gler.mybatis.onetoone.mapper.ClassesMapper">
<select id="selectClassById" parameterType="int" resultMap="classmap">
select * from tb_class c, tb_head_teacher t where c.c_ht_id = t.ht_id and c.c_id=#{id}
</select>
<!-- resultMap:映射实体类和字段之间的一一对应的关系 返回两个表中的数据 -->
<resultMap id="classmap" type="Classes">
<id property="id" column="c_id" />
<result property="name" column="c_name" />
<!-- 一对一关联映射:association -->
<association property="teacher" javaType="HeadTeacher">
<id property="id" column="ht_id" />
<result property="name" column="ht_name" />
<result property="age" column="ht_age" />
</association>
</resultMap>
</mapper>
这里对assacation标签的属性进行解释一下:
property | 对象属性的名称 |
javaType | 对象属性的类型 |
column | 所对应的外键字段名称 |
select | 使用另一个查询封装的结果 |
一对多
获取一个顾客以及一个顾客下的多个订单
<resultMap type="com.yc.m.Customer" id="resultCustomerMap">
<id column="id" jdbcType="INTEGER" property="id" />
<result property="address" column="address"/>
<result property="postcode" column="postcode"/>
<result property="sex" column="sex"/>
<result property="cname" column="cname"/>
<collection property="orders" ofType="com.yc.m.Orders">
<id property="id" column="id"/>
<result property="code" column="code"/>
</collection>
</resultMap>
<select id="getCustomer" resultMap="resultCustomerMap" parameterType="int">
SELECT *
FROM t_customer
WHERE id=#{id}
</select>
多对多
<?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.yc.bean.Group">
<!-- resultMap:结合标准javabean规范,能hashmap或arraylist所不能完成的更复杂的resultType -->
<resultMap type="Group" id="groupMap">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="createTime" column="createdate" />
</resultMap>
<resultMap type="Group" id="groupUserMap" <span style="color:#ff0000;"><strong>extends</strong></span>="groupMap">
<collection property="user" ofType="User">
<!--collection:聚集 用来处理类似User类中有List<Group> group时要修改group的情况 user代表要修改的是Group中的List<user> -->
<id property="id" column="userId" />
<result property="name" column="userName" />
<result property="password" column="password" />
<result property="createTime" column="userCreateTime" />
</collection>
</resultMap>
<select id="selectAllGroup" resultMap="groupMap">
select * from group_info
</select>
<!-- 根据Group表中的id或name查询组信息和组内用户信息 -->
<select id="selectGroupUser" parameterType="Long"
resultMap="groupUserMap">
select u.id as userId,u.name as userName,
u.password,u.createtime as userCreateTime,
gi.id,gi.name,gi.createdate,gi.state from group_info gi left
join user_group ug on gi.id=ug.group_id left join user u on
ug.user_id=u.id where gi.id = #{id}
</select>
<!-- 删除组与组内成员之间的对应关系 -->
<delete id="deleteGroupUser" parameterType="UserGroupLink">
delete from user_group
<where>
<if test="user.id != 0">user_id = #{user.id}</if>
<if test="group.id != 0">and group_id = #{group.id}</if>
</where>
</delete>
</mapper>
缓存cache
动态SQL
jDBC或者其他的框架拼接sql 时非常麻烦的但是mybatis 很好的解决了这一问题
if | 在动态SQL中做所做的最通用的事情是包含部分where字句的条件 入另外一个条件 | |
choose(when,otherwise) | ||
trim(where) | ||
foreach |
<select id=”findActiveBlogLike” parameterType=”Blog”
resultType=”Blog”>
SELECT * FROM BLOG WHERE state = „ACTIVE‟
<choose>
<when test=”title ! null ”>
AND title like #{title}
</when>
<when test=”author ! null and author.name ! =null”>
AND title like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list" open="("
separator="," close=")">
#{item}
</foreach>
</select>