传参
在实际的使用中,我们的sql语句要查询的不可能总是固定的,很有可能会来自前端提供的参数。这时候我们就需要进行sql传参。 在xml中编写相应的语句
//paramettype:传入的参数类型,传参处使用#{}进行包裹
<select id="selectid" parameterType="Integer" resultType="mybatis/entity/goods">
select * from where getGoodsId = #{value};
</select>
//调用相关sql并传参
List<goods> list1 = sqlSession.selectList("goods.selsectid" ,12345);
sql注入问题
SQL注入是指攻击者利用SQL漏洞,绕过系统约束,越权获取数据的攻击方式。
比如使用' or 1=1 or 1=' 这种,就会使语句无视前面的查询结果,看1=1成立,就将数据返回了。
有两种传值方法:#{}和{}是原文传值,#{}是预编译之后再传值。
预编译:主要是里面的setString方法,对一些特殊的字符,例如’'单引号,会在值后面加上一个\右斜线进行转义,让值无效,因此不会产生sql注入
在一些情况下我们需要使用{}内的语句不要是外部传进来的。
上面只是简单的单参数传递的情况,在实际的业务中我们很可能会有多参数查询的情况,比如说搜索价格范围内的商品。这时候我们就可以使用Map这个结构来帮助我们实现。
//可以根据map的键值对自动匹配数据
<select id="selectbyprice" parameterType="java.util.Map" resultType="mybatis/entity/goods">
select *
from allgoods
where goods_price between #{min} and #{max}
</select>
//创建map对象,用于存放查询的数据
Map<String,Integer> map = new HashMap<>();
map.put("min",100);
map.put("max",300);
List<goods> list2 = sqlSession.selectList("goods.selsectbyprive",map);
单参数:使用parametype指定参数类型,传参,sql使用#{value}获取参数 多参数:parametype指定map类型,sql使用#{value}获取对应参数
多表查询
多表查询的结果可以使用map存储,但map存储的结果是以hashcode的值来保存的,其顺序不一定是按照我们表中的顺序保存的。这时候可以使用LinkedHashMap。map类结构保存结果时会用key保存字段名,用value保存对应的值。
使用glinkedhashmap的优点:易于拓展和使用,缺点:过于灵活,无法进行编译时检查。
所以我们还可以使用resultMap
//此处的id要与sql语句的结果类型想对应,type要与实际的类对应
<resultMap id="rmGoods" type="goodsDTO">
//id标签表示是主键,如果要是类对象的属性就用对象.属性这样子实现,column对应表中的字段
<id property="thegoods.goodsId" column="goods_id"></id>
//非主键位置,设置和主键一样设置
<result property="thegoods.title" column="title"></result>
</resultMap>
<select id="seectgoodsGTO" resultMap="rmGoods">
-- selsect 语句
</select>
public class goodsDTO {
goods thegood = new goods();
Integer name1;
Integer price;
}
插入语句
//parameterType就是插入的对象类型
<insert id="insert" parameterType="mybatis/entity/goods">
//插入的位置就是表中的字段
insert into t_goods (title,......)
//值是对象的属性
values (#{title},.......)
</insert>
selectKey和useGeneratedKeys
selectKey用于获取主键/主键回填
<insert id="insert" parameterType="mybatis/entity/goods">
insert into t_goods (title,......)
values (#{title},.......)
//参数:order:selectkey的执行顺序,resultType:返回的结果,keypoperty:主键对应的哪个类的属性
<selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">
//查询最后插入生成的id
select last_insert_id()
</selectKey>
</insert>
useGeneratedKeys也可以获取主键
<insert id="insert" parameterType="mybatis/entity/goods"
//参数:确认使用useGeneratedKeys,对应的类中的属性,在表中的字段
useGeneratedKeys="true" keyProperty="goodsId" keyColumn="goods_id">
insert into t_goods (title,......)
values (#{title},.......)
<!-- <selectKey resultType="Integer" keyProperty="goodsId" order="AFTER">-->
<!-- select last_insert_id()-->
<!-- </selectKey>-->
</insert>
两者的区别:
- 显示和隐式调用:selectkey是显示调用查询语句而useGeneratedKeys是隐式调用(执行时根据驱动类型自动生成)
- selectKey适用于所有的数据库而usegenerateKeys适用于支持自增主键类型的数据库
- select使用广泛但书写麻烦,usegeneratekeys使用简单但使用范围有一定的限制。