myBatis系列之六:与SpringMVC集成

Bertha 。 2022-04-11 06:42 350阅读 0赞
  1. 前面几篇文章已经讲到了mybatisspring 的集成。但这个时候,所有的工程还不是web工程,虽然我一直是创建的web 工程。今天将直接用mybatisSpring mvc 的方式集成起来,源码在本文结尾处下载.主要有以下几个方面的配置:
  2. 1.web.xml 配置spring dispatch servlet ,比如为:hbatis
  3. 2.hbatis-servlet.xml文件配置
  4. 3.spring applicationContext.XML文件配置(与数据库相关,与mybatis sqlSessionFaction 整合,扫描所有mybatis mapper 文件等.)
  5. 4.编写controller
  6. 5.编写页面代码
  7. 先有个大概映像,整个工程图如下:

c4ad8cd1-5c91-3c7e-8ae8-d2d5a4d10935.png
一.web.xml配置spring dispatchservlet,比如为:hbatis

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  5. http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  6. <display-name>MyBatisStudy03</display-name>
  7. <context-param>
  8. <param-name>contextConfigLocation</param-name>
  9. <param-value>/WEB-INF/applicationContext.xml</param-value>
  10. </context-param>
  11. <listener>
  12. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  13. <!-- 监听容器事件,初始化和关闭Web应用上下文并调用ContextCleanupListener清理资源 -->
  14. </listener>
  15. <listener>
  16. <listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
  17. <!-- Web应用关闭时,清理ServletContext中spring相关的可销毁资源 -->
  18. </listener>
  19. <filter>
  20. <filter-name>encodingFilter</filter-name>
  21. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  22. <init-param>
  23. <param-name>encoding</param-name>
  24. <param-value>UTF-8</param-value>
  25. </init-param>
  26. <init-param>
  27. <param-name>forceEncoding</param-name>
  28. <param-value>true</param-value>
  29. </init-param>
  30. </filter>
  31. <filter-mapping>
  32. <filter-name>encodingFilter</filter-name>
  33. <url-pattern>/*</url-pattern>
  34. </filter-mapping>
  35. <servlet>
  36. <servlet-name>hbatis</servlet-name>
  37. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  38. <!--<init-param>
  39. <param-name>contextConfigLocation</param-name>
  40. <param-value>/WEB-INF/hbatis-servlet.xml</param-value>
  41. </init-param>-->
  42. <!-- 未配置时,SpringMVC会到WEB-INF目录下找${servlet-name}-servlet.xml -->
  43. <load-on-startup>1</load-on-startup>
  44. </servlet>
  45. <servlet-mapping>
  46. <servlet-name>hbatis</servlet-name>
  47. <url-pattern>/</url-pattern>
  48. </servlet-mapping>
  49. </web-app>

二.在web.xml同目录下配置hbatis-servlet.xml 文件

  1. 这个文件名前面部分必须与你在web.xml里面配置的DispatcherServletservlet名字对应,其内容为:
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:mvc="http://www.springframework.org/schema/mvc"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
  8. http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  9. <!-- 注册RequestMappingHandlerMapping, RequestMappingHandlerAdapterExceptionHandlerExceptionResolver以提供对@RequestMapping,@ExceptionHandler等注解的支持 -->
  10. <mvc:annotation-driven />
  11. <!-- 扫描控制器包下有特定注解的类,并实例化和依赖注入 -->
  12. <context:component-scan base-package="com.bijian.study.controller" />
  13. <bean
  14. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  15. <property name="prefix">
  16. <value>/WEB-INF/pages/</value>
  17. </property>
  18. <property name="suffix">
  19. <value>.jsp</value>
  20. </property>
  21. </bean>
  22. <!-- FreeMarker视图处理器 -->
  23. <bean id="viewResolverFtl"
  24. class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  25. <property name="viewClass"
  26. value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
  27. <property name="contentType" value="text/html;charset=utf-8" />
  28. <property name="prefix" value="" />
  29. <property name="cache" value="false" />
  30. <property name="viewNames">
  31. <array>
  32. <value>*.ftl</value>
  33. </array>
  34. </property>
  35. <!--<property name="suffix" value=".ftl"/> -->
  36. <!-- 优先级,数值越小优先级越高 -->
  37. <property name="order" value="0" />
  38. </bean>
  39. <bean id="freemarkerConfig"
  40. class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  41. <property name="templateLoaderPaths">
  42. <list>
  43. <!-- 模板加载路径 -->
  44. <value>/WEB-INF/ftl/</value>
  45. </list>
  46. </property>
  47. </bean>
  48. </beans>

三.配置文件applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  7. <!-- 数据库配置文件 -->
  8. <context:property-placeholder location="classpath:/database.properties" />
  9. <!-- 数据源配置 -->
  10. <!--本示例采用DBCP连接池,应预先把DBCP的jar包复制到工程的lib目录下。 -->
  11. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  12. p:driverClassName="${driverClassName}" p:url="${url}" p:username="${user_name}"
  13. p:password="${password}" />
  14. <!-- sqlSessionFactory对象 -->
  15. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  16. <!--dataSource属性指定要用到的连接池 -->
  17. <property name="dataSource" ref="dataSource" />
  18. <!--configLocation属性指定mybatis的核心配置文件 -->
  19. <property name="configLocation" value="classpath:Configuration.xml" />
  20. <!-- 可以在Configuration.xml或此处配置映射文件,但其中不能有相同id的parameterMap, resultMap或sql等 -->
  21. <property name="mapperLocations" value="classpath*:com/bijian/study/model/*.xml" />
  22. </bean>
  23. <!-- 扫描指定包以获取映射器 -->
  24. <bean id="mapperConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  25. <property name="basePackage" value="com.bijian.study.dao" />
  26. </bean>
  27. </beans>
  28. 类路径下的database.properties
  29. driverClassName=com.mysql.jdbc.Driver
  30. url=jdbc:mysql://192.168.235.1:3306/hbatis?characterEncoding=utf8
  31. user_name=bijian
  32. password=123456
  33. 注:因为MapperScannerConfigurer可能会导致username取的是系统用户的账号,而造成数据库连接失败,所以改成其它值:user\_name。

四.编写controller层

UserController.java

  1. package com.bijian.study.controller;
  2. import java.util.List;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.ui.ModelMap;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.servlet.ModelAndView;
  10. import com.bijian.study.dao.IUserMapper;
  11. import com.bijian.study.model.Article;
  12. @Controller
  13. @RequestMapping("/article")
  14. public class UserController {
  15. @Autowired
  16. private IUserMapper mapper;
  17. @RequestMapping("/list")
  18. public String showAll(ModelMap modelMap) {
  19. List<Article> articles = mapper.getArticlesByUserId(1);
  20. modelMap.addAttribute("articles", articles);
  21. return "main.ftl";
  22. }
  23. @RequestMapping("/list2")
  24. public ModelAndView listall(HttpServletRequest request,
  25. HttpServletResponse response) {
  26. List<Article> articles = mapper.getArticlesByUserId(1);
  27. ModelAndView mav = new ModelAndView("list");
  28. mav.addObject("articles", articles);
  29. return mav;
  30. }
  31. }

五.Configuration.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
  3. <configuration>
  4. <typeAliases>
  5. <!-- 别名 -->
  6. <typeAlias alias="User" type="com.bijian.study.model.User"/>
  7. <typeAlias alias="Article" type="com.bijian.study.model.Article"/>
  8. </typeAliases>
  9. <!-- 与spring 集成之后,这些可以完全删除,数据库连接的管理交给 spring 去管理 -->
  10. <!--
  11. <environments default="development">
  12. <environment id="development">
  13. <transactionManager type="JDBC"/>
  14. <dataSource type="POOLED">
  15. <property name="driver" value="com.mysql.jdbc.Driver" />
  16. <property name="url" value="jdbc:mysql://192.168.235.1:3306/hbatis" />
  17. <property name="username" value="bijian" />
  18. <property name="password" value="123456" />
  19. </dataSource>
  20. </environment>
  21. </environments>
  22. -->
  23. <!-- 这里交给sqlSessionFactory 的 mapperLocations属性去得到所有配置信息 -->
  24. <!--
  25. <mappers>
  26. <mapper resource="com/bijian/study/model/User.xml" />
  27. </mappers>
  28. -->
  29. </configuration>
  30. mybatis的Configure.xml配置文件,与上一讲的差不多,唯一不同的就是不用再配置类似如下的: <mapper resource="com/bijian/study/model/User.xml"/> ,所有这些都交给在配置sqlSessionFactory的时候,由<property name="mapperLocations" value="classpath\*:com/bijian/study/model/\*.xml" />去导入了。

六.DAO层

  1. package com.bijian.study.dao;
  2. import java.util.List;
  3. import com.bijian.study.model.Article;
  4. import com.bijian.study.model.User;
  5. public interface IUserMapper {
  6. User getUserById(int id);
  7. List<User> getUsers(String name);
  8. int addUser(User user);
  9. int updateUser(User user);
  10. int deleteUser(int id);
  11. List<Article> getArticlesByUserId(int id);
  12. }

七.模型及MyBatis配置

User.java

  1. package com.bijian.study.model;
  2. public class User {
  3. private int id;
  4. private String name;
  5. private int age;
  6. private String address;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public int getAge() {
  20. return age;
  21. }
  22. public void setAge(int age) {
  23. this.age = age;
  24. }
  25. public String getAddress() {
  26. return address;
  27. }
  28. public void setAddress(String address) {
  29. this.address = address;
  30. }
  31. // 如果有带参数的构造器,编译器不会自动生成无参构造器。当查询需要返回对象时,ORM框架用反射来调用对象的无参构造函数,导致异常:java.lang.NoSuchMethodException: com.bijian.study.model.User.<init>()
  32. // 这时需要明确写出:
  33. public User() {
  34. }
  35. public User(int id, String address) {
  36. this.id = id;
  37. this.address = address;
  38. }
  39. public User(String name, int age, String address) {
  40. this.name = name;
  41. this.age = age;
  42. this.address = address;
  43. }
  44. }

Article.java

  1. package com.bijian.study.model;
  2. public class Article {
  3. private int id;
  4. private User user;
  5. private String title;
  6. private String content;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public User getUser() {
  14. return user;
  15. }
  16. public void setUser(User user) {
  17. this.user = user;
  18. }
  19. public String getTitle() {
  20. return title;
  21. }
  22. public void setTitle(String title) {
  23. this.title = title;
  24. }
  25. public String getContent() {
  26. return content;
  27. }
  28. public void setContent(String content) {
  29. this.content = content;
  30. }
  31. }

User.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.bijian.study.dao.IUserMapper">
  4. <select id="getUserById" parameterType="int" resultType="User">
  5. select *
  6. from `user` where id = #{id}
  7. </select>
  8. <resultMap type="User" id="userList"><!-- type为返回列表元素的类全名或别名 -->
  9. <id column="id" property="id" />
  10. <result column="name" property="name" />
  11. <result column="age" property="age" />
  12. <result column="address" property="address" />
  13. </resultMap>
  14. <select id="getUsers" parameterType="string" resultMap="userList"><!-- resultMap为上面定义的User列表 -->
  15. select * from `user` where name like #{name}
  16. </select>
  17. <insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
  18. <!-- useGeneratedKeys指定myBatis使用数据库自动生成的主键,并填充到keyProperty指定的属性上。如果未指定,返回对象拿不到生成的值 -->
  19. insert into user(name,age,address) values(#{name},#{age},#{address})
  20. </insert>
  21. <update id="updateUser" parameterType="User">
  22. update `user` set name=#{name}, age=#{age}, address=#{address}
  23. where id=#{id}
  24. </update>
  25. <delete id="deleteUser" parameterType="int">
  26. delete from `user` where id=#{id}
  27. </delete>
  28. <resultMap type="com.bijian.study.model.Article" id="articleList">
  29. <id column="a_id" property="id" />
  30. <result column="title" property="title" />
  31. <result column="content" property="content" />
  32. <!-- user属性映射到User类 -->
  33. <!--
  34. <association property="user" javaType="User">
  35. <id column="id" property="id" />
  36. <result column="name" property="name" />
  37. <result column="address" property="address" />
  38. </association>
  39. -->
  40. <association property="user" javaType="User" resultMap="userList"/>
  41. </resultMap>
  42. <select id="getArticlesByUserId" parameterType="int" resultMap="articleList">
  43. select u.id, u.name, u.age, u.address, a.id a_id, a.title, a.content
  44. from article a
  45. inner join user u
  46. on a.user_id=u.id and u.id=#{id}
  47. </select>
  48. </mapper>

六.**视图层**

main.ftl

  1. <#list articles as article>
  2. <div>${article.id}. ${article.title}: ${article.content}</div>
  3. </#list>

list.jsp

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  8. <title>article list</title>
  9. </head>
  10. <body>
  11. <c:forEach items="${articles}" var="item">
  12. ${item.id }--${item.title }--${item.content }<br />
  13. </c:forEach>
  14. </body>
  15. </html>

七.运行测试

  1. 启动工程
  2. 浏览器输入:http://localhost:8080/MyBatisStudy03/article/list,结果如下:

5f9d2ba1-9b1e-320d-a776-61710c1e2f39.png
浏览器输入:http://localhost:8080/MyBatisStudy03/article/list2,结果如下:

34aa2261-cf4c-357f-afdd-eab5db4560df.png

PS:在开发过程中,遇到spring MVC整合freemarker抛出java.lang.IllegalAccessError: tried to access method freemarker.ext.servlet.AllHttpScopesHashModel异常,详细异常信息如下:

  1. java.lang.IllegalAccessError: tried to access method freemarker.ext.servlet.AllHttpScopesHashModel.<init>(Lfreemarker/template/ObjectWrapper;Ljavax/servlet/ServletContext;Ljavax/servlet/http/HttpServletRequest;)V from class org.springframework.web.servlet.view.freemarker.FreeMarkerView
  2. at org.springframework.web.servlet.view.freemarker.FreeMarkerView.buildTemplateModel(FreeMarkerView.java:295)
  3. at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:276)
  4. at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:233)
  5. at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
  6. at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
  7. at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221)
  8. at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
  9. at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)
  10. at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
  11. at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
  12. at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
  13. at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
  14. at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
  15. at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
  16. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
  17. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  18. at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
  19. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
  20. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  21. at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
  22. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  23. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
  24. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
  25. at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
  26. at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
  27. at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
  28. at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
  29. at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
  30. at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
  31. at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
  32. at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
  33. at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
  34. at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
  35. at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
  36. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  37. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  38. at java.lang.Thread.run(Thread.java:745)
  39. 原因是因为fremarker的版本问题,将freemarker-2.3.8.jar改为com.springsource.freemarker-2.3.15.jar后,OK

参考文章:http://czj4451.iteye.com/blog/1995489

http://www.yihaomen.com/article/java/318.htm

发表评论

表情:
评论列表 (有 0 条评论,350人围观)

还没有评论,来说两句吧...

相关阅读