##搭建一个简单的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。