1、MyBatis是什么
- 是一个半ORM(关系对象映射)框架,它封装了JDBC,加载驱动,创建连接,创建statement等繁杂的过程,是开发者只专注于如何编写SQL语句。
- 作为一个半ORM框架,MyBatis可以使用XML或者注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
- 通过xml文件或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终的sql语句,最后MyBatis框架执行sql并将结果映射为java对象并返回(从执行sql到返回result的过程)
- 由于MyBatis专注于SQL本身,灵活度高,所以比较适合对性能要求高,需求变化多的项目,如互联网项目。
2、通常一个xml映射文件,会有一个Dao接口与之对应,那么这个Dao接口原理是什么?Dao接口里的方法、参数不同时,方法能重载吗?
Dao接口即Mapper接口。接口的全限名就是映射文件中namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口里传的参数就是传给sql的参数。Dao接口是没有实现类的,当调用接口方法时,通过接口全限名+接口名的拼接字符串作为key值,可唯一定位一个Mapper中的Statement
注:以下是SysUserMapper
接口的全限名和对应映射文件SysUserMapper.xml
中mapper
标签的namespace
属性
注:接口的方法名,就是映射文件中Mapper的Statement的id值;
关于MyBatis的输入输出类型:
输入输出支持类型:
输入:parameterType 支持的类型: java简单类型 、 hashmap 、 自定义pojo对象
输出1:resultType: 支持的类型: java简单类型 、 hashmap 、 自定义pojo对象
注意:封装到自定义pojo对象的要求:对象的属性名和数据库表的字段名一一对应的!!!
输出2: resultMap:
1.可以解决对象属性名和数据库字段名不一致的问题
2.还可以做一对一 和 一对多
关于输出类型resultType
何时用基本数据类型(int等)和包装数据类型(Integer等)?
具体要根据SQL语句的返回值决定,如果sql语句有返回null的情况则不能使用int作为返回类型。具体区别看以下两条SQL语句
<select id="selectRoleListByUserId" parameterType="Long" resultType="Integer">
select r.role_id
from sys_role r
left join sys_user_role ur on ur.role_id = r.role_id
left join sys_user u on u.user_id = ur.user_id
where u.user_id = #{userId}
</select>
<select id="checkUserNameUnique" parameterType="String" resultType="int">
select count(1) from sys_user where user_name = #{userName} limit 1
</select>
MyBatis中#{}
和${}
的区别?
首先,我们说一下这两种引用参数时的区别,使用#{parameterName}引用参数的时候,Mybatis会把这个参数认为是一个字符串,并自动加上’’,例如传入参数是“Smith”,那么在下面SQL中:
Select * from emp where name = #{employeeName}
使用的时候就会转换为:
Select * from emp where name = 'Smith';
同时使用${parameterName}的时候在下面SQL中
Select * from emp where name = ${employeeName}
就会直接转换为:
Select * from emp where name = Smith
简单说#{}是经过预编译的,是安全的
。
而${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入
。
详情请参考:mybatis中#与$的区别
MyBatis常用传多个参数方式?
注:以下转载于mybatis中传入多个参数的4个解决方法
1、利用参数出现的顺序(不推荐——不美观,不易维护)
Parameter ‘id’ not found. Available parameters are [arg1, arg0, param1, param2]
,这句话的意思就是id找不到,可用的参数是[arg1, arg0, param1, param2]。所以可使用参数出现的顺序号码引用参数,第一个参数用arg0或param1表示,第二个参数用arg1或param2表示,以此类推(arg从0开始计数,param从1开始计数)。
参考SQL语句:
<select id="select" resultType="model.User">
select * from `user` where name = #{arg0} and age =#{arg1}
</select>
// or
<select id="select" resultType="model.User">
select * from `user` where name = #{param1} and age =#{param2}
</select>
2、使用@Param注解
/**
* 校验部门名称是否唯一
*
* @param deptName 部门名称
* @param parentId 父部门ID
* @return 结果
*/
public SysDept checkDeptNameUnique(@Param("deptName") String deptName, @Param("parentId") Long parentId);
对应mapper映射文件
<select id="checkDeptNameUnique" resultMap="SysDeptResult">
<include refid="selectDeptVo"/>
where dept_name=#{deptName} and parent_id = #{parentId} limit 1
</select>
3、使用Map
public User selectUser(Map<String, Object> params);
以下是对应mapper映射文件
<select id="selectUser" parameterType="java.util.Map" resultMap="UserMap">
select * from user
where user_name = #{userName} and dept_id = #{deptId}
</select>
4、把参数封装在Javabean中
public List<SysUser> selectUserList(SysUser sysUser);
以下是对应mapper映射文件
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">