ORM模型
java中的对象和数据库中的表建立映射关系,通过pojo对象能够访问到数据库中的表,而且数据库的中表能
映射为pojo对象。
Hibernate缺点
* 做为全表映射框架,比如更新时候需要发送所有的字段更新
* 无法根据不同的条件组装不同的SQL
* 多表关联的查询支持较差,并不支持存储过程调用
* 虽然有HQL,但性能较差。大型互联网系统需要优化SQL,而hibernate做不到。
MyBatis
为了解决Hibernate的不足,一个半自动映射的框架产生。mybatis的映射文件包含以下三个部分
* SQL
* 映射规则
* PJO
MyBatis的基本构成
MyBatis的核心组件
* SqlSessionFactoryBuilder(构造器): 它会根据配置信息或者代码来生成SqlSessionFactory(工厂接口)
* SqlSessionFactory: 依靠工厂来生成SqlSession(会话)。
* SqlSession: 是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口
* SQL Mapper: 它是MyBatis新设计的组件,由一个Java接口和XML文件构成,需要给出对应的SQL和映射规则。
负责发送SQL去执行,并返回出结果。
构建SqlSessionFactory
每个MyBatis的应用都是以SqlSessionFactory的实例为中心的,SqlSessionFactory的实例可以通过
SqlSessionFactoryBuilder获得,SqlSessionFactory是一个工程接口而不是一个实现类,它的任务是创建
SqlSession.SqlSession类似于一个JDBC的Connection对象。
Configuration类对象中存放配置了Mybatis的信息,在MyBatis中提供了两个实现类,DefaultSQLSessionFactory(默认使用)和SqlSessionManager
* 使用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>
<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/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 定义映射器,引入的xml文件的作用是,提供了SQL和SQL对POJO的映射规则定义,
它包含了映射器里面的信息,Mybatis将会为我们解析这个xml生成映射器
-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
可以自己创建一个流读取xml文件,交给builder
public static SqlSessionFactory getSqlSessionFactory(){
InputStream input = null;
SqlSessionFactory factory = null;
try {
input = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(input);
} catch (IOException e) {
e.printStackTrace();
}
return factory;
}
实际上,MyBatis解析程序将会将这个配置文件读取到configuration对象中,然后利用sqlsessionfactorybuilder读取这个对象来创建
SQLSessionFactory。
* 使用代码的方式进行构建(不建议)
DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
构建SqlSession
类似于jdbc的Connection的对象,SqlSession是一个接口类,真正执行的是Executor接口,SqlSession只是接受信息并返回结果。
SqlSession session = null;
try{
session = factory.openSession();
//some code ...
session.commit();
}catch(Exception e){
e.printStackTrace();
session.rollback();
}finally{
//确保资源被关闭
if(session!=null){
session.close();
}
}
映射器
映射器是由Java接口和XML文件(或者注解),它的作用如下:
* 定义参数类型
* 描述缓存
* 描述SQL语句
* 定义查询结果和pojo映射关系
xml创建
1. 创建接口
public interface StudentService {
public Student queryStudentInfo(Integer id);
}
2. 创建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="cn.bing.mapper.StudentMapper">
<select id="queryStudentInfo" resultType="student">
select stu_id as stuId,stu_age as stuAge,stu_sex as stuSex,stu_name as stuName
from student_info where stu_id = #{id}
</select>
</mapper>
* namespace的值,必须和定义的接口的全限定名一致
* id 表示接口的方法名,resultType表示返回的数据类型,可以是对象的全限定名或者是别名
在mybatis-config.xml中定义别名,上面的就可以改为resultType= "Student"
<!-- 定义别名 -->
<typeAliases>
<typeAlias alias="Student" type="cn.bing.pojo.Student"/>
</typeAliases>
* parameterType:定义传入参数的类型
* 定义的pojo,必须符合javaBean的规范
* SQL列的列名和pojo的属性名保持一致,就会将结果映射到属性上,在这里都是使用了和pojo对象属性相同的别名
生命周期
1. SqlSessionFactoryBuilder
builder负责利用读取的xml文件信息来构建SqlSessionFactory,一旦构建完毕就可以回收,因而它的生命周期只是存在方法的局部,作用只是用来创建factory对象。
2. SqlSessionFactory
SqlSessionFactory的作用就是创建SqlSession,而SqlSession就是一个会话,每次访问数据库都需要通过SqlSessionFactory来创建SqlSession,因而SqlSessionFactory是存在MyBatis的整个生命周期内的,并且SqlSessionFactory的创建设计为单例的
3. SqlSession
SqlSession是一个会话,生命周期是数据库的一个事务请求过程中,而且每次使用完毕,都必须关闭,如前面在finally中关闭。
4. Mapper
Mapper是一个接口,它的作用就是发送SQL,然后返回我们需要的结果。因而它的生命周期在一个SqlSession的事务方法之内,最大的范围和SqlSession一致。当SqlSession销毁的时候,对应的Mapper也会去销毁