springMVC + mybatis 搜索 分页等
mybatis-3.0.5
spring-core-3.2.0.RELEASE
等
MyBatis3+Spring3
当前Spring版本(3.0.5)中未提供对MyBatis3的支持
使用第三方jar包进行整合(mybatis-spring-1.0.1.jar)
============================================================
============================================================
1.配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>springmvc</display-name> <!-- 字符集过滤器 --> <filter> <filter-name>characterEncodingFilter</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> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- SpringMVC中央控制器 --> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- Spring容器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> </web-app>
新建etc文件夹中配置applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" > <context:component-scan base-package="com.kaishengit"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 配置数据源 --> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="url" value="${jdbc.url}"/> <property name="driverClassName" value="${jdbc.driver}"/> <property name="username" value="${jdbc.name}"/> <property name="password" value="${jdbc.password}"/> <property name="minIdle" value="5"/> <property name="maxActive" value="10"/> <property name="maxWait" value="5000"/> </bean> <!-- 重新由以前的hibernate管理器变回最原始的JDBC事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- MyBatis SessionFactory --> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 别名都放在哪个包里面 --> <property name="typeAliasesPackage" value="com.kaishengit.pojo"/> </bean> <!-- MyBatis 自动扫描Mapper --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.kaishengit.dao"/> </bean> </beans>
etc中配置ehcache.xml和jdbc.properties
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <!-- <cache name="com.kaishengit.pojo.User" maxElementsInMemory="100" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> --> </ehcache>
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///book?useUnicode=yes&characterEncoding=UTF-8 jdbc.name=root jdbc.password=root
WEB-INF中配置mvc-servlet.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: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-3.0.xsd"> <context:component-scan base-package="com.kaishengit.controller"/> <mvc:annotation-driven/> <!-- 静态资源 --> <mvc:resources location="/static/" mapping="/static/**"/> <mvc:view-controller path="/" view-name="index"/> <!-- 视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 文件上传解析器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="1000000000"/> </bean> <!-- 异常处理 --> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="com.kaishengit.exception.LoginException">redirect:/</prop> </props> </property> </bean> <!-- 拦截器配置 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.kaishengit.controller.interceptor.LoginInterceptor"> <property name="execludeUrls"> <list> <value></value> <value>/</value> <value>/login</value> </list> </property> </bean> </mvc:interceptor> </mvc:interceptors> </beans>
---------------------------------------------------------------------------
---------------------------------------------------------------------------
---------------------------------------------------------------------------
对于springmvc+mybatis的表单搜索
加q_是因为有的搜索不用提交
<div class="well"> <form action="/book" method="get" class="form-search"> <input type="text" name="q_name" placeholder="书籍名称" value="${q_name }"/> <input type="text" name="q_publish" placeholder="出版社" value="${q_publish }"/> <input type="text" name="q_author" placeholder="作者" value="${q_author }"/> <button class="btn btn-success">搜索</button> </form> </div>
表单提交到bookcontroller中
@Controller @RequestMapping("/book") public class BookController { @Inject private BookService bookService; // 没有指定请求路径的时候默认就是namespace的路径 @RequestMapping(method=RequestMethod.GET) public String list(@PathVariable Integer page,Model model,HttpServletRequest request) { model.addAttribute("bookList", bookService.findAll(ServletUtil.builderParamMapByRequest(request))); return "book/list"; } }
写一个工具类
public class ServletUtil { public static Map<String, Object> builderParamMapByRequest(HttpServletRequest request) { Map<String, Object> map = new HashMap<String, Object>(); //获取表单中的搜索数据 Enumeration<String> reqNames = request.getParameterNames(); while(reqNames.hasMoreElements()) { String name = reqNames.nextElement(); String value = request.getParameter(name); if(name.startsWith("q_")) { try { // 表单的数据传到url中会有乱码,转码 value = new String(value.getBytes("ISO8859-1"),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } map.put(name, value); /* 将这些值放入request中,方便在查询完成之后表单中能获取这些值 如果不这样做,而是直接从url中获取会有乱码问题 这样就需要在页面上进行转码,所有的都要转码,这样比较麻烦-- <% String name = request.getParameter("q_name"); if(name != null){ name = new String(name.getBytes("ISO8859-1"),"UTF-8"); pageContext.setAttribute("name",name); } 然后再页面上用value="${pageScope.name }"取值 %>*/ request.setAttribute(name, value); } } return map; } }
将这个map给bookService.findAll()中
public List<Book> findAll(Map<String, Object> map) { return bookDao.findByParam(map); }
然后在bookdao.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.kaishengit.dao.BookDao"> <insert id="save" parameterType="Book"> INSERT INTO book(CODE,NAME,author,publish,total,nowcount) VALUES(#{code},#{name},#{author},#{publish},#{total},#{nowcount}) </insert> <select id="findByParam" parameterType="map" resultType="list" resultMap="bookMap"> select * from book <where> <!-- 当url中有值的时候在加上这些sql --> <if test="q_name != null and q_name != ''"> name like = #{q_name} </if> <if test="q_author != null and q_author != ''"> and author = #{q_author} </if> <if test="q_publish != null and q_publish != ''"> and publish = #{q_publish} </if> </where> </select> <resultMap type="Book" id="bookMap"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="author" column="author"/> <result property="publish" column="publish"/> <result property="total" column="total"/> <result property="nowcount" column="nowcount"/> <result property="code" column="code"/> </resultMap> </mapper>
<!-- 但是如果是like查询,就要这样加name like = '%${q_name}%' 因为用#是默认加上了单引号,没法加单引号,所以要用$--> <select id="findByParam" parameterType="map" resultType="list" resultMap="bookMap"> select * from book <where> <!-- 当url中有值的时候在加上这些sql --> <if test="q_name != null and q_name != ''"> name like = '%${q_name}%' </if> <if test="q_author != null and q_author != ''"> and author = #{q_author} </if> <if test="q_publish != null and q_publish != ''"> and publish = #{q_publish} </if> </where> </select>
----------------------------------------------------------------------------
-----------------------------------------------------------------------------
------------------------------------------------------------------------------
分页
bookcontroller中
@RequestMapping(method=RequestMethod.GET)
public String list(@RequestParam(required=false,defaultValue="1")int page,Model model,HttpServletRequest request) {
model.addAttribute("bookList", bookService.findAll(ServletUtil.builderParamMapByRequest(request),page));
return "book/list";
}
在bookservice中
public List<Book> findAll(Map<String, Object> map, int page) { // 指定一页多少个 int pageCount = 2; // 指定起始数据 int start = (page-1) * pageCount; map.put("start", start); return bookDao.findByParam(map); }
bookdao.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.kaishengit.dao.BookDao"> <insert id="save" parameterType="Book"> INSERT INTO book(CODE,NAME,author,publish,total,nowcount) VALUES(#{code},#{name},#{author},#{publish},#{total},#{nowcount}) </insert> <select id="findByParam" parameterType="map" resultType="list" resultMap="bookMap"> select * from book <where> <if test="q_name != null and q_name != ''"> name like '%${q_name}%' </if> <if test="q_author != null and q_author != ''"> and author = #{q_author} </if> <if test="q_publish != null and q_publish != ''"> and publish = #{q_publish} </if> </where> <choose> <when test="start == null or start == ''"> limit 0,2 </when> <otherwise> limit #{start},2 </otherwise> </choose> </select> <resultMap type="Book" id="bookMap"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="author" column="author"/> <result property="publish" column="publish"/> <result property="total" column="total"/> <result property="nowcount" column="nowcount"/> <result property="code" column="code"/> </resultMap> </mapper>
========================================================================
========================================================================
以下仅供了解
如果觉得url丑陋,分页还要用? 想用/book/1 这中形式
bookcontroller中
这个时候就必须传过来一个页数,所以要加上value="/{page:\\d+}",不能用之前的没有指定路径直接用namespace的路径-->
@RequestMapping(value="/{page:\\d+}",method=RequestMethod.GET)
获取url的动态值用@PathVariable Integer page
public String list(@PathVariable int page,Model model,HttpServletRequest request) {
model.addAttribute("bookList", bookService.findAll(ServletUtil.builderParamMapByRequest(request),page));
return "book/list";
}
用这种方式虽然能得到分页的效果,但是如果在这个基础上在进行搜索还是会在后面加上?
而且
<div class="well">
<form action="/book" method="get" class="form-search">
<input type="text" name="q_name" placeholder="书籍名称" value="${q_name }"/>
<input type="text" name="q_publish" placeholder="出版社" value="${q_publish }"/>
<input type="text" name="q_author" placeholder="作者" value="${q_author }"/>
<button class="btn btn-success">搜索</button>
</form>
</div>
搜索提交到的是/book 也就是永远都是/book/1 都是第一页,当你点击第二页的时候
需要做到不只传过来一个页号${pageNo+1},还要讲第一页?后面的搜索条件也加进来
这样就比较麻烦/book/${pageNo+1}?xxxxx 所以还不如一开始就都用?传值