前言:MyBatis是一个非常优秀的存储过程和高级映射的优秀持久层框架。大大简化了,数据库操作中的常用操作。下面将介绍MyBatis的一些概念和在Eclipse上的实际项目搭建使用。
一、MyBatis的概念介绍
1.1、背景介绍
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。
用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类—-Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。
1.2、总体流程
(1)加载配置并初始化
触发条件:加载配置文件
将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)接收调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
(3)处理操作请求 触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(4)返回处理结果将最终的处理结果返回。
1.3、功能架构
功能架构讲解:
我们把Mybatis的功能架构分为三层:
(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
1.4、框架架构
框架架构讲解:
(1)加载配置:配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
(4)结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。
1.5、动态SQL
MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。尽管与动态SQL一起工作不是在开一个party,但是MyBatis确实能通过在任何映射SQL语句中使用强大的动态SQL来改进这些状况。
动态SQL元素对于任何使用过JSTL或者类似于XML之类的文本处理器的人来说,都是非常熟悉的。在上一版本中,需要了解和学习非常多的元素,但在MyBatis 3 中有了许多的改进,现在只剩下差不多二分之一的元素。MyBatis使用了基于强大的OGNL表达式来消除了大部分元素。
二、MyBatis实例
接下来的MyBatis的实例是在eclipse+maven+MySQL的基础上写的,如果猿友们,没有搭建好maven,甚至没有听过maven的,那么请阅读博主的关于maven的文章:http://blog.csdn.net/u013142781/article/details/50316383(含实例哦)
如果mysql没有搭建好的话,可以阅读博主的另外一篇文章:http://blog.csdn.net/u013142781/article/details/50300233
1、创建表,并插入数据:
CREATE TABLE `t_user` ( `USER_ID` int(11) NOT NULL AUTO_INCREMENT, `USER_NAME` char(30) NOT NULL, `USER_PASSWORD` char(10) NOT NULL, PRIMARY KEY (`USER_ID`), KEY `IDX_NAME` (`USER_NAME`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
INSERT INTO t_user (USER_ID, USER_NAME, USER_PASSWORD) VALUES (1, 'luoguohui', '123456'); INSERT INTO t_user (USER_ID, USER_NAME, USER_PASSWORD) VALUES (2, 'zhangsan', '123456');
2、添加包的依赖,我的文章 Maven之初恋,已经创建好的maven项目,现在只需要添加如下依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.luo</groupId> <artifactId>first_maven_project</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <!-- spring版本号 --> <spring.version>3.2.8.RELEASE</spring.version> <!-- log4j日志文件管理包版本 --> <slf4j.version>1.6.6</slf4j.version> <log4j.version>1.2.12</log4j.version> <!-- junit版本号 --> <junit.version>4.10</junit.version> <!-- MyBatis版本号 --> <MyBatis.version>3.2.1</MyBatis.version> </properties> <dependencies> <!-- 添加Spring依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!--单元测试依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- 日志文件管理包 --> <!-- log start --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!-- log end --> <!--spring单元测试依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!--MyBatis依赖 --> <dependency> <groupId>org.MyBatis</groupId> <artifactId>MyBatis</artifactId> <version>${MyBatis.version}</version> </dependency> <!-- MyBatis/spring包 --> <dependency> <groupId>org.MyBatis</groupId> <artifactId>MyBatis-spring</artifactId> <version>1.2.0</version> </dependency> <!-- mysql驱动包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.29</version> </dependency> </dependencies> </project>
3、配置文件:
3.1、MyBatis包下添加MyBatis-config.xml文件(MyBatis配置文件):
<?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> </configuration>
3.2、properties包下添加jdbc.properties文件(数据源配置文件):
jdbc_driverClassName=com.mysql.jdbc.Driver jdbc_url=jdbc:mysql://localhost:3306/luo jdbc_username=root jdbc_password=root
3.3、mapper包下userMapper.xml配置文件(表映射文件):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//MyBatis.org//DTD Mapper 3.0//EN" "http://MyBatis.org/dtd/MyBatis-3-mapper.dtd"> <mapper namespace="com.luo.dao.UserDao"> <!--设置domain类和数据库中表的字段一一对应,注意数据库字段和domain类中的字段名称不致,此处一定要!--> <resultMap id="BaseResultMap" type="com.luo.domain.User"> <id column="USER_ID" property="userId" jdbcType="INTEGER" /> <result column="USER_NAME" property="userName" jdbcType="CHAR" /> <result column="USER_PASSWORD" property="userPassword" jdbcType="CHAR" /> </resultMap> <!-- 查询单条记录 --> <select id="selectUserById" parameterType="int" resultMap="BaseResultMap"> SELECT * FROM t_user WHERE USER_ID = #{userId} </select> </mapper>
3.4、spring配置文件application.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 引入jdbc配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:properties/*.properties</value> <!--要是有多个配置文件,只需在这里继续添加即可 --> </list> </property> </bean> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- 不使用properties来配置 --> <!-- <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/learning" /> <property name="username" value="root" /> <property name="password" value="christmas258@" /> --> <!-- 使用properties来配置 --> <property name="driverClassName"> <value>${jdbc_driverClassName}</value> </property> <property name="url"> <value>${jdbc_url}</value> </property> <property name="username"> <value>${jdbc_username}</value> </property> <property name="password"> <value>${jdbc_password}</value> </property> </bean> <!-- 自动扫描了所有的XxxxMapper.xml对应的mapper接口文件,这样就不用一个一个手动配置Mpper的映射了,只要Mapper接口类和Mapper映射文件对应起来就可以了。 --> <bean class="org.MyBatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.luo.dao" /> </bean> <!-- 配置Mybatis的文件 ,mapperLocations配置**Mapper.xml文件位置,configLocation配置MyBatis-config文件位置--> <bean id="sqlSessionFactory" class="org.MyBatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath:mapper/*.xml"/> <property name="configLocation" value="classpath:MyBatis/MyBatis-config.xml" /> <!-- <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" /> --> </bean> <!-- 自动扫描注解的bean --> <context:component-scan base-package="com.luo.service" /> </beans>
4、接口和类的配置:
4.1、com.luo.domain下添加User.java文件:
package com.luo.domain; public class User { private Integer userId; private String userName; private String userPassword; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } }
4.2、com.luo.dao下添加UserDao.java文件:
package com.luo.dao; import com.luo.domain.User; public interface UserDao { /** * @param userId * @return User */ public User selectUserById(Integer userId); }
4.3、com.luo.service下添加UserService.java接口和UserServiceImpl实现类:
package com.luo.service; import com.luo.domain.User; public interface UserService { User selectUserById(Integer userId); }
package com.luo.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.luo.dao.UserDao; import com.luo.domain.User; @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; public User selectUserById(Integer userId) { return userDao.selectUserById(userId); } }
5、单元测试
5.1、com.luo.baseTest下添加SpringTestCase.java:
package com.luo.baseTest; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; //指定bean注入的配置文件 @ContextConfiguration(locations = { "classpath:application.xml" }) //使用标准的JUnit @RunWith注释来告诉JUnit使用Spring TestRunner @RunWith(SpringJUnit4ClassRunner.class) public class SpringTestCase extends AbstractJUnit4SpringContextTests { }
5.2、com.luo.service添加UserServiceTest.java:
package com.luo.service; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.luo.baseTest.SpringTestCase; import com.luo.domain.User; public class UserServiceTest extends SpringTestCase { @Autowired private UserService userService; @Test public void selectUserByIdTest(){ User user = userService.selectUserById(1); System.out.println(user.getUserName() + ":" + user.getUserPassword()); } }
5.3、运行单元测试,UserServiceTest右键Run As –>Junit Test,运行结果: