1.介绍
MyBatis是一个优秀的**持久层框架**,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
2.mybatis与hibernate不同
- Mybatis和hibernate不同,它不完全是一个ORM框架,因为**MyBatis需要程序员自己编写Sql语句**。mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
- Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是**mybatis无法做到数据库无关性**,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
- Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
3.Mybatis架构
1、 SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
2.mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
3、通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
4、由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
5、mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
6、Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
7、Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
8、Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
4.Mybatis使用步骤
1.导入jar包
mybatis-3.2.7.jar mybatis的核心包
lib文件夹中所有包 mybatis的依赖包所在
mysql-connector-java-5.1.7-bin.jar 数据驱动包
2.在src下创建 log4j.properties 文件(内容如下):主要用于打印日志文件,了解即可 (log4j.properties)
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# 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
3. 在src下创建SqlMapConfig.xml(大概如下,了解即可,在和spring整合的时候会被代替):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>
<!-- 是用resource属性加载外部配置文件(例如c3p0这里) -->
<properties resource="db.properties">
<!-- 在properties内部用property定义属性 -->
<property name="jdbc.username" value="root123" />
<property name="jdbc.password" value="root123" />
</properties>
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="cn.itcast.mybatis.pojo.User" />
<!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) -->
<package name="cn.itcast.mybatis.pojo" />
<package name="其它包" />
</typeAliases>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>
4.创建实体类(javaBean通常与数据库表对应)(user.java)
在src下的实体类目录下创建
Public class User {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
get/set……
5.创建sql映射文件**(UserMapper.xml)**
在src下的实体类目录下创建sql映射文件UserMapper.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">
<!-- namespace:命名空间,用于隔离sql -->
<!-- 还有一个很重要的作用,使用动态代理开发DAO,1. namespace必须和Mapper接口类路径一致 -->
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper"><!--映射文件的目录-->
<!--中间写的是sql语句,下面是个实例-->
<!-- 通过ID查询一个用户 -->
<!-- id:statement的id 或者叫做sql的id( id必须和Mapper接口方法名一致)-->
<!-- parameterType:声明输入参数的类型(parameterType必须和接口方法参数类型一致) -->
<!-- resultType:声明输出结果的类型,应该填写pojo的全路径,但是在sqlMsqlMapConfig.xml中配置了别名,所以可以直接写短的路径(resultType必须和接口方法返回值类型一致) -->
<!-- #{}:输入参数的占位符,相当于jdbc的? -->
<select id="findUserById" parameterType="Integer" resultType="User">
select * from user where id = #{v}
</select>
</mapper>
6.创建UserMapper(接口文件(Mapper动态代理方式))(UserMapper.java)
在UserMapper.xml的目录中创建UserMapper.java接口(一定要在同一个目录当中)
public interface UserMapper {
//只写了一个方法,不需要实例化这个方法
//根据id查询
public User findUserById(Integer id);
}
7.加载映射文件(在SqlMapConfig.xml的configuration属性中写入下面的代码)(mybatis框架需要加载Mapper.xml映射文件,上面的文件就是mapper.xml映射文件)
<!-- Mapper的位置 Mapper.xml 写Sql语句的文件的位置 -->
<!--三种方法,推荐使用第三种,没打注释的那种(但是框架整合之后就不需要了,直接spring扫描)-->
<mappers>
<!-- <mapper resource="sqlmap/User.xml" class="" url=""/> -->
<!-- <mapper resource="sqlmap/User.xml" class="" url=""/> -->
<!-- <mapper class="com.itheima.mybatis.mapper.UserMapper" /> -->
<!-- <mapper url="" /> -->
<package name="com.itheima.mybatis.mapper"/><!--直接写mappper所在的包名,直接会加载所有在本目录下的文件,包括子类的子类-->
<!--注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。-->
</mappers>
8.测试
private SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws Exception {
// 创建SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 加载SqlMapConfig.xml配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlsessionFactory
this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
@Test
public void testQueryUserById() {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
//-------------------------------------------------几个测试下来,只需要更改中间的代码
// 从sqlSession中获取Mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 执行查询方法
User user = userMapper.findUserById(1);
System.out.println(user);
//----------------------------------------------------
// 和spring整合后由spring管理
sqlSession.close();
}
5.补充
Mapper接口开发需要遵循以下规范(上面就是mapper接口开发):
1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
1.SqlSession的使用范围
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
SqlSession通过SqlSessionFactory创建。
SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
2.SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。
3.SqlSession
SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
4.SqlMapConfig.xml中配置的内容和顺序如下:(注意: MyBatis 将按照下面的顺序来加载属性)
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)