mybatis配置文件和映射文件,简述mybatis的配置和使用步骤
MyBatis介绍
MyBatis是一个持久化的ORM框架,简单易用,学习成本低。您可以执行自己手写的SQL语句,这很灵活。但MyBatis的自动化程度和可移植性较低,有时在从一个数据库迁移到另一个数据库时需要修改配置,所以只称为半自动ORM框架。
00-1010传统JDBC
@Testpublic void test()抛出SQLException { Connection conn=null;PreparedStatement pstmt=null试试{//1。加载驱动程序class . forname( com . MySQL . JDBC . driver );//2.创建连接conn=driver manager . getconnection( JDBC 3360 MySQL ://localhost 33603306/mybatis _ example , root , 123456 );//SQL语句字符串SQL= select id,user _ name,create _ time from t _ user where id=?;//获取sql执行程序pstmt=conn . prepare statement(SQL);pstmt.setInt(1,1);//执行查询//resultsetters=pstmt . execute query();pstmt . execute();ResultSet RS=PS TMT . get ResultSet();RS . next();User User=new User();user . setid(RS . getlong( id ));user . set username(RS . getstring( user _ name ));user . set create time(RS . getdate( create _ time ));system . out . println(user . tostring());} catch(Exception e){ e . printstacktrace();}最后{ //关闭资源尝试{if(conn!=null){ conn . close();} if(pstmt!=null){ pstmt . close();} } catch(SQLException e){ e . printstacktrace();} }}
传统JDBC和Mybatis相比的弊病
1.数据库连接的频繁创建和释放造成了西融的资源浪费,从而影响了系统性能。使用数据库连接池可以解决这个问题。2.sql语句被硬编码在代码中,导致代码的不断维护。在实际应用中,sql的变化可能很大,不分开维护sql代码和java代码很不方便。3.使用preparedStatement向占位符传递参数时,存在硬编码问题。因为sql中where子句的条件是不确定的,所以修改起来也不方便。/4.解析结果集时存在硬编码问题。sql的变化导致解析代码的变化,给系统维护带来不便。
00-1010 1.频繁地创建和释放数据库连接会造成系统资源的浪费,从而影响系统性能。如果使用数据库连接池,就可以解决这个问题。解决方案:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。
2.Sql语句写在代码中,导致代码难以维护,sql的实际应用可能会有很大变化。sql的改变需要改变java代码。解决方案:将XXXXmapper.xml文件中的Sql语句配置为与java代码分离。
3.给sql语句传递参数比较麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。解决方案:Mybatis自动将java对象映射到sql语句,通过语句中的parameterType定义输入参数的类型。
4.解析结果集比较麻烦,sql的变化导致解析代码的变化,解析之前需要遍历。将数据库记录封装到pojo对象中进行解析更加方便。解决方案:Mybatis自动将sql执行结果映射到java对象,通过语句中的resultType定义输出结果的类型。
传统JDBC的问题如下:
Mybatis最简单的使用示例如下:
ss="brush:java;">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
<?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> <!--properties 扫描属性文件.properties --> <properties resource="db.properties"></properties> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <plugins> <plugin interceptor="com.tuling.plugins.ExamplePlugin" ></plugin> </plugins> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <!--// mybatis内置了JNDI、POOLED、UNPOOLED三种类型的数据源,其中POOLED对应的实现为org.apache.ibatis.datasource.pooled.PooledDataSource,它是mybatis自带实现的一个同步、线程安全的数据库连接池 一般在生产中,我们会使用c3p0或者druid连接池--> <dataSource type="POOLED"> <property name="driver" value="${mysql.driverClass}"/> <property name="url" value="${mysql.jdbcUrl}"/> <property name="username" value="${mysql.user}"/> <property name="password" value="${mysql.password}"/> </dataSource> </environment> </environments> <mappers> <!--1.必须保证接口名(例如IUserDao)和xml名(IUserDao.xml)相同,还必须在同一个包中--> <package name="com.tuling.mapper"/> <!--2.不用保证同接口同包同名 <mapper resource="com/mybatis/mappers/EmployeeMapper.xml"/> 3.保证接口名(例如IUserDao)和xml名(IUserDao.xml)相同,还必须在同一个包中 <mapper class="com.mybatis.dao.EmployeeMapper"/> 4.不推荐:引用网路路径或者磁盘路径下的sql映射文件 file:///var/mappers/AuthorMapper.xml <mapper url="file:E:/Study/myeclipse/_03_Test/src/cn/sdut/pojo/PersonMapper.xml"/>--> </mappers></configuration>
总结下就是分为下面四个步骤:
从配置文件(通常是XML文件)得到SessionFactory;从SessionFactory得到SqlSession;通过SqlSession进行CRUD和事务的操作;执行完相关操作之后关闭Session。
MyBatis 源码编译
1.下载mybatis源码
下载地址:https://github.com/mybatis/mybatis-3
我下载的最新的 mybatis-3-mybatis-3.4.6,下载完后解压。打开pom.xml
<parent> <groupId>org.mybatis</groupId> <artifactId>mybatis-parent</artifactId> <version>30</version> <relativePath /> </parent>
发现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 插件
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pdf-plugin</artifactId> </plugin> -->
然后重新编译
4.导入IDEA
导入方式就不多说,按maven项目导入即可!导入成功后:
如果希望在spring源码中引入你自己的这份源码,可以做如下操作
1.修改你mybatis源码的pom的 这样可以和官方的区分开来
<version>3.5.3-xsls</version>
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 包
<plugin> <artifactId>maven-source-plugin</artifactId> <version>3.0.1</version> <configuration> <attach>true</attach> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>jar</goal> </goals> </execution> </executions></plugin>
Mybatis启动流程分析
String resource = "mybatis-config.xml";//将XML配置文件构建为Configuration配置类reader = Resources.getResourceAsReader(resource);// 通过加载配置文件流构建一个SqlSessionFactory DefaultSqlSessionFactorySqlSessionFactory 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); }
下面我们看下解析配置文件过程中的一些细节。先给出一个配置文件的例子:
<?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> <!--SqlSessionFactoryBuilder中配置的配置文件的优先级最高;config.properties配置文件的优先级次之;properties标签中的配置优先级最低 --> <properties resource="org/mybatis/example/config.properties"> <property name="username" value="dev_user"/> <property name="password" value="F2Fa3!33TYyg"/> </properties> <!--一些重要的全局配置--> <settings> <setting name="cacheEnabled" value="true"/> <!--<setting name="lazyLoadingEnabled" value="true"/>--> <!--<setting name="multipleResultSetsEnabled" value="true"/>--> <!--<setting name="useColumnLabel" value="true"/>--> <!--<setting name="useGeneratedKeys" value="false"/>--> <!--<setting name="autoMappingBehavior" value="PARTIAL"/>--> <!--<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>--> <!--<setting name="defaultExecutorType" value="SIMPLE"/>--> <!--<setting name="defaultStatementTimeout" value="25"/>--> <!--<setting name="defaultFetchSize" value="100"/>--> <!--<setting name="safeRowBoundsEnabled" value="false"/>--> <!--<setting name="mapUnderscoreToCamelCase" value="false"/>--> <!--<setting name="localCacheScope" value="STATEMENT"/>--> <!--<setting name="jdbcTypeForNull" value="OTHER"/>--> <!--<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>--> <!--<setting name="logImpl" value="STDOUT_LOGGING" />--> </settings> <typeAliases> </typeAliases> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!--默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果--> <!--如果某些查询数据量非常大,不应该允许查出所有数据--> <property name="pageSizeZero" value="true"/> </plugin> </plugins> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://10.59.97.10:3308/windty"/> <property name="username" value="windty_opr"/> <property name="password" value="windty!234"/> </dataSource> </environment> </environments> <databaseIdProvider type="DB_VENDOR"> <property name="MySQL" value="mysql" /> <property name="Oracle" value="oracle" /> </databaseIdProvider> <mappers> <!--这边可以使用package和resource两种方式加载mapper--> <!--<package name="包名"/>--> <!--<mapper resource="./mappers/SysUserMapper.xml"/>--> <mapper resource="./mappers/CbondissuerMapper.xml"/> </mappers></configuration>
下面是解析配置文件的核心方法:
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请查看下面的相关链接
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。