MyBatis配置文件解析与MyBatis实例演示

网友投稿 269 2022-08-15


MyBatis配置文件解析与MyBatis实例演示

MyBatis介绍

MyBatis是一个持久层的ORM框架,使用简单,学习成本较低。可以执行自己手写的SQL语句,比较灵活。但是MyBatis的自动化程度不高,移植性也不高,有时从一个数据库迁移到另外一个数据库的时候需要自己修改配置,所以称只为半自动ORM框架

传统JDBC和Mybatis相比的弊病

传统JDBC

@Test

public void test() throws SQLException {

Connection conn=null;

PreparedStatement pstmt=null;

try {

// 1.加载驱动

Class.forName("com.mysql.jdbc.Driver");

// 2.创建连接

conn= DriverManager.

getConnection("jdbc:mysql://localhost:3306/mybatis_example", "root", "123456");

// SQL语句

String sql="select id,user_name,create_time from t_user where id=?";

// 获得sql执行者

pstmt=conn.prepareStatement(sql);

pstmt.setInt(1,1);

// 执行查询

//ResultSet rs= pstmt.executeQuery();

pstmt.execute();

ResultSet rs= pstmt.getResultSet();

rs.next();

User user =new User();

user.setId(rs.getLong("id"));

user.setUserName(rs.getString("user_name"));

user.setCreateTime(rs.getDate("create_time"));

System.out.println(user.toString());

} catch (Exception e) {

e.printStackTrace();

}

finally{

// 关闭资源

try {

if(conn!=null){

conn.close();

}

if(pstmt!=null){

pstmt.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

}

传统JDBC的问题如下:

1.数据库连接创建,释放频繁造成西戎资源的浪费,从而影响系统性能,使用数据库连接池可以解决问题。2.sql语句在代码中硬编码,造成代码的不已维护,实际应用中sql的变化可能较大,sql代码和java代码没有分离开来维护不方便。3.使用preparedStatement向有占位符传递参数存在硬编码问题因为sql中的where子句的条件不确定,同样是修改不方便/4.对结果集中解析存在硬编码问题,sql的变化导致解析代码的变化,系统维护不方便。

mybatis对传统的JDBC的解决方案

1、数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。

2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。

3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。

4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

Mybaits整体体系图

一个Mybatis最简单的使用例子如下:

public class App {

public static void main(String[] args) {

String resource = "mybatis-config.xml";

Reader reader;

try {

//将XML配置文件构建为Configuration配置类

reader = Resources.getResourceAsReader(resource);

// 通过加载配置文件流构建一个SqlSessionFactory DefaultSqlSessionFactory

SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);

// 数据源 执行器 DefaultSqlSession

SqlSession session = sqlMapper.openSession();

try {

// 执行查询 底层执行jdbc

//User user = (User)session.selectOne("com.tuling.mapper.selectById", 1);

UserMapper mapper = session.getMapper(UserMapper.class);

System.out.println(mapper.getClass());

User user = mapper.selectById(1L);

System.out.println(user.getUserName());

} catch (Exception e) {

e.printStackTrace();

}finally {

session.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

mybatis-config.xml

"http://mybatis.org/dtd/mybatis-3-config.dtd">

总结下就是分为下面四个步骤:

从配置文件(通常是XML文件)得到SessionFactory;从SessionFactory得到SqlSession;通过SqlSession进行CRUD和事务的操作;执行完相关操作之后关闭Session。

MyBatis 源码编译

1.下载mybatis源码

下载地址:https://github.com/mybatis/mybatis-3

我下载的最新的 mybatis-3-mybatis-3.4.6,下载完后解压。打开pom.xml

org.mybatis

mybatis-parent

30

发现mybatis源码依赖mybatis-parent 所以编译前要先下载mybatis-parent

2.下载mybatis-parent源码

下载地址:https://github.com/mybatis/parent

下载的mybatis-parent版本要和mybatis源文件pom.xml 版本一致。

3.编译mybatis-parent源码

切换到你下载的mybatis-parent目录:

mvn clean install

3.编译mybatis源码

切换到你下载的mybatis源码目录:

mvn clean

mvn install -Dmaven.test.skip=true

如果出现如下错误:

打开pom.xml 文件注释掉 maven-pdf-plugin 插件

然后重新编译

4.导入IDEA

导入方式就不多说,按maven项目导入即可!导入成功后:

如果希望在spring源码中引入你自己的这份源码,可以做如下操作

1.修改你mybatis源码的pom的 这样可以和官方的区分开来

3.5.3-xsls

2.这样你在spring源码中就可以引入这份mybatis源码了.

如果引入mybatis-spring 同样需要做1、3步骤

compile("org.mybatis:mybatis-spring:2.0.3-xsls")

compile("org.mybatis:mybatis:3.5.3-xsls")

3.当然,如果你想在spring这边看到你mybatis源码相关的注释,还得在mybatis源码的pom里面加入plugin,使它生成 jar 的同时 生成 sources 包

maven-source-plugBppTwNJwKcin

3.0.1

true

compile

jar

Mybatis启动流程分析

String resource = "mybatis-config.xml";

//将XML配置文件构建为Configuration配置类

reader = Resources.getResourceAsReader(resource);

// 通过加载配置文件流构建一个SqlSessionFactory DefaultSqlSessionFactory

SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);

通过上面代码发现,创建SqlSessionFactory的代码在SqlSessionFactoryBuilder中,进去一探究竟:

//整个过程就是将配置文件解析成Configration对象,然后创建SqlSessionFactory的过程

//Configuration是SqlSessionFactory的一个内部属性

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {

try {

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

return build(parser.parse());

} catch (Exception e) {

throw ExceptionFactory.wrapException("Error building SqlSession.", e);

} finally {

ErrorContext.instance().reset();

try {

inputStream.close();

} catch (IOException e) {

// Intentionally ignore. Prefer previous error.

}

}

}

public SqlSessionFactory build(Configuration config) {

return new DefaultSqlSessionFactory(config);

}

下面我们看下解析配置文件过程中的一些细节。先给出一个配置文件的例子:

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

下面是解析配置文件的核心方法:

private void parseConfiguration(XNode root) {

try {

//issue #117 read properties first

//解析properties标签,并set到Configration对象中

//在properties配置属性后,在Mybatis的配置文件中就可以使用${key}的形式使用了。

propertiesElement(root.evalNode("properties"));

//解析setting标签的配置

Properties settings = settingsAsProperties(root.evalNode("settings"));

//添加vfs的自定义实现,这个功能不怎么用

loadCustomVfs(settings);

//配置类的别名,配置后就可以用别名来替代全限定名

//mybatis默认设置了很多别名,参考附录部分

typeAliasesElement(root.evalNode("typeAliases"));

//解析拦截器和拦截器的属性,set到Configration的interceptorChain中

//MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

//Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)

//ParameterHandler (getParameterObject, setParameters)

//ResultSetHandler (handleResultSets, handleOutputParameters)

//StatementHandler (prepare, parameterize, batch, update, query)

pluginElement(root.evalNode("plugins"));

//Mybatis创建对象是会使用objectFactory来创建对象,一般情况下不会自己配置这个objectFactory,使用系统默认的objectFactory就好了

objectFactoryElement(root.evalNode("objectFactory"));

objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));

reflectorFactoryElement(root.evalNode("reflectorFactory"));

//设置在setting标签中配置的配置

settingsElement(settings);

//解析环境信息,包括事物管理器和数据源,SqlSessionFactoryBuilder在解析时需要指定环境id,如果不指定的话,会选择默认的环境;

//最后将这些信息set到Configration的Environment属性里面

environmentsElement(root.evalNode("environments"));

//

databaseIdProviderElement(root.evalNode("databaseIdProvider"));

//无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。解析typeHandler。

typeHandlerElement(root.evalNode("typeHandlers"));

//解析Mapper

mapperElement(root.evalNode("mappers"));

} catch (Exception e) {

throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);

}

}

上面解析流程结束后会生成一个Configration对象,包含所有配置信息,然后会创建一个SqlSessionFactory对象,这个对象包含了Configration对象。

简单总结

对于MyBatis启动的流程(获取SqlSession的过程)这边简单总结下:

SqlSessionFactoryBuilder解析配置文件,包括属性配置、别名配置、拦截器配置、环境(数据源和事务管理器)、Mapper配置等;解析完这些配置后会生成一个Configration对象,这个对象中包含了MyBatis需要的所有配置,然后会用这个Configration对象创建一个SqlSessionFactory对象,这个对象中包含了Configration对象;

这里解析的东西比较多,大致概况:会把所有的信息都解析到Configration对象中,比较简单不多介绍。

更多关于MyBatis配置文件解析与MyBatis实例演示以及怎样编译安装MyBatis请查看下面的相关链接


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java如何实现获取客户端ip地址的示例代码
下一篇:Java实现最小生成树算法详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~