Spring集成MyBatis
本文原创,原文地址为http://www.cnblogs.com/fengzheng/p/5045105.html
如果觉得 Hibernate 不够灵活,可以尝试用 Mybatis。相比于 Hibernate,Mybatis 则显得更加轻量、更加灵活,对于我这种不喜欢被束缚的人,使用 Mybatis 更加顺手、舒心一些。
MyBatis 是什么
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生 Map 使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects, 普通的 Java 对象) 映射成数据库中的记录。
项目结构及说明
项目最终结构如下图:
项目结构介绍:
- com.springapp.mvc 包为 mvc 结构,分别为视图、数据访问层、模型、服务接口。
- resource 中分别放置各种配置文件和属性定义文件
- webapp/WEB-INF/view 中为 freemarker 的模板文件
- mvc-dispatcher-servlet.xml 为默认的 mvc 配置文件
- web.xml 是 java web 项目配置文件
引用 MyBatis 的支持
之前创建 MVC 项目的过程不是本文介绍重点,略过不讲。此项目采用 maven 的方式创建,引用 MyBatis 非常简单,只需在 pom 文件中添加如下内容:
1 2 3 4 5 6 7 8 9 10 11 | < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis</ artifactId > < version >3.3.0</ version > </ dependency > < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis-spring</ artifactId > < version >1.2.3</ version > </ dependency > |
除此之外还要包括 mysql 驱动器包、freemarker 等,完整的 pom 文件配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | < 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/maven-v4_0_0.xsd"> < modelVersion >4.0.0</ modelVersion > < groupId >com.springapp</ groupId > < artifactId >springmvc_mybatis</ artifactId > < packaging >war</ packaging > < version >1.0-SNAPSHOT</ version > < name >springmvc_mybatis</ name > < properties > < spring.version >4.1.6.RELEASE</ spring.version > </ properties > <!--Spring mvc --> < dependencies > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-core</ artifactId > < version >${spring.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-web</ artifactId > < version >${spring.version}</ version > </ dependency > < dependency > < groupId >javax.servlet</ groupId > < artifactId >servlet-api</ artifactId > < version >2.5</ version > </ dependency > < dependency > < groupId >javax.servlet.jsp</ groupId > < artifactId >jsp-api</ artifactId > < version >2.1</ version > < scope >provided</ scope > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-webmvc</ artifactId > < version >${spring.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-test</ artifactId > < version >${spring.version}</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >org.freemarker</ groupId > < artifactId >freemarker</ artifactId > < version >2.3.23</ version > </ dependency > <!--freemarker依赖此包 --> < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-context-support</ artifactId > < version >${spring.version}</ version > </ dependency > <!-- myBatis--> < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis</ artifactId > < version >3.3.0</ version > </ dependency > < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis-spring</ artifactId > < version >1.2.3</ version > </ dependency > <!-- mysql驱动包 --> < dependency > < groupId >mysql</ groupId > < artifactId >mysql-connector-java</ artifactId > < version >5.1.29</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-jdbc</ artifactId > < version >4.2.3.RELEASE</ version > </ dependency > < dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < version >4.11</ version > < scope >test</ scope > </ dependency > </ dependencies > < build > < finalName >springmvc_mybatis</ finalName > < plugins > < plugin > < artifactId >maven-compiler-plugin</ artifactId > < configuration > < source >1.6</ source > < target >1.6</ target > </ configuration > </ plugin > < plugin > < artifactId >maven-surefire-plugin</ artifactId > < configuration > < includes > < include >**/*Tests.java</ include > </ includes > </ configuration > </ plugin > </ plugins > </ build > </ project > |
如果项目采用非 maven 方式创建,可下载 MyBatis 的相关的 jar 包,引用到项目中。包括 mybatis 和 mybatis-spring 这两个 jar 包,其中 mybatis-spring 是 mybatis 对 spring 的支持。
开始使用 MyBatis
创建数据库 test,并添加表 tt_user, 创建表的 sql 如下:
1 2 3 4 5 6 7 | DROP TABLE IF EXISTS `tt_user`; CREATE TABLE `tt_user` ( `id` int (11) NOT NULL AUTO_INCREMENT, `age` int (11) DEFAULT NULL , ` name ` varchar (255) DEFAULT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; |
在 resource/conf 中添加 jdbc 配置文件,设置相关属性,属性内容如下:
1 2 3 4 | jdbc_driverClassName=com.mysql.jdbc.Driver jdbc_url=jdbc:mysql: //localhost:3306/test?useUnicode=true&characterEncoding=utf-8 jdbc_username=root jdbc_password=root |
在 dao 中添加 user 的数据访问层接口,内容如下,其中接口定义了 getUserById()和 getUserCount() 两个方法:
1 2 3 4 5 | public interface UserDao { public User getUserById( int id); public int getUserCount(); } |
在 model 中添加 user 的对象模型类,这里定义的字段名和数据库字段名相同,方便 MyBatis 查询结果和对象实体做映射,不用再定义 resultmap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class User { private int id; private int age; private String name; public int getId() { return id; } public void setId( int id) { this .id = id; } public int getAge() { return age; } public void setAge( int age) { this .age = age; } public String getName() { return name; } public void setName(String name) { this .name = name; } } |
在 service 中定义服务接口和接口实现:
接口定义如下:
1 2 3 4 5 | public interface UserService { public User getUserById( int id); public int getUserCount(); } |
接口实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class UserServiceImpl implements UserService { @Resource (name = "userDao" ) private UserDao userDao; public User getUserById( int id){ return userDao.getUserById(id); } public int getUserCount(){ return userDao.getUserCount(); } } |
以上这些定义了关于 User 对象的一系列 mvc 层次代码,接下来定义 UserMapper 文件,此文件是 MyBatis 中 SQL 定义文件,需要在此配置文件中定义 dao 数据访问接口中需要用到的 sql 语句,本例比较简单只有两个方法,分别是 getUserById 和 getUserCount,命名为 UserMapper.xml,并存放在 resource/mapper 文件夹中,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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.springapp.mvc.dao.UserDao" > <select id = "getUserById" resultType = "com.springapp.mvc.model.User" > SELECT * FROM tt _ user WHERE id = # {id} </select> <select id = "getUserCount" resultType = "int" > SELECT COUNT(*) FROM tt _ user </select> </mapper> |
其中 id 为 dao 数据访问接口中方法名称,resultType 为返回值类型,参数需要用 #{参数名} 表示。
配置 mybatis-config,指定 mapper 文件以及给实体设定别名,在 resource/conf 文件夹中创建 mybatis-config.xml,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?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> <!-- 命名空间 设置别名--> <typeAliases> <typeAlias alias = "User" type = "com.springapp.mvc.model.User" /> </typeAliases> <!-- 映射map 指定映射文件--> <mappers> <mapper resource = "mapper/UserMapper.xml" ></mapper> </mappers> </configuration> |
通过设置 mappers,设置数据访问接口对应的映射文件,通过设置 typeAlias,指定实体模型的别名,例如,这里讲 com.springapp.mvc.model.User 设置别名为 User,那么在 UserMapper.xml 中,可以将 getUserById 的 resultType 直接指定为 User, 就不需要加包前缀了。
最后,在 mvc-dispatcher-servlet.xml 中配置相关的 bean、freemarker 等配置,内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | <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" xsi : schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > <context : component-scan base- package = "com.springapp.mvc" /> <!-- 导入属性配置文件 --> <context : property-placeholder location = "classpath:conf/jdbc.properties" /> <!--配置数据源--> <bean id = "dataSource" class = "org.springframework.jdbc.datasource.DriverManagerDataSource" > <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> <bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name = "dataSource" ref = "dataSource" /> </bean> <bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" > <property name = "configLocation" value = "classpath:conf/mybatis-config.xml" /> <property name = "dataSource" ref = "dataSource" /> </bean> <!-- mapper bean --> <bean id = "userDao" class = "org.mybatis.spring.mapper.MapperFactoryBean" > <property name = "mapperInterface" value = "com.springapp.mvc.dao.UserDao" /> <property name = "sqlSessionFactory" ref = "sqlSessionFactory" /> </bean> <bean id = "userService" class = "com.springapp.mvc.service.impl.UserServiceImpl" > <!--<property name = "userDao" ref = "userDao" ></property> 若启用此配置 UserServiceImpl类中的userDao必须具有setter和getter--> </bean> <!-- freemarker的配置 --> <bean id = "freemarkerConfigurer" class = "org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" > <property name = "templateLoaderPath" value = "/WEB-INF/view/" /> <property name = "defaultEncoding" value = "utf-8" /> <property name = "freemarkerSettings" > <props> <prop key = "template_update_delay" > 10 </prop> <prop key = "locale" >zh _ CN</prop> <prop key = "datetime_format" >yyyy-MM-dd HH : mm : ss</prop> <prop key = "date_format" >yyyy-MM-dd</prop> <prop key = "number_format" > # . ## </prop> </props> </property> </bean> <!-- FreeMarker视图解析 如返回userinfo。。在这里配置后缀名ftl和视图解析器。。 --> <bean id = "viewResolver" class = "org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" > <property name = "viewClass" value = "org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> <property name = "suffix" value = ".ftl" /> <property name = "contentType" value = "text/html;charset=utf-8" /> <property name = "exposeRequestAttributes" value = "true" /> <property name = "exposeSessionAttributes" value = "true" /> <property name = "exposeSpringMacroHelpers" value = "true" /> </bean> <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name = "prefix" value = "/WEB-INF/pages/" /> <property name = "suffix" value = ".jsp" /> </bean> </beans> |
之后在 controller 中加入视图方法,输出查询内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import com.springapp.mvc.dao.UserDao; import com.springapp.mvc.model.User; import com.springapp.mvc.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import javax.annotation.Resource; @Controller @RequestMapping ( "/restful" ) public class HelloController { @Resource (name = "userService" ) private UserService userService; @RequestMapping (value = "/userinfo/{id}" ,method = RequestMethod.GET) public String showUserInfo( @PathVariable int id, ModelMap model){ User user = userService.getUserById(id); if (user!= null ) { model.addAttribute( "name" , user.getName()); } else { model.addAttribute( "name" , "查无此用户" ); } return "home" ; } @RequestMapping (value = "/home" ,method = RequestMethod.GET) public String showHome(ModelMap model){ int count = userService.getUserCount(); model.addAttribute( "count" ,count); return "count" ; } } |
通过浏览器访问页面,即可输出内容: