mybatis

2018-04-09  本文已影响23人  静心安分读书

18.10.24
大家都知道,java中JDBC中,有个预处理功能,这个功能一大优势就是能提高执行速度尤其是多次操作数据库的情况,再一个优势就是预防SQL注入,严格的说,应该是预防绝大多数的SQL注入。
那为什么它这样处理就能预防SQL注入提高安全性呢?其实是因为SQL语句在程序运行前已经进行了预编译,在程序运行时第一次操作数据库之前,SQL语句已经被数据库分析,编译和优化,对应的执行计划也会缓存下来并允许数据库已参数化的形式进行查询,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or '1=1'也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令,如此,就起到了SQL注入的作用了!

转自原文:https://blog.csdn.net/chenleixing/article/details/44024095

18.9.5
mybatis对多数据源的支持不行,但是也能做,demo删了,只剩链接了。。先留在这里。
http://www.cnblogs.com/digdeep/p/4512368.html
https://blog.csdn.net/xiao466068504/article/details/79310183
https://blog.csdn.net/truong/article/details/25062231
https://blog.csdn.net/shuxing520/article/details/79129432
https://blog.csdn.net/zhmz1326/article/details/52041918

18.7.22
xml中写的sql的动态语句解析中,#{}和{}的区别? 两者在使用上没有区别,最终解析出来的语句也完全一样。 不同在于,在预编译过程中,#{}生成的sql语句,被替换处换成了? 而{}生成的sql语句,被替换处换成了字符串。
{}容易引起sql注入问题。 sql注入的例子: select * from{tableName} where name = #{name};
在这个例子中,如果表名为
user; delete user; --
则动态解析之后 sql 如下:
select * from user; delete user; -- where name = ?;
 --之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。
但是表名用参数传递进来的时候,只能使用 ${} ,具体原因可以自己做个猜测,去验证。这也提醒我们在这种用法中要小心sql注入的问题。
参考文献:https://www.2cto.com/database/201709/676537.html
————————————
18.7.22
parameterType可传入类型有哪些?不能一次传入多个参数,只可以通过类、数组、map、注解等形式传入多个参数。
1.基本数据类型
可以通过#{参数名}直接获取。每次只能传入一个值
<select id="selectTeacher" parameterType="int" resultType="com.myapp.domain.Teacher"> select * from Teacher where c_id=#{id}
基本数据类型的<if test="">里面作为参数就会出问题。
2.自定义类
可以传入一个对象,通过#{对象中的property或field}获取对象中存放的值,如果自定义对象user内还存在自定义对象address的话可以通过address.id获取address的属性值。
<select id="selectTeacher" parameterType="teacher" resultType="com.myapp.domain.Teacher"> select * from Teacher where c_id=#{id}
<select id="selectTeacher" parameterType="teacher" resultType="com.myapp.domain.Teacher"> select * from Teacher where a_id=#{address.id}
3.Map集合
传入一个Map集合,通过#{key}获取存在Map中的value值
<select id="selectTeacher" parameterType="java.util.Map" resultType="com.myapp.domain.Teacher"> select * from Teacher where c_id=#{id}
4.数组|集合
传入数据的话,需要使用下标当做key值,获取value
<select id="selectTeacher" resultType="com.myapp.domain.Teacher"> select * from Teacher where c_id=#{0} and address.id = #{1}
5.注解
可以在接口内传入多个参数,这时mybatis会把多个参数当成一个数组使用,使用下标获取值。可以使用注解,给每个变量设置一个key,在取值的时候通过这个key获取。
public List<User> selectUserByPage(@Param(value="startIndex")int startIndex, @Param("rows")int rows);
这样传入时就相当于是传入了一个Map集合

总结一下:parameterType类型包括基本类型、自定义类型、Map、数组/List、注解,5类。
参考:https://blog.csdn.net/programmer123455/article/details/78382974
————————————
18.7.17
resultMap之discriminator
discriminator–使用一个结果值以决定使用哪个resultMap
case–基于不同值的结果映射
嵌套结果映射–case也能引用它自身, 所以也能包含这些同样的元素。它也可以从外部引用resultMap
例如:
<resultMap id="vehicleResult" type="Vehicle">
<id property=”id” column="id" />
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="make" column="make"/>
<result property="model" column="model"/>
<result property="color" column="color"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultMap="carResult"/>
<case value="2" resultMap="truckResult"/>
<case value="3" resultMap="vanResult"/>
<case value="4" resultMap="suvResult"/>
</discriminator>
</resultMap>
如果carResult像下面这样定义:
<resultMap id="carResult" type="Car">
<result property=”doorCount” column="door_count" />
</resultMap>
那么,只有doorCount属性会被加载。
在刚才的例子里我们当然知道cars和vehicles的关系,a Car is-a Vehicle。因此,我们也要把其它属性加载进来。我们要稍稍改动一下resultMap:
<resultMap id="carResult" type="Car"extends=”vehicleResult”>
<result property=”doorCount” column="door_count" />
</resultMap>
现在,vehicleResult和carResult的所有属性都会被加载。

也可以把case映射的属性放在自己内部。
<resultMap id="vehicleResult" type="Vehicle">
<id property=”id” column="id" />
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="make" column="make"/>
<result property="model" column="model"/>
<result property="color" column="color"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultType="carResult">
<result property=”doorCount” column="door_count" />
</case>
<case value="2" resultType="truckResult">
<result property=”boxSize” column="box_size" />
<result property=”extendedCab” column="extended_cab" />
</case>
<case value="3" resultType="vanResult">
<result property=”powerSlidingDoor” column="power_sliding_door" />
</case>
<case value="4" resultType="suvResult">
<result property=”allWheelDrive” column="all_wheel_drive" />
</case>
</discriminator>
</resultMap>
参考:http://zhangdefeng2008.iteye.com/blog/1887945
——————————
18.6.28
1、
updateByExampleSelective
updateByExample
updateByPrimaryKey
updateByPrimaryKeySelective
insertSelective
insert
deleteByExample
含有Selective的保存和更新时,对象属性为空的不更新或者不保存。
不含有Example的直接保存或更新,根据对象所有有值的属性作为where条件,有的时候用的不方便。
带有Example能够精细化控制,如下:
Example exampleMenu = new Example(PermissionsMenu.class);
Example.Criteria criteriaMenu = exampleMenu.createCriteria();
criteriaMenu.andEqualTo("id", id);//可以设置where条件
permissionsMenuMapper.updateByExampleSelective(permissionsMenu,exampleMenu);
2、mybatis对应的实体,每一个字段都有加@Column 注解要加@Id等等。

——————————
18.6.22
mapper.xml里面的<select>标签里面的sql,不能有注释的sql,应该是有注释的sql也没问题,主要是sql里面有#{}会被认为是一个参数,如果参数不足,会报错。。。这是什么鬼,注释里面有#{}就会被计数。
——————————
18.6.20
resultType resultMap同时存在时,resultType可以正常赋值,
但是当转成json时,会转成resultMap
——————————
18.6.15
1、mysql jdbc java 中类型对应
参考:https://www.cnblogs.com/jerrylz/p/5814460.html
https://www.cnblogs.com/waterystone/p/6226356.html
2、springboot使用mybatis
引入starter及相关jdbc
然后配置
mybatis.mapper-locations=classpath:mapper/.xml
mybatis.type-aliases-package=com.XX.entity
下面的参考,最后启动文件上加注解在实际中并没有使用。
参考:https://blog.csdn.net/sinat_38278330/article/details/73694441
3、MyBatis中的@Mapper注解
写好的Mapper,也就是Dao接口,上面写上注解@Mapper,系统就会自动将其识别为mapper,就可以直接映射到mapper.xml文件或者与通用mapper映射。

——————————————
18.6.14
关于Mapper.xml
1、parameterType只能有一个,最多只可以有一个基本类型作为参数,无法有多个基本类型作为参数。
当一个基本类型做参数时,<if test="username != null and username != ''">无法使用,若使用会报错“reflection.ReflectionException: There is no getter for property named 'username' in 'class java.lang.String'”
原因就是源码里面使用_parameter作为参数比较的。
因此需要修改成:
<if test="_parameter != null and _parameter != ''">
只有当parameterType是一个类时,才可以用类中属性名做条件判断。如下例子:
<update id="batchToSend" parameterType="BidProjectDto">
<if test="createUserErp != null and createUserErp != ''">
2、resultMap的作用是用来将结果集中字段名映射到对象中属性名的。
例如:
<resultMap id="BaseResultMap" type="BasePermissionsVO" >
<result column="permission_name" property="permissionName" jdbcType="VARCHAR" />
<result column="permissions_code" property="permissionsCode" jdbcType="VARCHAR" />
</resultMap>
使用resultMap属性必须定义<resultMap>标签块。
resultMap可以继承,一个Base <resultMap> 两个<resultMap>继承Base
但resultMap的作用仅仅是作为字段名与属性名映射用的,而且必须在type指定一个对应的类。但是实际上缺少几项或多出几项也不会有任何影响。
如上例子中,由于数据库字段名比较规范,mybatis可以将permissions_code自行转换匹配到permissionsCode上。
因此resultMap的作用应当是给非常规字段或属性映射使用的。
resultMap相关详解:https://blog.csdn.net/wuskzuo/article/details/79186144
3、resultType对应的类中属性的个数要大于等于结果字段数。即使返回list,resultType也直接写list里面的类型就可以了。
resultType:
基本类型 :resultType=基本类型
List类型: resultType=List中元素的类型
Map类型 单条记录:resultType =map
多条记录:resultType =Map中value的类型
4、关于namespace
<mapper namespace="security.mapper.PermissionsMapper" >
这个要对应Mapper接口,其实就是Dao接口,使用通用mapper,就无需Dao的实现类
——————————————
18.4.9
1、控制台打印sql
就在log4j的配置文件里面加
把我代码里log的配置贴一份 供参考
log4j.logger.com.ibatis=DEBUG log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG l
og4j.logger.java.sql.PreparedStatement=DEBUG

作者:流觞-鹜
链接:https://www.zhihu.com/question/20091325/answer/59345075
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
————————————

上一篇下一篇

猜你喜欢

热点阅读