Mybatis简单介绍
Mybatis是一个半自动ORM映射工具,一款优秀的持久层框架。它支持编写动态sql(定制化sql),高级映射,存储过程。Mybatis的出现是弥补JDBC的不足,那么,JDBC编程有哪些不足之处。
JDBC的缺点
- JDBC在数据库链接上耗费系统资源,影响系统性能,主要是由于数据库链接的创建和释放过于频繁。而Mybatis使用数据库链接池解决这个问题。
- Sql语句和Java语句混在一起,不易调试和维护,在实际应用中可能由于需求的变化而改变sql语句,这样就需要改变Java代码(大忌)。Mybatis将Sql语句配置在xxxmappeer.xml文件中实现了Sql语句和Java代码分离。
- 在JDBC中,向Sql语句传递参数比较麻烦,因为where条件不一定,有时条件多,有时条件少,占位符要和参数一一对应,Mybatis自动把对象映射到Sql语句中。
- JDBC对结果集解析复杂,而且会导致代码变化,Mybatis自动将Sql执行结果映射值Java对象。
Mybatis配置
Mybatis主要技术点:动态Sql标签、Mapper.java 和 Mapper.xml 文件。首先,介绍Mybatis的配置文件SqlMapConfig.xml ,我们需要在这个配置文件中配置什么?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="entity"/>
</typeAliases>
<environments default="mybatis">
<environment id="mybatis">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="ok"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="dao"/>
</mappers>
</configuration>
简单介绍标签作用
<typeAliases>标签的作用是扫描在<package>下面的包名,MyBatis 会在包名下面搜索需要的 Java Bean
<environment>标签是配置环境,MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例。事务管理器transactionManager使用JDBC,dataSource使用POOLED数据库连接池。
mapper 映射器,扫描包文件。映射器是创建用来绑定映射语句的接口。映射器接口的实例是从 SqlSession 中获得的。
Mybatis执行流程
SqlMapConfig.xml ----> xxxMapper.xml ---->Configuration ----->SqlSessionFactory -----> SqlSession(会话) ---->寻找Statemnt ------> 执行Transaction(comint or rollbacck)。
介绍流程节点
- SqlSessionFactory 被 SqlSessionFactoryBuilder创建出来,SqlSessionFactoryBuilder的生命周期应该在创建出SqlSessionFactory,就不再需要它了,因此可以丢弃,我们创建SqlSessionFactoryBuilder的作用域是在方法域里面,可以重复使用SqlSessionFactoryBuilder来多次创建SqlSessionFactory,但是还是不要让其一直存在以保证所有的xml解析资源开放给其他更重要的事务。
- SqlSession被SqlSessionFactory创建,SqlSessionFactory一旦创建就一直存在,没有理由对它进行清除或重建,不必要对SqlSessionFactory进行多次的创建,因此 SqlSessionFactory 的最佳作用域是应用作用域,SqlSessionFactory使用单例模式或静态单例模式。
注意:
SqlSession不是线程安全的,不可以被共享,当多个线程使用同一个SqlSession时,我们一般不要这样做,不可以把SqlSession的实例放到静态方法中,实例变量,在使用完毕之后要在finally块中关闭它。
OGEL表达式
动态SQL:MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。if choose trim foreach
<select id="findIdStudentWithNameLike"
resultType="Student">
SELECT * FROM student
WHERE id = ‘1’
<if test="name != null">
AND name like #{name}
</if>
</select>
这条语句提供了一个可选的文本查找类型的功能。如果没有传入“name”,那么所有Id=1的学生都会返回;反之若传入了“name”,那么就会把模糊查找学生姓名为“name”的student结果返回(就这个例子而言,细心的读者会发现其中的参数值是可以包含一些掩码或通配符的)。如果想选择性的根据id 和 name 进行查找,如何做?
<select id="findStudentIdOrNameLike"
resultType="Student">
SELECT * FROM student WHERE
<if test="id != null">
AND id like #{id}
</if>
<if test="name != null ">
AND name like #{name}
</if>
</select>
<select id="findStudentIdOrNameLike"
resultType="Student">
SELECT * FROM student
<choose>
<when test="id != null">
AND id like #{id}
</when>
<when test="name != null">
AND name like #{name}
</when>
<otherwise>
AND age = 1
</otherwise>
</choose>
</select>
上面这个用到了choose when otherwise
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
trim 和 when 是一样的作用,when的用处是:一般情况下when是和if在一起使用的。
<select id="findStudentIdOrNameLike"
resultType="Student">
SELECT * FROM Student
<where>
<if test="id!= null">
id= #{id}
</if>
<if test="name != null">
AND name like #{name }
</if>
</where>
</select>