`

myBatis系列之六:与SpringMVC集成

阅读更多

        前面几篇文章已经讲到了mybatis与spring 的集成。但这个时候,所有的工程还不是web工程,虽然我一直是创建的web 工程。今天将直接用mybatis与Spring mvc 的方式集成起来,源码在本文结尾处下载.主要有以下几个方面的配置:

        1.web.xml 配置spring dispatch servlet ,比如为:hbatis

        2.hbatis-servlet.xml文件配置

        3.spring applicationContext.XML文件配置(与数据库相关,与mybatis sqlSessionFaction 整合,扫描所有mybatis mapper 文件等.)

        4.编写controller类

        5.编写页面代码

        先有个大概映像,整个工程图如下:


一.web.xml配置spring dispatchservlet,比如为:hbatis

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
   
	<display-name>MyBatisStudy03</display-name>
	
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
		<!-- 监听容器事件,初始化和关闭Web应用上下文并调用ContextCleanupListener清理资源 -->
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
		<!-- Web应用关闭时,清理ServletContext中spring相关的可销毁资源 -->
	</listener>

	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<servlet>
	  <servlet-name>hbatis</servlet-name>
	  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	  <!--<init-param>
	    <param-name>contextConfigLocation</param-name>
	    <param-value>/WEB-INF/hbatis-servlet.xml</param-value>
	  </init-param>-->
	  <!-- 未配置时,SpringMVC会到WEB-INF目录下找${servlet-name}-servlet.xml -->
	  <load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
	  <servlet-name>hbatis</servlet-name>
    <url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

 

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

        这个文件名前面部分必须与你在web.xml里面配置的DispatcherServlet的servlet名字对应,其内容为:

<?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:mvc="http://www.springframework.org/schema/mvc"
	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
 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!-- 注册RequestMappingHandlerMapping, RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver以提供对@RequestMapping,@ExceptionHandler等注解的支持 -->
	<mvc:annotation-driven />

	<!-- 扫描控制器包下有特定注解的类,并实例化和依赖注入 -->
	<context:component-scan base-package="com.bijian.study.controller" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

	<!-- FreeMarker视图处理器 -->
	<bean id="viewResolverFtl"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
		<property name="contentType" value="text/html;charset=utf-8" />
		<property name="prefix" value="" />
		<property name="cache" value="false" />
		<property name="viewNames">
			<array>
				<value>*.ftl</value>
			</array>
		</property>
		<!--<property name="suffix" value=".ftl"/> -->
		<!-- 优先级,数值越小优先级越高 -->
		<property name="order" value="0" />
	</bean>

	<bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPaths">
			<list>
				<!-- 模板加载路径 -->
				<value>/WEB-INF/ftl/</value>
			</list>
		</property>
	</bean>
</beans>

 

三.配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p" 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:property-placeholder location="classpath:/database.properties" />
	
	<!-- 数据源配置 -->
	<!--本示例采用DBCP连接池,应预先把DBCP的jar包复制到工程的lib目录下。 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		p:driverClassName="${driverClassName}" p:url="${url}" p:username="${user_name}"
		p:password="${password}" />
	
	<!-- sqlSessionFactory对象 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!--dataSource属性指定要用到的连接池 -->
		<property name="dataSource" ref="dataSource" />
		<!--configLocation属性指定mybatis的核心配置文件 -->
		<property name="configLocation" value="classpath:Configuration.xml" />
		<!-- 可以在Configuration.xml或此处配置映射文件,但其中不能有相同id的parameterMap, resultMap或sql等 -->
		<property name="mapperLocations" value="classpath*:com/bijian/study/model/*.xml" />
	</bean>

	<!-- 扫描指定包以获取映射器 -->
	<bean id="mapperConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.bijian.study.dao" />
	</bean>
</beans>

        类路径下的database.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.235.1:3306/hbatis?characterEncoding=utf8
user_name=bijian
password=123456

        注:因为MapperScannerConfigurer可能会导致username取的是系统用户的账号,而造成数据库连接失败,所以改成其它值:user_name。 

 

四.编写controller层

UserController.java

package com.bijian.study.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.bijian.study.dao.IUserMapper;
import com.bijian.study.model.Article;

@Controller
@RequestMapping("/article")
public class UserController {

	@Autowired
	private IUserMapper mapper;

	@RequestMapping("/list")
	public String showAll(ModelMap modelMap) {

		List<Article> articles = mapper.getArticlesByUserId(1);
		modelMap.addAttribute("articles", articles);
		return "main.ftl";
	}

	@RequestMapping("/list2")
	public ModelAndView listall(HttpServletRequest request,
			HttpServletResponse response) {
		
		List<Article> articles = mapper.getArticlesByUserId(1);
		ModelAndView mav = new ModelAndView("list");
		mav.addObject("articles", articles);
		return mav;
	}
}

 

五.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>
	<typeAliases>
		<!-- 别名 -->
        <typeAlias alias="User" type="com.bijian.study.model.User"/>
        <typeAlias alias="Article" type="com.bijian.study.model.Article"/>  
    </typeAliases> 
	
	<!-- 与spring 集成之后,这些可以完全删除,数据库连接的管理交给 spring 去管理  -->
	<!-- 
	<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://192.168.235.1:3306/hbatis" />
			<property name="username" value="bijian" />
			<property name="password" value="123456" />
		</dataSource>
	  </environment>
	</environments>
	-->
	
	<!-- 这里交给sqlSessionFactory 的 mapperLocations属性去得到所有配置信息  -->
	<!-- 
	<mappers>
		<mapper resource="com/bijian/study/model/User.xml" />
	</mappers>
	-->
</configuration>

        mybatis的Configure.xml配置文件,与上一讲的差不多,唯一不同的就是不用再配置类似如下的:   <mapper resource="com/bijian/study/model/User.xml"/> ,所有这些都交给在配置sqlSessionFactory的时候,由<property name="mapperLocations" value="classpath*:com/bijian/study/model/*.xml" />去导入了。

 

六.DAO层

package com.bijian.study.dao;

import java.util.List;

import com.bijian.study.model.Article;
import com.bijian.study.model.User;

public interface IUserMapper {

    User getUserById(int id);
    
    List<User> getUsers(String name);
    
    int addUser(User user);
    
    int updateUser(User user);
    
    int deleteUser(int id);
    
    List<Article> getArticlesByUserId(int id);
}

 

七.模型及MyBatis配置

User.java

package com.bijian.study.model;

public class User {
    
    private int id;
    private String name;
    private int age;
    private String address;
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    // 如果有带参数的构造器,编译器不会自动生成无参构造器。当查询需要返回对象时,ORM框架用反射来调用对象的无参构造函数,导致异常:java.lang.NoSuchMethodException: com.bijian.study.model.User.<init>()
    // 这时需要明确写出:
    public User() {
    }

    public User(int id, String address) {
        this.id = id;
        this.address = address;
    }

    public User(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

Article.java

package com.bijian.study.model;

public class Article {

    private int id;
    private User user;
    private String title;
    private String content;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}

User.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.bijian.study.dao.IUserMapper">
	<select id="getUserById" parameterType="int" resultType="User">
		select *
		from `user` where id = #{id}
	</select>

	<resultMap type="User" id="userList"><!-- type为返回列表元素的类全名或别名 -->
		<id column="id" property="id" />
		<result column="name" property="name" />
		<result column="age" property="age" />
		<result column="address" property="address" />
	</resultMap>

	<select id="getUsers" parameterType="string" resultMap="userList"><!-- resultMap为上面定义的User列表 -->
		select * from `user` where name like #{name}
	</select>
	
	<insert id="addUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
		<!-- useGeneratedKeys指定myBatis使用数据库自动生成的主键,并填充到keyProperty指定的属性上。如果未指定,返回对象拿不到生成的值 -->
		insert into user(name,age,address) values(#{name},#{age},#{address})
	</insert>

	<update id="updateUser" parameterType="User">
		update `user` set name=#{name}, age=#{age}, address=#{address}
		where id=#{id}
	</update>
	
	<delete id="deleteUser" parameterType="int">
		delete from `user` where id=#{id}
	</delete>
	
	<resultMap type="com.bijian.study.model.Article" id="articleList">
	    <id column="a_id" property="id" />
	    <result column="title" property="title" />
	    <result column="content" property="content" />
	    
	    <!-- user属性映射到User类 -->
	    <!-- 
	    <association property="user" javaType="User">
	        <id column="id" property="id" />
	        <result column="name" property="name" />
	        <result column="address" property="address" />
	    </association>
	    -->
	    
	    <association property="user" javaType="User" resultMap="userList"/>
	</resultMap>
	
	<select id="getArticlesByUserId" parameterType="int" resultMap="articleList">
	    select u.id, u.name, u.age, u.address, a.id a_id, a.title, a.content
	    from article a
	    inner join user u
	    on a.user_id=u.id and u.id=#{id}
	</select>
</mapper>

 

六.视图层

main.ftl

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

list.jsp

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

 

七.运行测试

        启动工程

        浏览器输入:http://localhost:8080/MyBatisStudy03/article/list,结果如下:


        浏览器输入:http://localhost:8080/MyBatisStudy03/article/list2,结果如下:

 

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

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
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.buildTemplateModel(FreeMarkerView.java:295)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:276)
    at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:233)
    at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:167)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:267)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1221)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:952)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

        原因是因为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

  • 大小: 21.8 KB
  • 大小: 9.4 KB
  • 大小: 10.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics