##搭建一個簡單的Mybatis+Maven項目 ###Maven依賴html
<!-- 添加log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency> <!-- 添加mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.6</version> </dependency> <!-- 添加mysql驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.12</version> </dependency> <!-- 添加junit驅動 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.14.8</version> </dependency>
###代碼java
@Data public class Student { private Long id; private String name; } public interface StudentDao { public void insert(Student student); public Student findUserById (int id); public List<Student> findAllUsers(); } public class StudentDaoTest { @Test public void findUserById() { SqlSession sqlSession = getSessionFactory().openSession(); StudentDao userMapper = sqlSession.getMapper(StudentDao.class); Student user = userMapper.findUserById(1); System.out.println(user.toString()); } //Mybatis 經過SqlSessionFactory獲取SqlSession, 而後才能經過SqlSession與數據庫進行交互 private static SqlSessionFactory getSessionFactory() { SqlSessionFactory sessionFactory = null; String resource = "configuration.xml"; try { sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource)); } catch (IOException e) { e.printStackTrace(); } return sessionFactory; } }
###配置文件mysql
//configuration.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 resource="dbConfig.properties"></properties> <!-- 指定Mybatis使用log4j --> <settings> <setting name="logImpl" value="LOG4J"/> </settings> <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://localhost:3306/student"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 映射文件,mybatis精髓, 後面纔會細講 --> <mappers> <mapper resource="userDao-mapping.xml"/> </mappers> </configuration> //userDao-mapping.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd"> <mapper namespace="com.mybatis.StudentDao"> <select id="findUserById" resultType="com.mybatis.Student" > select * from student where id = #{id} </select> </mapper>
##經過SqlSessionFactory獲取SqlSession ###執行流程圖 ###源碼走讀 ####獲取readersql
sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource)); Resources.getResourceAsReader(resource)
####獲取SqlSessionFactory #####build()方法數據庫
//調用SqlSessionFactoryBuilder.build()方法獲取SqlSessionFactory public SqlSessionFactory build(Reader reader, String environment, Properties properties) { //獲取解析器 XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); //解析配置文件 return build(parser.parse()); }
#####解析配置返回configurationapache
//XMLConfigBuilder.parse()解析配置返回configuration public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; //configuration爲根節點 parseConfiguration(parser.evalNode("/configuration")); //解析完成後返回configration return configuration; } private void parseConfiguration(XNode root) { //接下來有10個子節點,注意在configuration.xml中配置子節點的時候得按照解析的順序 //這些節點的解析後面的博客再走讀 try { propertiesElement(root.evalNode("properties")); //issue #117 read properties first typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); settingsElement(root.evalNode("settings")); environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631 databaseIdProviderElement(root.evalNode("databaseIdProvider")); typeHandlerElement(root.evalNode("typeHandlers")); mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } }
#####得到SqlSessionFactory緩存
//經過configuration得到SqlSessionFactory public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
####獲取sqlSession #####調用openSession()方法session
//調用SqlSessionFactory的openSession()方法 public SqlSession openSession() { //主要看看這個方法 return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }
######獲取SqlSessionmybatis
//經過DefaultSqlSessionFactoryz獲取SqlSession private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { //Environment子節點得到數據鏈接的配置還有事務的配置 final Environment environment = configuration.getEnvironment(); final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //獲取執行器 final Executor executor = configuration.newExecutor(tx, execType); return new DefaultSqlSession(configuration, executor, autoCommit); } catch (Exception e) { closeTransaction(tx); // may have fetched a connection so lets call close() throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
######獲取Executorapp
//Configurationz中獲取執行器(Executor) public Executor newExecutor(Transaction transaction, ExecutorType executorType) { executorType = executorType == null ? defaultExecutorType : executorType; executorType = executorType == null ? ExecutorType.SIMPLE : executorType; Executor executor; if (ExecutorType.BATCH == executorType) { executor = new BatchExecutor(this, transaction); } else if (ExecutorType.REUSE == executorType) { executor = new ReuseExecutor(this, transaction); } else { executor = new SimpleExecutor(this, transaction); } //緩存配置,以下 /* <select id="findUserById" useCache="true" resultType="com.mybatis.Student"> select * from student where id = #{id} </select> /* if (cacheEnabled) { executor = new CachingExecutor(executor); } //執行攔截器 其實就是plugins子節的配置 executor = (Executor) interceptorChain.pluginAll(executor); return executor; }
經過上面的操做變得到有含有confingration,Executor,transaction,數據庫鏈接等的sqlsession。