Mybatis可以说是java 后端最基本掌握得技能,但是当我们平时复制粘贴多了,就会忘记一些细节的处理:
比如为什么要将上这个注解,作用是什么!首先是mybatsi的配置文件
<configuration>
<!-- 加载属性文件 -->
<properties resource="jdbc.properties">
<!--properties中还可以配置一些属性名和属性值 -->
<!-- <property name="jdbc.driver" value=""/> -->
</properties><!-- 全局配置参数,需要时再设置 -->
<settings>
<!-- 打开延迟加载的开关,默认为false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 开启二级缓存,默认为true -->
<setting name="cacheEnabled" value="true"/>
<!-- 使用jdbc的getGeneratedKeys获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true"/>
</settings><!-- 别名定义 -->
<typeAliases>
<!-- 针对单个别名定义
type:类型的路径,alias:别名。示例:-->
<typeAlias type="com.czd.mybatis.po.User" alias="user"/>
<!-- 批量别名定义
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写都可以)-->
<package name="com.czd.mybatis.po"/></typeAliases>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis-->
<transactionManager type="JDBC"/>
<!-- 数据库连接池,由mybatis管理-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments><!--加载映射文件有 3 种方法,如下所示-->
<mappers>
<mapper resource="sqlmap/User.xml"/>
<!--1. 通过 resource 方法一次加载一个映射文件 -->
<!-- <mapper resource="mapper/UserMapper.xml"/> --><!-- 2. 通过 mapper 接口加载单个映射文件
遵循一些规范:需要将 mapper 接口类名和 mapper.xml 映射文件名称保持一致,且在一个目录中
-->
<!-- <mapper class="com.iot.mybatis.mapper.UserMapper"/> --><!-- 3. 批量加载 mapper
指定 mapper 接口的包名,mybatis 自动扫描包下边所有 mapper 接口进行加载
遵循一些规范:需要将 mapper 接口类名和 mapper.xml映射文件名称保持一致,且在一个目录中
-->
<package name="com.czd.mybatis.mapper"/><mappers/>
2.# 和 $ 的区别
使用#{parameterName} 引用参数时候,mybatsi会吧参数认为是一个字符串,例如下面的参数"corey" 是一个字符串
Select from emp where name = #{employeeName} 则会转意为 Select from emp where name = 'corey'
同理在下面sql传入参数"corey"
Select from emp where name = ${employeeName} 则会装化为 Select from emp where name = corey
所以可以说#{}是经过预编译的 是安全的,而${} 是没有经过预编译的,仅仅是变量的取值,并不是安全的,存在sql
注入的危险,#将传入的数据当成一个字符穿,会对自动传入的数据加上一个引号
而是用${}的情况下, order by , like 语句只能${}了,用#{} 会多一个'' 导致sql语句失效,此外动态拼接sql,
模糊查询也要用${}
例如举个例子: name=徐,那么该sql就是.....like '%徐%'
DELETE FROM stu WHERE `name` LIKE '%${name}%'
所以总结下:
#{}:编译好sql语句再执行
${}:取之后再去编译sql语句
3.sql语句中的列明和关键字冲突怎么办?
例如:name 字段
解决方法:在列明两边加上 ' 即可
DELETE FROM stu WHERE `name` LIKE '%${name}%'
4.列明和bean属性名不一样,导致获取不到数据时怎么办?
因为mybatis 会通过反射得到bean,由于字段名和属性名不一样,导致无法将查询到的
表字段数据set到bean熟悉中
解决办法:
1.修改表字段或者对应的bean属性名称,使他们同名即可
2.修改标签中的内容
<!--当实体属性与表字段名不相同的时候,必须书写一下代码
当尸体属性与表字段名相同时候,一下代码可选
-->
<resultMap id="student" type="arraylist">
<id property="id" column="student_id"/>
<result property="name" column="student_name"/>
<result property="sal" column="student_sal"/>
<!--bean 属性名字 bean表字段名-->
</resultMap>
5.@param 参数的作用
作用:相当于给其修饰的参数指定一个别名
若接口只有一个参数,则可以不用指定别名,list参数除外,当有多个参数时候 一定要指定,否则mybatis
映射不到对应的字段
如代码:
List<Book> queryAll(@Param("offset")int offset, @Param("limit")int limit);
该接口方法对应mapper如下:
<select id="queryAll" resultType="Book">
SELECT
book_id,
`name`,
`number`
FROM
book
ORDER BY
book_id
LIMIT #{offset}, #{limit}
</select>
可以看到#{} 里面的值是和@Param("value") 保持一致的,也一定要一直,否则mybatsi会找不到这个值而报错
另外@Param("value") 中的value可以是任意的