一、首先了解下什么是mybatis?
Mybatis是一个半ORM(对象关系映射)框架,它能内部封装JDBC,加载驱动、创建连接、创建statement等复杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。
作为一个半ORM框架,Mybatis可以使用XML或注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。(称Mybatis是半自动ORM映射工具,是因为在查询关联对象或关联集合对象时,需要手动编写SQL来完成。不像Hibernate这种全自动ORM映射工具,Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取。)
通过xml文件或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中SQL的动态参数进行映射生成最终执行的SQL语句,最后由mybatis框架执行SQL并将结果映射为java对象并返回。(从执行SQL到返回result的过程)
Mybatis优点:基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,sql写在xml里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态sql语句,并可重用。
二、通常一个mapper.xml文件,都会对应一个Dao接口,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
Mapper接口的工作原理:JDK动态代理,Mybatis运行时会使用JDK动态代理Mapper接口生成代理对象proxy,代理对象会拦截接口方法,根据类的全限定名 + 方法名 ,唯一定位到一个MapperStatement并调用执行器执行所代表的sql,然后将sql执行结果返回。
Mapper接口===Dao接口,是不能重载的,因为是使用类的全限定名 + 方法名 的保存和寻找策略。
接口的全限定名:就是映射文件中的namespace的值;
接口的方法名:就是映射文件中Mapper的Statement的id值;
接口方法内的参数,就是传递给sql的参数。
三、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?
不同的xml映射文件,如果配置了namespace,那么id可以重复;
如果没有配置namespace,那么id不能重复;------------------因为namespace + id 是作为Map< String,MapperStatement>的key使用的,
如果没有namespace,就剩下id,那么id重复会导致数据相互覆盖。有了namespace,自然id就可以重复,namespace不同,namespace + id 自然也就不同。
四、剖析代码
(1)书写controller类,添加映射URL
@Controller
public class LoginController {
//将Service注入Web层
@Autowired
UserService userService;
@RequestMapping(value = "/loginIn",method = RequestMethod.POST)
public String login(String name,String password){
UserBean userBean = userService.loginIn(name,password);
if(userBean!=null){
return "success";
}else {
return "error";
}
}
}
(2)书写service
1、接口
public interface UserMapper {
//根据ID查询用户信息
UserBean selectUserById(String id);
}
2、接口实现类service
@Service
public class UserServiceImpl implements UserService {
//将DAO注入Service层
@Autowired
UserMapper userMapper;
/**
* 登录验证
* @param name
* @param password
* @return
*/
@Override
public UserBean loginIn(String name, String password) {
return userMapper.getInfo(name,password);
}
}
(3)书写接口Mapper
public interface UserMapper {
//登录时信息核对
UserBean getInfo(String name, String password);
}
(4)书写*Mpper.xml文件,注意:mapper.xml文件名和mapper接口名称保持一致,且放在同一个目录下。
mapper.xml中的namespace为mapper接口的类地址;mapper接口中的方法名和mapper.xml中定义的statement的id保持一致;
mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同;
mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;
<?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.example.test.mapper.UserMapper">
<!--验证用户账号和密码-->
<select id="getInfo" parameterType="String" resultType="com.example.test.bean.UserBean">
SELECT * FROM user
WHERE name = #{name}
AND password = #{password};
</select>
</mapper>
(5)图例解析
五、Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
1、使用标签,逐一定义数据列名和对象属性名之间的映射关系。
2、使用sql列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。