什么是MyBatis
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现。
再来说说什么是OMR
- ORM(对象关系映射):利用对象和数据库之间映射的数据,把Java程序中的对象持久化到数据库中的表内。
-
- 这里的“半自动化”,是相对 Hibernate 等提供了全面的数据库封装机制的“全自动化”ORM 实现而言,“全自动”ORM 实现了 POJO 和数据库表之间的映射,以及 SQL 的自动生成和执行。而 MyBatis 的着力点,则在于 POJO 与 SQL 之间的映射关系。也就是说,MyBatis 并不会为程序员在运行期自动生成 SQL 执行。具体的 SQL 需要程序员编写,然后通过映射配置文件,将 SQL 所需的参数,以及返回的结果字段映射到指定 POJO。使用 ibatis 提供的 ORM 机制,对业务逻辑实现人员而言,面对的是纯粹的 Java 对象,这一层与通过 Hibernate 实现 ORM 而言基本一致,而对于具体的数据操作,Hibernate会自动生成 SQL 语句,而 MyBatis 则要求开发者编写具体的 SQL 语句。相对 Hibernate 等“全自动”ORM 机制而言,ibatis 以 SQL 开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。作为“全自动”ORM 实现的一种有益补充,MyBatis 的出现显得别具意义。
我们可以再说一下mybatis的优缺点:
-
- 优点:1.简单易学
- 2.消除了大量的JDBC过多的代码
- 3.良好的性能
- 3.友好的Spring集成支持
- 4.友好的第三方缓存类库集成支持
- 缺点:1、编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
- 2、SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
- 3、缓存机制不佳
- 优点:1.简单易学
既然我们要用MyBaits链接数据库,所以需要一个数据库的驱动包,以及一个MyBatis源码包,(通过idea创建Maven项目)在pom.xml文件中引入需要的依赖。其中引入junit是便于后面的测试,而log4j则能看到一些日志信息,有时能为找bug提供帮助。
- <dependencies>
- <dependency>
- <!--日志文件所用的jar包-->
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.12</version>
- </dependency>
- <dependency>
- <!--mysql驱动包-->
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.28</version>
- </dependency>
- <dependency>
- <!--mybatisjar包-->
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.2.8</version>
- </dependency>
- <dependency>
- <!--测试所用的jar包-->
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.10</version>
- </dependency>
- </dependencies>
- log4j所用代码可以从官网找到
- log4j.rootLogger=DEBUG,CONSOLE,file
- log4j.logger.cn.smbms.dao=debug
- log4j.logger.com.ibatis=debug
- log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
- log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
- log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
- log4j.logger.java.sql.Connection=debug
- log4j.logger.java.sql.Statement=debug
- log4j.logger.java.sql.PreparedStatement=debug
- log4j.logger.java.sql.ResultSet=debug
- log4j.logger.org.tuckey.web.filters.urlrewrite.UrlRewriteFilter=debug
- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
- log4j.appender.Threshold=error
- log4j.appender.CONSOLE.Target=System.out
- log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
- log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n
- log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
- log4j.appender.file.DatePattern=yyyy-MM-dd
- log4j.appender.file.File=log.log
- log4j.appender.file.Append=true
- log4j.appender.file.Threshold=error
- log4j.appender.file.layout=org.apache.log4j.PatternLayout
- log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
- log4j.logger.com.opensymphony.xwork2=error
接下来创建MyBatis核心配置文件。MyBatis核心配置文件主要用于配置数据库连接和Mybatis运行时所需要的各种特性,包含了行为的设置(setting) 和属性(properties)信息。命为为"mybatis-config.xml"以区分各个配置文件。
- <configuration>
- <!--调用database.properties文件-->
- <properties resource="database.properties"></properties>
- <!--选择log4j日志存储文件-->
- <settings>
- <setting name="logImpl" value="LOG4J"/>
- </settings>
- <!--类型别名-->
- <typeAliases>
- <typeAlias alias="Tuser" type="cn.jdbc.entity.Tuser"></typeAlias>
- </typeAliases>
- <environments default="dvr">
- <environment id="dvr">
- <!--事务管理器 选择jdbc获取事务-->
- <transactionManager type="JDBC"></transactionManager>
- <!--数据源有POOLED 和UNPOLED可选择是否使用数据源-->
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver"></property>
- <property name="url" value="${jdbc.url}"></property>
- <property name="username" value="${jdbc.username}"></property>
- <property name="password" value="${jdbc.password}"></property>
- </dataSource>
- </environment>
- </environments>
- <mappers>
- <!--mappers是映射器,把mapper文件加入到配置文件中-->
- <mapper resource="cn/jdbc/dao/TuserMapper.xml"></mapper>
- </mappers>
- </configuration>
PS:datasource type设置为POOLED,MyBatis会创建一个数据库连接池,连接池中的一个连接将会被用作数据库操作,一旦数据库操作完成,MyBatis会将此连接返回给连接池,在开发或测试环境中,经常使用此方式。
1.数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个Vector对象中,一旦数据库连接建立后,不同的数据库访问请求就可以共享这些连接,这样,通过复用这些已经建立的数据库连接,可以克服上述缺点,极大地节省系统资源和时间。
数据库连接池的主要操作如下:(1)建立数据库连接池对象(服务器启动)。
(2)按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。
(3)对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
(4)存取数据库。
(5)关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)
(6)释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。
2,使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等,MyBatis事务的创建是交给TransactionFactory 事务工厂来创建的,如果我们将<transactionManager>的type 配置为"JDBC",那么,在MyBatis初始化解析<environment>节点时,会根据type="JDBC"创建一个JdbcTransactionFactory工厂。
- private TransactionFactory transactionManagerElement(XNode context) throws Exception {
- if (context != null) {
- String type = context.getStringAttribute("type");
- Properties props = context.getChildrenAsProperties();
- /*
- 在Configuration初始化的时候,会通过以下语句,给JDBC和MANAGED对应的工厂类
- typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
- typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
- 下述的resolveClass(type).newInstance()会创建对应的工厂实例
- */
- TransactionFactory factory = (TransactionFactory) resolveClass(type).newInstance();
- factory.setProperties(props);
- return factory;
- }
- throw new BuilderException("Environment declaration requires a TransactionFactory.");
- }
- 如上述代码所示,如果type = "JDBC",则MyBatis会创建一个JdbcTransactionFactory.class 实例;
SqlSessionFactory可以理解为创建SqlSession实例的工厂,所有MyBatis应用都是以SqlSessionFactory实例为中心,而
SqlSessionFactory可通过SqlSessionFactoryBuilder对象来获取。然后运用SqlSessionFactory提供的openSession()方法来获取SqlSession实例。因为SqlSessionFactory一旦创建会一直存在,所以没必要重复创建或者销毁它,因此我们最好使用单例模式来优化我们的测试类,把它放在静态块中来实现。
public class mybatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
String source = "mybatis-config.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(source);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession createSqlSession(){
return sqlSessionFactory.openSession();
}
public static void closeSqlSession(SqlSession sqlSession){
if(sqlSession!=null){
sqlSession.close();
}
}
}
- 测试类
public class tuserTest {
@Test
public void testQueryCount(){
SqlSession sqlSession = null;
int count=0;
try{
sqlSession = mybatisUtil.createSqlSession();
count = sqlSession.selectOne("cn.bdqn.dao.TuserMapper.querycount");
}catch (Exception e){
}finally {
mybatisUtil.closeSqlSession(sqlSession);
}
System.out.println(count);
}
}
运行时控制台打印连接成功,代表MyBatis连接数据库成功,然后就可以进行其他的相关操作了。