Mybatis是数据访问层的一个框架,主要是用来操作数据库,以下是我个人对mybatis框架的理解。
mybatis框架的运行流程如下。
----------------------------------------第一步---------------------------------------
将主配置文件转换成输入流,以便后续解析。
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
主配置文件里主要是设置了连接数据库所需要的资源;
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<!--这里type有四个取值,我们通常使用POOLED,是指使用Mybatis框架提供得数据库连接池,其他的三个不常用,不做过多解释-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis03?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
以及指明了用来操作实体类的接口所对应的配置文件的位置;
<mappers>
<mapper resource="com.nd.dao/IUserMapper.xml"/>
<mapper resource="com.nd.dao/IRoleMapper.xml"/>
</mappers>
另外还可以通过以下代码来给实体类起别名,便于后续开发。
<typeAliases>
<package name="com.nd.domain"/><!--name这里指定所要起别名的实体类所在包的路径-->
</typeAliases>
----------------------------------------第二步---------------------------------------
实例化一个用来解析主配置文件的构建者builder;
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
使用构建者builder解析主配置文件得到一个用来生产SqlSession的工厂factory;
SqlSessionFactory factory=builder.build(in);
使用factory生产SqlSession对象;
//true则事务自动提交,false则需要手动提交,默认为false
SqlSession session=factory.openSession(true);
使用session创造一个用来操作实体类的接口的代理对象。
(使用代理对象的优点是:在修改实体类的时候,无需重新运行程序)
IUserDao userDAo=session.getMapper(IUserDAo.class);
然后就可以使用代理对象来调用接口的方法。
----------------------------------------第三步---------------------------------------
调用方法的过程如下
实现方法的过程有两种:
第一种是注解:
只需在接口里的方法名上一行写上注解即可
无参:
@Select("select * from user")
public List<User> findAll();
有参:
当你使用了使用@Param注解来声明参数时,使用 #{} 或 ${} 的方式都可以。不使用@Param注解来声明参数时,必须使用使用 #{}方式。
//@Select("select * from user where userId = #{userId} ")
@Select("select * from user where userId = ${userId} ")
public List<User> findUser(@Param("userid") int userId);
当参数只能有一个,并且该属性所属的类符合Javabean规范的话。也可以不使用@Param注解。
@Select("select * from user where userId = ${userId} ")
public List<User> findUser(int userId);
第二种方式是编写接口对应的xml文件:
该xml文件的命名方式一般为
(例:接口名:IUserDao 对应的文件名:IUserMapper.xml)
xml文件里首先应该是约束条件:
<?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属性里声明工作空间,就是xml对应的接口的全限定接口名。
例:
<mapper namespace="com.nd.dao.IUserDao"></mapper>
mapper标签里使用增删改查的标签来设置sql语句
id是接口对应的方法名 resultType是返回值类型(此种写法仅适用于java实体类的属性名和数据库中对应的的表的属性名完全相同的情况下),另外常用的还有parameterType是参数类型。
例:
<select id="findAll" resultType="com.nd.domain.User">
select * from user;
</select>
如果java实体类中的属性名与数据库中对应的表的属性名有出入的话,则需要使用<resultMap>
标签使其一一对应。
例:
<!--id就是这个resultMap的身份证号,使用哪个resultMap就是通过id来识别的-->
<!-- type是数据库中的表对应的实体类的类名,如果前面在主配置文件里给所有实体类
起了别名,则这里不区分大小写,直接写类名即可,否则区分大小写而且要写该类的全限
定类名:com.nd.domain.User-->
<resultMap id="userMap" type="user">
<!--property是实体类的属性名,column是对应的数据库中的表中的属性名-->
<result property="userId" column="id"/>
<result property="userName" column="username"/>
<result property="userSex" column="sex"/>
<result property="userAge" column="age"/>
<result property="userBirthday" column="birthday"/>
<result property="userAddress" column="address"/>
<!-- collection是指定一对多或者多对多的对应关系-->
<!-- association用来指定一对一的对应关系,与一对多类似,不再举例-->
<!-- property是本类中多对多关系的的属性名 、ofType是该属性所属类名、javaType是属性类型、column是该类对应的数据库表中的主键-->
<collection property="roles" ofType="Role" javaType="ArrayList" column="rid">
<result property="roleId" column="id"/>
<result property="roleName" column="rolename"/>
<result property="roleDesc" column="roledesc"/>
</collection>
</resultMap>
之后在CRUD的标签中使用该返回值类型时格式如下:
<select id="findUserAndRole" resultMap="userMap">
<!--这里是关于多对多的表的一个查询语句(使用了两次左连接查询)-->
select * from user as u left outer join user_role as ur on
u.id=ur.uid left outer join role as r on ur.rid=r.id
</select>
同样的,传入参数时也可以使用<parameterMap>
标签来指定实体类中的属性与对应的数据库中的表中的属性的对应关系。
——————————————————————————————
至此,我们来总结一下mybatis的执行流程。
第一步:mybatis需要解析主配置文件SqlMapConfig.xml文件,从主配置文件里拿到连接数据库的所需要的资源和操作实体类的接口对应的配置文件(IUserMapper.xml,IRoleMapper.xml等)的位置;
第二步:mybatis会根据第一步拿到的资源连接数据库。
第三步:我们通过SqlSession产生的代理对象来调用接口中的方法。但是接口中只有方法,不能实现方法体。所以mybatis接下来会根据第一步解析主配置文件拿到的所有的接口对应的所有配置文件中,去找我们调用的方法所属的接口对应的配置文件。
第四步:在接口对应的配置文件的<mapper>
标签的namespace属性中,我们指明了这个配置文件属于哪个接口。通过这一点我们可以找到我们用到的接口对应的配置文件。
第五步:mybatis框架在接口对应的配置文件里可以拿到 需要传入的参数,返回值类型,sql语句等等。mabatis会根据拿到的这些属性值去执行代理对象调用的接口中的方法。