简介
Mybatis 是由iBatis迁移,持久层(持久是:把数据存储在可永久保存的存储设备,一般是对数据库对的各种操作,如增删改查,持久层把持久动作封装成独立的层,降低了功能代码间的关联)框架,支持定制化SQL,存储过程,及高级映射,避免几乎JDBC代码和手动设置参数以及获取结果集,<br /> Mybatis 可以使用Xml 或注解配置和映射原生信息,将接口和java的pojo(普通的java对象)映射成数据库中记录<br />
特点
主要有以下5大特点:
支持自定义 SQL、存储过程、高级映射;
实现自动对 SQL 的参数设置;
实现自动对结果集进行解析和封装;
通过 XML 或者注解进行配置和映射,大大减少代码量;
数据源的连接信息通过配置文件进行配置。
总体流程
加载配置并初始化
接收请求
处理操作
处理过程:<br /> (A)根据SQL的ID查找对应的MappedStatement对象。<br /> (B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。<br /> (C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。<br /> (D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。<br /> (E)释放连接资源。<br /> (4)返回处理结果将最终的处理结果返回。<br />对架构的主要部分做下说明:
配置文件:全局配置文件 mybatis-config.xml,其作用为配置数据源,引入映射文件 Mapper.xml,映射文章的作用是配置 SQL 语句、参数、结果集封装类型等。
SqlSessionFactory:相当于 Hibernate 的 SessionFactory,作用为获取 SqlSession,通过 newSqlSessionFactoryBuilder().build(inputStream) 来构建,inputStream用来读取配置文件的 IO 流。
SqlSession:相当于 Hibernate 的 Session,作用为执行 CRUD 操作。
Executor:执行器,SqlSession 通过调用它来完成具体的 CRUD,它是一个接口,提供了两种实现,即缓存的实现、数据库的实现。
Mapped Statement:在映射文件里面配置,包含3部分内容:具体的 SQL,SQL执行所需的参数类型,SQL 执行结果的封装类型,参数类型和结果集封装类型包括3种,即 HashMap,基本数据类型,POJO。
XML 映射配置文件
XML 头部的声明,用来验证 XML 文档正确性。
mybatis.xml 在src目录下
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
environment 元素体中包含了事务管理和连接池的配置。mappers 元素则是包含一组 mapper 映射器(这些 mapper 的 XML 文件包含了 SQL 代码和映射定义信息) 即UserMybatis.xml
———————————————————————————————————————————————————————————-
连接外部配置资源db.properties
<properties resource="db.properties"/>
配置数据源资源
<environments default="development" >
<environment id="development" >
<!——配置事务管理——>
<transactionManager type="JDBC">
<!数据源配置>
<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}"/>
</environment>
</environments>
映射器配置
<mappers>
<mapper resource = "com/zhiyou/mybatis/pojo/UserMybatis.xml"/>
</mappers>
UserMybatis.xml
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
namepace 命名空间
<mapper namepace="com.zhiyou.mybatis.pojo.UserMapper">
resultMap查询字段和实体属性的映射
column属性 :指定SQL查询结果的字段名或字段别名。
<resultMap type="User" id="base_map">
<!--
column
property
jdbcType
-->
<id column="_id" property="id" jdbcType="INTEGER" javaType="int"/>
<d/>
<result column="as_password" property="password"/>
<result column="as_phone" property="phone"/>
<result column="as_age" property="age"/>
<result column="as_sex" property="sex"/>
</resultMap>
<!-- 表示6要写的语句用来插入操作
insert
com.zhiyou.mybatis.pojo.User insert方法中传入地 参数类型
#{name} 里的name是User的字段
keyColumn 数据库中自增的字段
keyProperty 自增的字段在user中对应的字段
useGeneratedKeys:标记这个字段是否需要使用数据库中的自增长
mybatis 中的属性赋值使用的是字段直接赋值,采用反射机制
-->
<insert id="save" parameterType="com.zhiyou.mybatis.pojo.User" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
<!-- 没有set get方法也可以执行 -->
insert into user(name,password,phone,age,sex) values(#{name},#{password },#{phone },#{age },#{sex })
</insert>
<update id="update" parameterType="com.zhiyou.mybatis.pojo.User">
update user set name=#{name},password = #{password} ,phone = #{phone}, age = #{age}, sex = #{sex} where id=#{id}
</update>
<!-- resultType:查询结果的每一条记录,封装成什么样对象,如果結果中的字段名和結果類型中的字段不一樣就得不到正確結果 -->
<select id="select" resultType="com.zhiyou.mybatis.pojo.User" resultMap="base_map">
select id as as_id,name as as_name from user where id=#{id}
</select>
<select id="listByCondition" resultType="user" parameterType="user">
select * from user
<where>
<if test="age !=0">
AND age = #{age}
</if>
<if test="name!=null">
<!-- AND name=#{name} -->
AND name like concat('%',#{name},'%')
</if>
</where>
</select>
<delete id="deleteForEach">
delete from user where id in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
</mapper>
测试类
TestMubatisMapper .java
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
//获取Session 完全包含了面向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。 //输入流 //资源文件
SqlSession ss = ssf.openSession();
映射器实例(Mapper Instances)
映射器是创建来绑定映射的语句的接口。映射器接口的实例是从 SqlSession 中获得的。因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。
@Test
public void select() throws IOException {
/* Properties p = new Properties();
p.load(Resources.getResourceAsStream("db.properties"));*/
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
//获取Session //输入流 //资源文件
//完全包含了面向数据库执行 SQL 命令所需的所有方法。通过 SqlSession 实例来直接执行已映射的 SQL 语句。
SqlSession ss = ssf.openSession();
//映射器接口的实例
UserMapper mapper = ss.getMapper(UserMapper.class);
User user = mapper.select(1);
mapper.delete(4);
ss.commit();
System.out.println(user);
}
多表查询
一对一
association联合
联合元素用来处理“一对一”的关系。需要指定映射的Java实体类的属性,属性的javaType(通常MyBatis 自己会识别)
select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型
<resultMap type="employee" id="base_employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="dep" javaType="department">
<id column="dep_id" property="id"/>
<result column="dep_name" property="name"/>
</association>
</resultMap>
SQL语句
<select id="list" resultMap="base_employee">
select e.id,e.name,d.id as dep_id,d.name as dep_name from employee e left join
department d on e.dep_id = d.id
</select>
一对多
collection聚集
聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList);列表中对象的类型ofType(Java实体类);对应的数据库表的列名称;
不同情况需要告诉MyBatis 如何加载一个聚集。MyBatis 可以用两种方式加载:
select: 执行一个其它映射的SQL 语句返回一个Java实体类型。较灵活;
resultsMap: 使用一个嵌套的结果映射来处理通过join查询结果集,映射成Java实体类型
ofType 元素类型 javaType表示属性类型
<resultMap type="user" id="base_user">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!-- ofType 元素类型 javaType表示属性类型 -->
<collection property="orders" ofType="order">
<id column="o_id" property="id"/>
<result column="number" property="number"/>
</collection>
</resultMap>
SQL语句
<select id="listOrder" resultMap="base_user">
select u.id,u.name,o.id as o_id,o.number from user u left join `order` o on o.u_id=u.id
</select>
日志打印
导入jar log4j包
修改
log4j.logger.com.zhiyou.mybatis.pojo.UserMapper=TRACE
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
#
log4j.logger.com.zhiyou.mybatis.pojo.UserMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
MySQL +mybatis 分页查询
关联表的数据添加和查询
N+1问题
缓存问题
SpringMVC 和 Struts2 比较
我们从机制、性能、参数传递、设计思想四个方面来看看两者的差异:
机制:SpringMVC 的入口是 Servlet,Struts2 的入口是 Filter, 两者的实现机制不同;
性能:SpringMVC 稍微比 Struts 快些。SpringMVC 是基于方法的设计,而 Struts2 是基于类,每发一次请求都会实例化一个 action,每个 action 都会被注入属性,而 SpringMVC 基于方法,粒度更细。
参数传递:Struts2 在接受参数时,可以用属性来接受参数,这就说明参数可被多个方法共享。SpringMVC 是基于方法的设计,传递参数是通过方法形参。多个方法间不能共享。
设计思想上:Struts2 更加符合 OOP 的编程思想,SpringMVC 就比较谨慎,在 Servlet 上扩展。
Mybatis 和 Hibernate 比较
我们从难易程度、对象管理、优势对比三个方面来看看两者的差异:
难易程度:Hibernate 的真正掌握要比 Mybatis 难些。Mybatis 框架相对简单容易上手。
对象管理:Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理的功能,使开发者不需要关心底层数据库系统的细节。而 Mybatis 在这一块没有文档说明,用户需要自己对对象进行详细的管理。
优势对比:Mybatis 可以进行更为细致的 SQL 优化,可以减少查询字段。Hibernate 数据库移植性很好,Mybatis 的数据库移植性不好,不同的数据库需要些不同的 SQL。
综上所述,在性能方面 SSM 框架要优于 SSH 框架,这也是越来越多互联网企业选择 SSM 框架的主要原因。而对于业务逻辑复杂,不太在乎执行效率的传统行业,一般会选择使用 SSH 框架。所以本达人课会选择 SSM 框架来开发,其中应用到的技术将适用于大部分的互联网企业。