使用SpringBoot+RabbitMQ框架集成例程

RabbitMQ是消息服务器,主要解决应用间解耦问题,消息异步处理和高并发场景下对关系数据库缓冲作用,比如电商系统中的秒杀设计。本例程中使用SpringBoot集成RabbitMQ解决高并发数据存储对关系数据库的缓冲问题。前端页面提交数据直接进入RabbitMQ队列,设计消息定时处理器或者消息监听器获取消息并保持到数据库。
这里写图片描述

本例要求:

1.安装RabbitMQ
2.使用SpringBoot框架

新建Maven webapp项目

这里写图片描述

POM.xml文件配置

<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.test</groupId>
  <artifactId>Proj_SpringRabbitmq</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Proj_SpringRabbitmq Maven Webapp</name>
  <url>http://maven.apache.org</url>

    <!-- 定义公共资源版本 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
        <relativePath/> 
    </parent>

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 添加springboot对AOP的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- 添加springboot对redis的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- 添加springboot对mybatis的支持 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!-- 添加springboot对freemarker的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-- 添加springboot对测试的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- 添加springboot对在线开发的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
            <scope>true</scope>
        </dependency>
        <!-- 添加springboot对amqp的支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <!-- 添加springboot对solr的支持 -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-solr</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.11</version>
            <exclusions>
                <exclusion>  
                    <groupId>com.alibaba</groupId>
                    <artifactId>jconsole</artifactId>
                </exclusion>  
                <exclusion>
                    <groupId>com.alibaba</groupId>
                    <artifactId>tools</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency> 
            <groupId>org.apache.tomcat.embed</groupId> 
            <artifactId>tomcat-embed-jasper</artifactId> 
            <scope>provided</scope> 
        </dependency> 
        <dependency>
            <groupId>javax.servlet</groupId> 
            <artifactId>jstl</artifactId> 
        </dependency>


        <!-- 分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils-core</artifactId>
            <version>1.8.3</version>
        </dependency>
  </dependencies>
  <build>
    <finalName>Proj_SpringRabbitmq</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
            </configuration>
        </plugin>
    </plugins>
  </build>
</project>

Applicaton.properties文件

#SpringBoot启动端口和项目路径
server.port=8080
server.context-path=/

#spring.resources.static-locations=/css,/images,/img,/js

#SpringMVC中JSP视图配置
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

#数据源配置      
spring.datasource.name=w1
spring.datasource.url=jdbc:mysql://localhost:3306/w1?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.maxActive=20
spring.datasource.initialSize=1
spring.datasource.maxWait=60000
spring.datasource.minIdle=1

#Http编码配置    
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true

#Rabbitmq消息服务器配置      
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/


#Mybatis实体类配置    
mybatis.mapper-locations=classpath:mapper/*.xml

#pagehelper分页插件
pagehelper.helperDialect=mysql
pagehelper.reasonable=true


#日志配置
logging.file=d:/springboot.log
logging.level.com.test.mapper=INFO
logging.level.com.hk.servlet=DEBUG
logging.level.com.test.service.impl=DEBUG

菜单实体类
MeunInfo.java

package com.test.bean;

import java.io.Serializable;

//菜单表实体类
public class MenuInfo implements Serializable{
    private Integer id = null;
    private String name = null;
    private Integer price = null;
    //冗余字段,存放材料名称,以逗号分隔
    private String sname = null;
    //冗余字段,存放材料ID,以逗号分隔
    private String sid = null;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPrice() {
        return price;
    }
    public void setPrice(Integer price) {
        this.price = price;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }

}

菜单材料实体类
StaffInfo.java

package com.test.bean;

import java.io.Serializable;

//材料表实体类
public class StaffInfo  implements Serializable{
    private Integer id = null;
    private String name = null;
    //冗余字段,代表前台页面Checkbox控件是否选中,true为选中
    private String checked = "";
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getChecked() {
        return checked;
    }
    public void setChecked(String checked) {
        this.checked = checked;
    }

}

中间表实体类
M2SInfo.java

package com.test.bean;

import java.io.Serializable;

//菜单关联材料的实体类
public class M2SInfo  implements Serializable{
    //菜单表ID
    private Integer mid = null;
    //材料表ID
    private Integer sid = null;
    public Integer getMid() {
        return mid;
    }
    public void setMid(Integer mid) {
        this.mid = mid;
    }
    public Integer getSid() {
        return sid;
    }
    public void setSid(Integer sid) {
        this.sid = sid;
    }

}

Mybatis Mapper接口

扫描二维码关注公众号,回复: 3136500 查看本文章
package com.test.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import com.test.bean.M2SInfo;
import com.test.bean.MenuInfo;
import com.test.bean.StaffInfo;

//Mybatis接口主键,Springboot自动扫描
@Mapper
public interface MenuMapper {
    //根据菜单名称查询菜单结果,@Param("name")标注参数名可以使用在SQL语句中
    public List<MenuInfo> findMenu(@Param("name") String name);
    //返回全部材料列表
    public List<StaffInfo> findStaff();
    //保存菜单对象
    public void saveMenu(MenuInfo mi);
    //更新菜单对象
    public void updateMenu(MenuInfo mi);
    //根据菜单ID删除记录,@Param("id")标注参数名可以使用在SQL中
    public void deleteMenu(@Param("id") Integer mid);
    //保存中间表
    public void saveM2S(M2SInfo m2s);
    //根据菜单ID删除中间表
    public void deleteM2S(@Param("id") Integer mid);
    //返回多表关联查询数据
    public List<MenuInfo> findMenu2(@Param("name") String name);
    //根据菜单ID返回菜单对象,需要多表关联查询
    public MenuInfo getMenuById(@Param("id") Integer mid);
}

Mybatis Mapper.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.test.mapper.MenuMapper">
    <select id="findMenu" resultType="com.test.bean.MenuInfo">
        select * from t_menu where name like '%${name}%'
    </select>
    <select id="findStaff" resultType="com.test.bean.StaffInfo">
        select * from t_staff
    </select>
    <insert id="saveMenu" parameterType="com.test.bean.MenuInfo"
        useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into t_menu(name,price) values(#{name},#{price})
    </insert>
    <update id="updateMenu" parameterType="com.test.bean.MenuInfo">
        update t_menu set name=#{name},price=#{price} where id=#{id}
    </update>
    <delete id="deleteMenu" parameterType="Integer">
        delete from t_menu where id=#{id}
    </delete>
    <insert id="saveM2S" parameterType="com.test.bean.M2SInfo">
        insert into t_m2s(mid,sid) values(#{mid},#{sid})
    </insert>
    <delete id="deleteM2S" parameterType="Integer">
        delete from t_m2s where mid=#{id}
    </delete>


    <select id="findMenu2" resultType="com.test.bean.MenuInfo">
        select a.*,b.sname,b.sid from t_menu a left join
        (select group_concat(s.name) sname,group_concat(s.id) sid,m2s.mid from t_staff s,t_m2s m2s where s.id=m2s.sid group by m2s.mid) b
        on a.id=b.mid where a.name like '%${name}%' or b.sname like '%${name}%'
    </select>
    <select id="getMenuById" resultType="com.test.bean.MenuInfo">
        select a.*,b.sname,b.sid from t_menu a left join
        (select group_concat(s.name) sname,group_concat(s.id) sid,m2s.mid from t_staff s,t_m2s m2s where s.id=m2s.sid group by m2s.mid) b
        on a.id=b.mid where a.id=#{id}
    </select>
</mapper>

SQL

create table t_menu(id int auto_increment primary key,
    name varchar(40),
    price int);

create table t_staff(id int auto_increment primary key,
    name varchar(40));

create table t_m2s(mid int,sid int);

insert into t_staff(name) values('鸡肉');
insert into t_staff(name) values('花生米');
insert into t_staff(name) values('猪肉');
insert into t_staff(name) values('木耳');

insert into t_menu(name,price) value('宫保鸡丁',18);
insert into t_menu(name,price) value('土豆丝',20);

insert into t_m2s (mid,sid) values (1,1);
insert into t_m2s (mid,sid) values (1,4);

insert into t_m2s (mid,sid) values (2,2);
insert into t_m2s (mid,sid) values (2,3);

关联中间表与材料表,获取材料名称,材料ID和菜单ID

select s.name,s.id,m2s.mid from t_staff s,t_m2s m2s where s.id=m2s.sid

select group_concat(s.name) sname,group_concat(s.id) sid,m2s.mid from t_staff s,t_m2s m2s where s.id=m2s.sid group by m2s.mid

select a.*,b.sname,b.sid from t_menu a left join
(select group_concat(s.name) sname,group_concat(s.id) sid,m2s.mid from t_staff s,t_m2s m2s where s.id=m2s.sid group by m2s.mid) b
on a.id=b.mid;

服务接口

package com.test.service;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.test.bean.M2SInfo;
import com.test.bean.MenuInfo;
import com.test.bean.StaffInfo;

public interface IMenuService {
    //根据菜单名称查询菜单结果
    public List<MenuInfo> findMenu(String name);
    //返回全部材料列表
    public List<StaffInfo> findStaff();
    //保存菜单对象
    public void saveMenu(MenuInfo mi);
    //更新菜单对象
    public void updateMenu(MenuInfo mi);
    //根据菜单ID删除记录
    public void deleteMenu(Integer mid);
    //保存中间表
    public void saveM2S(M2SInfo m2s);
    //根据菜单ID删除中间表
    public void deleteM2S(Integer mid);
    //返回多表关联查询数据
    public List<MenuInfo> findMenu2(String name);
    //根据菜单ID返回菜单对象,需要多表关联查询
    public MenuInfo getMenuById(Integer mid);
}

服务实现类

package com.test.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.test.bean.M2SInfo;
import com.test.bean.MenuInfo;
import com.test.bean.StaffInfo;
import com.test.mapper.MenuMapper;
import com.test.service.IMenuService;

@Service
public class MenuServiceImpl implements IMenuService{
    private Logger log = LoggerFactory.getLogger(MenuServiceImpl.class);


    @Autowired
    private MenuMapper mapper;
    @Override
    @Transactional(readOnly=true,propagation=Propagation.REQUIRES_NEW)
    public List<MenuInfo> findMenu(String name) {
        return mapper.findMenu(name);
    }

    @Override
    public List<StaffInfo> findStaff() {
        return mapper.findStaff();
    }

    @Transactional
    @Override
    public void saveMenu(MenuInfo mi) {
        mapper.saveMenu(mi);
    }

    @Override
    public void updateMenu(MenuInfo mi) {
        mapper.updateMenu(mi);
    }

    @Override
    public void deleteMenu(Integer mid) {
        mapper.deleteMenu(mid);
    }

    @Override
    public void saveM2S(M2SInfo m2s) {
        mapper.saveM2S(m2s);
    }

    @Override
    public void deleteM2S(Integer mid) {
        mapper.deleteM2S(mid);
    }

    @Override
    public List<MenuInfo> findMenu2(String name) {
        return mapper.findMenu2(name);
    }

    @Override
    public MenuInfo getMenuById(Integer mid) {
        return mapper.getMenuById(mid);
    }

}

RabbitMQ配置类

package com.test.util;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//RabbitMQ配置类,替代XML配置
@Configuration
public class RabbitmqConf {
    public static String QUEUE1 = "test_queue1";
    public static String EXCHANGE1 = "test_exg1";

    //生成队列test_queue1
    @Bean
    public Queue queue1()
    {
        return new Queue(QUEUE1);
    }

    //生成交换机test_exg1
    @Bean
    public DirectExchange exg1()
    {
        return new DirectExchange(EXCHANGE1);
    }

    //绑定队列与交换机
    @Bean
    public Binding directBinding1() {
        return BindingBuilder.bind(queue1()).to(exg1()).with("java");
    }


}

RabbitMQ消息接收器,有两种解决方案
1、使用定时器定时接收消息
2、使用消息监听器接收消息,两者互斥,只能选择其一

定时器接收消息

package com.test.util;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.ConnectionFactory;
import com.test.bean.M2SInfo;
import com.test.bean.MenuInfo;
import com.test.service.IMenuService;

@Component
public class CrontabGetMsg {
    @Autowired
    private AmqpTemplate amqp;
    @Autowired
    private IMenuService serv;

    //秒 分 时 日 月 周 年
    //每五秒接收一次消息
    @Scheduled(cron="0/5 * * ? * *")
    public void getMsg()
    {
        //System.out.println("getMsg() "+new java.sql.Timestamp(System.currentTimeMillis()));
        try
        {
            //每次接收一个消息
            Message msg = amqp.receive(RabbitmqConf.QUEUE1);
            //如果消息为空,返回
            if(msg == null)
                return;
            byte[] data = msg.getBody();
            //反序列化消息为对象
            Object obj = toObject(data);
            if(obj instanceof MenuInfo)
            {
                MenuInfo mi = (MenuInfo)obj;
                String sid = mi.getSid();
                Integer id = mi.getId();
                System.out.println("getMsg id="+id+",name="+mi.getName());
                if(id == null)//新增
                {
                    serv.saveMenu(mi);
                }
                else//更新
                {
                    serv.updateMenu(mi);
                    //删除原来关联中间表数据
                    serv.deleteM2S(mi.getId());
                }
                String[] dim = sid.split(",");
                for(String sid2:dim)
                {
                    M2SInfo m2s = new M2SInfo();
                    m2s.setSid(new Integer(sid2));
                    m2s.setMid(mi.getId());
                    serv.saveM2S(m2s);
                }
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public Object toObject(byte[] data)
    {
        try
        {
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            ObjectInputStream ois = new ObjectInputStream(bais);
            Object obj = ois.readObject();
            bais.close();
            return obj;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

}

消息监听器

package com.test.util;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.test.bean.M2SInfo;
import com.test.bean.MenuInfo;
import com.test.service.IMenuService;

@Component
public class RabbitmqListener {
    @Autowired
    private IMenuService serv;

    @RabbitListener(queues="test_queue1")
    public void receive(Message msg)
    {
        try
        {
            byte[] data = msg.getBody();
            Object obj = toObject(data);
            if(obj instanceof MenuInfo)
            {
                MenuInfo mi = (MenuInfo)obj;
                String sid = mi.getSid();
                Integer id = mi.getId();
                System.out.println("getMsg id="+id+",name="+mi.getName());
                if(id == null)//新增
                {
                    serv.saveMenu(mi);
                }
                else//更新
                {
                    serv.updateMenu(mi);
                    //删除原来关联中间表数据
                    serv.deleteM2S(mi.getId());
                }
                String[] dim = sid.split(",");
                for(String sid2:dim)
                {
                    M2SInfo m2s = new M2SInfo();
                    m2s.setSid(new Integer(sid2));
                    m2s.setMid(mi.getId());
                    serv.saveM2S(m2s);
                }
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public Object toObject(byte[] data)
    {
        try
        {
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            ObjectInputStream ois = new ObjectInputStream(bais);
            Object obj = ois.readObject();
            bais.close();
            return obj;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }
}

定义发送消息工具类

package com.test.ctrl;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.test.bean.MenuInfo;
import com.test.util.RabbitmqConf;

@Component
public class SendMsg {
    //注入消息模板
    @Autowired
    private AmqpTemplate amqp;

    public void send(MenuInfo mi)
    {
        amqp.convertAndSend(RabbitmqConf.QUEUE1,mi);
    }
}

定义Controller

package com.test.ctrl;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.test.bean.MenuInfo;
import com.test.bean.StaffInfo;
import com.test.service.IMenuService;
import com.test.util.PageUtil;

@Controller
public class MenuCtrl {
    @Autowired
    private IMenuService serv;
    @Autowired
    private SendMsg sendmsg;

    //跳转菜单列表的方法
    //接收前台参数page,rows
    @RequestMapping("/list")
    public String list(HttpServletRequest req,Integer page,Integer rows)
    {
        if(page == null)
            page = 1;
        if(rows == null)
            rows = 4;
        String name = req.getParameter("name");
        return toListPage(req,page,rows,name);
    }

    //删除方法,通过id删除菜单和中间表
    @RequestMapping("/delete")
    public String delete(HttpServletRequest req,Integer page,Integer rows)
    {
        if(page == null)
            page = 1;
        if(rows == null)
            rows = 4;
        String[] ids = req.getParameterValues("id");
        if(ids != null)
        {
            for(String id:ids)
            {
                Integer mid = new Integer(id);
                serv.deleteMenu(mid);
                serv.deleteM2S(mid);
            }
        }

        return toListPage(req,1,4,null);
    }

    //跳转到新增页面
    @RequestMapping("/add")
    public String add(HttpServletRequest req)
    {
        List<StaffInfo> staffList = serv.findStaff();
        req.setAttribute("staffList", staffList);
        return "add";
    }

    //跳转到修改页面
    @RequestMapping("/modify")
    public String modify(HttpServletRequest req)
    {
        String id = req.getParameter("id");
        Integer mid = new Integer(id);
        MenuInfo menu = serv.getMenuById(mid);
        req.setAttribute("menu", menu);
        String sid = menu.getSid();//1,2,3
        System.out.println("sid="+sid);
        List<StaffInfo> staffList = serv.findStaff();
        for(StaffInfo si:staffList)
        {
            String sid2 = si.getId().toString();
            if(sid.indexOf(sid2)>=0)
                si.setChecked("checked");
        }
        req.setAttribute("staffList", staffList);
        return "add";
    }

    //跳转到查看页面
    @RequestMapping("/view")
    public String view(HttpServletRequest req)
    {
        String id = req.getParameter("id");
        Integer mid = new Integer(id);
        MenuInfo menu = serv.getMenuById(mid);
        req.setAttribute("menu", menu);
        String sid = menu.getSid();//1,2,3
        System.out.println("sid="+sid);
        List<StaffInfo> staffList = serv.findStaff();
        for(StaffInfo si:staffList)
        {
            String sid2 = si.getId().toString();
            if(sid.indexOf(sid2)>=0)
                si.setChecked("checked");
        }
        req.setAttribute("staffList", staffList);
        return "view";
    }

    //保存菜单数据到Rabbitmq队列,返回到列表页面
    @RequestMapping("/save")
    public String save(HttpServletRequest req,MenuInfo mi)
    {
        sendmsg.send(mi);

        return toListPage(req,1,4,null);
    }

    //公共方法,统一返回到列表页面
    private String toListPage(HttpServletRequest req,Integer page,Integer rows,String name)
    {
        if(page == null)
            page = 1;
        if(rows == null)
            rows = 4;
        if(name == null)
            name = "";

        System.out.println("page===="+page+",rows==="+rows+",name="+name);
        PageHelper.startPage(page, rows);
        List<MenuInfo> menuList = serv.findMenu2(name);
        System.out.println("menuList===="+menuList.size());
        PageInfo pi = new PageInfo(menuList);
        List<MenuInfo> menuList2 = pi.getList();//当前页显示记录集合
        Long total = pi.getTotal();//数据库表全部记录数
        req.setAttribute("menuList", menuList2);
        System.out.println("menuList2===="+menuList2.size());
        String url = "/list";
        PageUtil pu = new PageUtil(url,page,rows,total);
        req.setAttribute("pageDiv", pu.toHtml());
        req.setAttribute("name", name);


        return "menu";
    }
}

分页工具类

package com.test.util;

public class PageUtil {
    private Integer page = 1;//默认显示第一页
    private Integer rows = 4;//每页显示记录数
    private Long total = null;//总行数
    private String url = null;//点击页码跳转url

    public PageUtil(String url,Integer page,Integer rows,Long total)
    {
        this.url = url;
        this.page = page;
        this.rows = rows;
        this.total = total;
    }

    public String toHtml()
    {
        StringBuffer sb = new StringBuffer();
        //计算总页数
        int pages = 0;
        if(total % rows == 0)
            pages = total.intValue() / rows;
        else
            pages = (total.intValue() / rows) + 1;
        sb.append("<div id='pagediv'>\r\n");
        String firstUrl = null;
        if(url.indexOf("?")>0)
            firstUrl = url + "&page=1&rows="+rows;
        else
            firstUrl = url + "?page=1&rows="+rows;
        sb.append("<a href='"+firstUrl+"'>首页</a>\r\n");
        String backUrl = null;
        if(url.indexOf("?")>0)
            backUrl = url + "&page="+(page==1?1:(page-1))+"&rows="+rows;
        else
            backUrl = url + "?page="+(page==1?1:(page-1))+"&rows="+rows;
        sb.append("<a href='"+backUrl+"'>上一页</a>\r\n");
        for(int i=1;i<=pages;i++)
        {
            String pageUrl = null;
            if(url.indexOf("?")>0)
                pageUrl = url + "&page="+i+"&rows="+rows;
            else
                pageUrl = url + "?page="+i+"&rows="+rows;
            if(i == page)
                sb.append("<a href='"+pageUrl+"'><b><font color='red'>"+i+"</font></b></a>\r\n");
            else
                sb.append("<a href='"+pageUrl+"'>"+i+"</a>\r\n");
        }
        String nextUrl = null;
        if(url.indexOf("?")>0)
            nextUrl = url + "&page="+(page==pages?pages:(page+1))+"&rows="+rows;
        else
            nextUrl = url + "?page="+(page==pages?pages:(page+1))+"&rows="+rows;
        sb.append("<a href='"+nextUrl+"'>下一页</a>\r\n");
        String lastUrl = null;
        if(url.indexOf("?")>0)
            lastUrl = url + "&page="+pages+"&rows="+rows;
        else
            lastUrl = url + "?page="+pages+"&rows="+rows;
        sb.append("<a href='"+lastUrl+"'>尾页</a>\r\n");
        sb.append("&nbsp;&nbsp;&nbsp;&nbsp;第"+page+"/"+pages+"页\r\n");
        sb.append("&nbsp;&nbsp;&nbsp;&nbsp;共"+total+"条记录\r\n");
        sb.append("</div>\r\n");
        return sb.toString();
    }
}

菜单页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>    
<!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>菜单列表</title>
<link rel="stylesheet" type="text/css" href="/js/base.css">
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script>
function doquery()
{
    listfrm.submit();
}
function dodelete()
{
    listfrm.action = '/delete'
    listfrm.submit();
}
function selectall()
{
    $('input[name="id"]').each(function(){
        this.checked = $('#idall').prop("checked");
    })
}
function doadd()
{
    var url = '/add';
    window.open(url,'_self');
}
function doedit(id)
{
    var url = '/modify?id='+id;
    window.open(url,'_self');
}
function doview(id)
{
    var url = '/view?id='+id;
    window.open(url,'_self');
}
function dorefresh()
{
    var url = '/list';
    window.open(url,'_self');
}
function dosingledel(id)
{
    listfrm.action = '/delete?id='+id
    listfrm.submit();
}
</script>
</head>
<body>
<form id="listfrm" action="/list" method="post">
<input type="text" id="name" name="name" value="${name }"/>
<input type="button" onclick="doquery()" value="查询"/>
<input type="button" onclick="dodelete()" value="批量删除"/>
<input type="button" onclick="doadd()" value="添加"/>
<input type="button" onclick="dorefresh()" value="刷新"/>
<table>
    <tr>
        <th><input type="checkbox" id="idall" name="idall" onclick="selectall()">全选</th>
        <th>编号</th>
        <th>名称</th>
        <th>材料</th>
        <th>价格</th>
        <th>操作</th>
    </tr>
    <c:forEach items="${menuList}" var="m">
        <tr>
            <td><input type="checkbox" id="id" name="id" value="${m.id }"></td>
            <td>${m.id }</td>
            <td>${m.name }</td>
            <td>${m.sname }</td>
            <td>${m.price }</td>
            <td>
                <input type="button" value="编辑" onclick="doedit(${m.id })"/>
                <input type="button" value="查看" onclick="doview(${m.id })"/>
                <input type="button" value="删除" onclick="dosingledel(${m.id })"/>
            </td>
        </tr>
        </c:forEach>
</table>
    ${pageDiv }
</form>
</body>
</html>

添加菜单页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>    
<!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>菜单</title>
<link rel="stylesheet" type="text/css" href="/js/base.css">
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script>
function dosave()
{
    addfrm.submit();
}
</script>
</head>
<body>
<form id="addfrm" action="/save" method="post">
<table>
    <input type="hidden" id="id" name="id" value="${menu.id}"/>
    <tr>
        <td>菜单名称</td>
        <td><input type="text" id="name" name="name" value="${menu.name}"/></td>
    </tr>
    <tr>
        <td>价格</td>
        <td><input type="text" id="price" name="price" value="${menu.price}"/></td>
    </tr>
    <tr>
        <td>材料</td>
        <td>
            <c:forEach items="${staffList }" var="s">
                <input type="checkbox" id="sid" name="sid" value="${s.id }" ${s.checked}>${s.name}
            </c:forEach>
        </td>
    </tr>
</table>
<input type="button" onclick="dosave()" value="保存">
<input type="button" onclick="window.open('/list','_self')" value="返回">
</form>
</body>
</html>

查看菜单页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>    
<!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>菜单</title>
<link rel="stylesheet" type="text/css" href="/js/base.css">
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script>
function dosave()
{
    addfrm.submit();
}
</script>
</head>
<body>
<form id="addfrm" action="/save" method="post">
<table>
    <input type="hidden" id="id" name="id" value="${menu.id}"/>
    <tr>
        <td>菜单名称</td>
        <td><input type="text" id="name" name="name" value="${menu.name}"/></td>
    </tr>
    <tr>
        <td>价格</td>
        <td><input type="text" id="price" name="price" value="${menu.price}"/></td>
    </tr>
    <tr>
        <td>材料</td>
        <td>
            <c:forEach items="${staffList }" var="s">
                <input type="checkbox" id="sid" name="sid" value="${s.id }" ${s.checked}>${s.name}
            </c:forEach>
        </td>
    </tr>
</table>
<input type="button" onclick="window.open('/list','_self')" value="返回">
</form>
</body>
</html>

通用CSS
base.css

@charset "utf-8";
/* CSS Document */

body{
    margin:0 auto;
    padding:0;  
    font-family:'Microsoft YaHei', arial, tahoma, \5b8b\4f53, sans-serif;
    font-size: 14px;
}
a {
    text-decoration:none;
    color:black;
}
div{
    margin:0 auto;
}
#pagediv{
    margin:0 auto;
    text-align:center;
    valign:middle;
    background-color: yellow;
    height:30px;
    line-height: 30px;
    border:1px solid black
}

table {
    width:100%;
    font-family: verdana,arial,sans-serif;
    font-size:11px;
    color:#333333;
    border-width: 1px;
    border-color: #666666;
    border-collapse: collapse;
}
table tr:nth-child(odd) td{
    background: #ccc;
}
table tr:hover td{
    background: pink;

}
table th {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: yellow;
}
table th {
    font-size:15px;
    color:blue;
}
table td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #ffffff;
}

SpringBoot启动类

package com.test.util;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.core.Queue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication //SpringBoot程序固定注解
@MapperScan("com.test.mapper") //扫描Mybatis定义Mapper接口
@ComponentScan("com.test.ctrl,com.test.service.impl,com.test.util") //扫描Spring包路径
@EnableScheduling
public class Starter {

    public static void main(String[] args) {
        SpringApplication.run(Starter.class,args);
    }

}

这里写图片描述

代码下载:
https://github.com/qixiangchen/Proj_SpringRabbitmq.git

猜你喜欢

转载自blog.csdn.net/qixiang_chen/article/details/81588547