springboot2.2.2+mybatis-plus3.0.0+bootstrap+jsp(webjars)

bootstrap模板(包括HTML和jsp) bootstrap模板包含html,jsp代码,从登陆到后台管理界面都有 立即下载

尚硅谷SSM框架实战课程,我把整个框架改为springboot+mybatis-plus+bootstrap+jQuery+jsp的项目

gitee地址:https://gitee.com/niucheng/sbm

一、创建springboot项目

使用idea创建springboot项目

二、引入依赖

		<!--Springboot整合web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--1:jsp的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <!--Provided 编译和测试的时候使用-->
            <scope>provided</scope>
        </dependency>
        <!-- 对jsp的支持的依赖 -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <!--Provided 编译和测试的时候使用-->
            <scope>provided</scope>
        </dependency>
        <!-- jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--2: webjar的方式引入bootstrap和Jquery-->
        <!--jquery 的webjar-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--boot strap 的webjar-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.0.0</version>
        </dependency>

        <!--3:mybatisPlus、数据库链接驱动、druid连接池、pagehelper-->
        <!--mybatisPlus3.1.0-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.1</version>
        </dependency>

        <!--mysql驱动、连接池-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.17</version>
        </dependency>
        <!-- 分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.13</version>
        </dependency>




        <!--其他包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

三、配置文件中配置相应的jsp的文件目录及后缀

在application.properties文件中填加

#项目的访问名字,使用jsp一定要加上。
server.servlet.context-path=/sbm
#项目的服务名字
spring.application.name=/sbm
#视图解析配置
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

四:编写controller中通用跳转页面方法

@Controller
public class BaseController {
    //去主页 http://127.0.0.1:8080/sbm/index
    @GetMapping("/index")
    public String index(){
        return "index";
    }
    //http://127.0.0.1:8080/sbm/
    @GetMapping("/")
    public String index1(){
        return "index";
    }
    //跳转页面,前段传jsp文件名就可以跳转该页面
    @RequestMapping("/forPage")
    protected String forPageJsp(String pageName) {
        return pageName;
    }

}

五、整合jsp中使用bootstrap、同时使用basepath,Ajax使用需要。

1、src目录下,新建webapp/WEB-INF/jsp/目录,然后新建index.jsp

在jsp页面中顶部增加增加basepath代码

Ajax使用basepath:

webjars的方式引入bootstrap4.0.0和jquery3.3.1

使用bootstrap,访问地址:http://127.0.0.1:8080/sbm/index,访问成功后是下方左边的样子。

index.jsp页面的完整代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
    <script>
        var rootPath = '<%=basePath%>';
    </script>

    <title>springboot+bootstrap</title>
    <!-- Bootstrap core CSS -->
    <!--<link href="asserts/css/bootstrap.min.css" rel="stylesheet">-->
    <!-- webjar 方式引入 Bootstrap的包-->
   <%-- <link  th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">--%>
    <!-- Custom styles for this template -->
    <!--<link href="asserts/css/signin.css" rel="stylesheet">-->
    <!-- webjar 方式引入 自己的包-->
    <%--<link th:href="@{/asserts/css/signin.css}" rel="stylesheet">--%>


    <script src="webjars/jquery/3.3.1/jquery.min.js"></script>
    <script src="webjars/bootstrap/4.0.0/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="webjars/bootstrap/4.0.0/css/bootstrap.min.css" />



</head>



<body>
呃呃呃呃呃呃呃呃呃呃呃呃
<!-- Provides extra visual weight and identifies the primary action in a set of buttons -->
<button type="button" class="btn btn-primary">(首选项)Primary</button>
<!-- Indicates a successful or positive action -->
<button type="button" class="btn btn-success">(成功)Success</button>


<button>原始</button>
<button class="btn-warning">警告</button>
<button class="btn-danger">报警</button>

</body>
</html>

六:整合mybatis-plus

1、引入依赖,前面的pom文件中已经引入全部的依赖,这里重复介绍了

2、mybatisplus配置,我们可以看到集成MyBatis-Plus非常的简单,只需要引入 starter 工程,并配置 mapper 扫描路径即可

在application.properties中配置:

#配置数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

#mybatis-plus配置
mybatis-plus.mapper-locations= classpath*:/mapper/**Mapper.xml
mybatis-plus.type-aliases-package=com.niucheng.sbmcrud.entuty

配置 MapperScan 注解,配置 mapper 扫描路径即可。在启动类上加@MapperScan("com.niucheng.sbmcrud.dao")

@SpringBootApplication
@MapperScan("com.niucheng.sbmcrud.dao")
public class SbmCrudApplication {

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

}

3、mybstis-plus的逆向工程(两种方式)

idea安装"Free Mybatis plugin"插件,链接数据库以后可以直接生成mapper.xml文件,需要指定mapper(dao)、实体类、Mapper.xml文件的位置。

在idea上链接到数据,打开表右键选第一个“mybatis-generator”

红线圈住的地方需要,手动指定包的位置,最下方的可以不勾选,看个人需要。

注意:src/main/resources/mapper目录下的**Mapper.xml一定要大写。与配置文件(classpath*:/mapper/**Mapper.xml)中对应

由于我们使用的是mybatis-plus生产的mapper没有继承BaseMapper<>,需要自己手动的添加。

4、测试mybatis-plus使用

在springboot测试类中添加@RunWith(SpringRunner.class)注解,和相应的测试方法

    @Resource
    private UserMapper mapper;


    @Test
    public void insert() {
        User user = new User();
        user.setName("小羊");
        user.setAge(3);
        user.setEmail("abc@mp.com");
        assertThat(mapper.insert(user)).isGreaterThan(0);
        // 成功直接拿回写的 ID
        assertThat(user.getId()).isNotNull();
    }

七:pagehelper的使用

1、引入pagehelper的依赖,前面介绍pom文件中已经有了,这里不重复写了。

2、在application.properties中配置

		#pageHelper分页插件
		pagehelper.helper-dialect=MYSQL
        #分页参数合理化
		pagehelper.reasonable=true
		pagehelper.support-methods-arguments=true
		pagehelper.params=count=countSql

3、使用pagehelper分页查询:

	    @GetMapping(value = "/empbyPage")
		@ResponseBody
		public PageInfo empbyPage(Integer pageNum, Integer pageSize){
			pageSize =5;
			// 查询之前需要调入页码,以及每页的大小 pageNum是第几页,pageSize是每页显示多少条。
			PageHelper.startPage(pageNum, pageSize);
			List<Emp> emps = empService.getALL();
			//pageInfo包装查询后的结果
			PageInfo<Emp> pageInfo = new PageInfo<>(emps);
			return   pageInfo;
		}

八:index.jsp用ajax方式查询数据

1、返回json数据的controller且使用统一返回结果格式Msg

    @GetMapping("/emplist")
    @ResponseBody
    public Msg getemplist(@RequestParam(value="pn",defaultValue="1")Integer pn){
        //查询之前需要调入页码,以及每页的大小
        PageHelper.startPage(pn,5);
        List<Emp> empList = empService.getALL();
        //封装了详细的分页信息,第二个参数是页码数量
        PageInfo<Emp> pageInfo = new PageInfo<>(empList,5);


        return Msg.success().add("pageInfo", pageInfo);
    }

2、改首页,首页直接发ajax请求,返回数据在index页面显示。

<script type="text/javascript">
    //1、页面加载完成以后,直接去发送ajax请求,要到分页数据
    $(function () {
        //去首页
        to_page(1);
    });
    //去哪一页的通用方法
    function to_page(pn) {
        $.ajax({
            url: "${basePath}emplist",
            data: "pn=" + pn,
            type: "GET",
            success: function (result) {
                //console.log(result);
                //1、解析并显示员工数据
                build_emps_table(result);
                //2、解析并显示分页信息
                build_page_info(result);
                //3、解析显示分页条数据
                build_page_nav(result);
            }
        });
    }
</script>

1)解析并显示员工数据

    //1解析并显示员工数据
    function build_emps_table(result) {
        //清空table表格
        $("#emps_table tbody").empty();

        //获取返回结果中的表格内容
        var emps = result.extend.pageInfo.list;
        //循环表格的内容
        $.each(emps, function (index, item) {
            //获取每一列的数据
            var checkBoxTd = $("<td><input type='checkbox' class='check_item'/></td>");
            var empIdTd = $("<td></td>").append(item.empId);
            var empNameTd = $("<td></td>").append(item.empName);
            var genderTd = $("<td></td>").append(item.empName == 'M' ? "男" : "女");
            var emailTd = $("<td></td>").append(item.email);
            var deptNameTd = $("<td></td>").append(item.dept.deptName);

            //操作列的按钮
            var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn")
                .append($("<span></span>")).addClass("glyphicon glyphicon-pencil").append("编辑");
            //为编辑按钮添加一个自定义的属性,来表示当前员工id
            editBtn.attr("edit-id", item.empId);
            var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn")
                .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除");
            //为删除按钮添加一个自定义的属性来表示当前删除的员工id
            delBtn.attr("del-id", item.empId);
            //把两个按钮放在一个单元格中
            var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn);

            //把每一列的数据填加到emps_table 的tbody中
            //append方法执行完成以后还是返回原来的元素
            $("<tr></tr>").append(checkBoxTd)
                .append(empIdTd)
                .append(empNameTd)
                .append(genderTd)
                .append(emailTd)
                .append(deptNameTd)
                .append(btnTd)
                .appendTo("#emps_table tbody");

        });
    }

2)解析并显示分页信息

    function build_page_info(result) {
        //先清空原来的数据
        $("#page_info_area").empty();
        $("#page_info_area").append("当前" + result.extend.pageInfo.pageNum + "页,总" +
            result.extend.pageInfo.pages + "页,总" + result.extend.pageInfo.total + "条记录");

    }

3)解析并显示分页信息,点击分页要能去下一页....

/**
     *  导航栏的格式:
     *  <nav>
     *          <ul>
     *              <li>首页</li>
     *              <li>前一页</li>
     *              <li>1</li>
     *              <li>2</li>
     *              <li>3</li>
     *              <li>4</li>
     *              <li>后一页</li>
     *              <li>末页</li>
     *          </ul>
     *  </nav>
     *3解析并显示分页信息,点击分页要能去下一页....
     * */
    function build_page_nav(result) {
        //先清空原有的数据
        $("#page_nav_area").empty();
        var ul = $("<ul></ul>").addClass("pagination");

        //构建元素
        var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href", "#"));
        var prePageLi = $("<li></li>").append($("<a></a>").append("&laquo;"));
        //判断是否前一页
        if (result.extend.pageInfo.hasPreviousPage == false) {
            firstPageLi.addClass("disabled");
            prePageLi.addClass("disabled");
        } else {
            //为元素添加点击翻页的事件
            firstPageLi.click(function () {
                to_page(1);
            });
            prePageLi.click(function () {
                to_page(result.extend.pageInfo.pageNum - 1);
            });
        }

        var nextPageLi = $("<li></li>").append($("<a></a>").append("&raquo;"));
        var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href", "#"));
        //判读是否有下一页一页
        if (result.extend.pageInfo.hasNextPage == false) {
            nextPageLi.addClass("disabled");
            lastPageLi.addClass("disabled");
        } else {
            nextPageLi.click(function () {
                to_page(result.extend.pageInfo.pageNum + 1);
            });
            lastPageLi.click(function () {
                to_page(result.extend.pageInfo.pages);
            });
        }
        //添加首页和前一页 的提示
        ul.append(firstPageLi).append(prePageLi);
        //1,2,3遍历给ul中添加页码提示
        $.each(result.extend.pageInfo.navigatepageNums, function (index, item) {

            var numLi = $("<li></li>").append($("<a></a>").append(item));
            //判断当前页码是否等于遍历的item
            if (result.extend.pageInfo.pageNum == item) {
                numLi.addClass("active");//活动标识(就是颜色变蓝)
            }
            numLi.click(function () {
                to_page(item);
            });
            ul.append(numLi);
        });
        //添加下一页和末页 的提示
        ul.append(nextPageLi).append(lastPageLi);

        //把ul加入到nav
        var navEle = $("<nav></nav>").append(ul);
        navEle.appendTo("#page_nav_area");

    }

 此处需要修改顶部加载数据的方法,改为第一步先跳到第一页,

九:新增员工页面

1、创建增页面的模态框

<!-- 员工添加的模态框-->
<div class="modal fade" id="empAddModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title" id="myModalLabel">添加员工</h4>
            </div>
            <div class="modal-body">

                <form class="form-horizontal">

                    <div class="form-group">
                        <label  class="col-sm-2 control-label">empName</label>
                        <div class="col-sm-10">
                            <input type="text" name="empName" class="form-control" id="empName_add_input" placeholder="empName">
                        </div>
                    </div>

                    <div class="form-group">
                        <label  class="col-sm-2 control-label">email</label>
                        <div class="col-sm-10">
                            <input type="email" name="email" class="form-control" id="email_add_input" placeholder="email">
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">gender</label>
                        <div class="col-sm-3">
                            <label class="radio-inline">
                                <input type="radio" name="gender" id="gender1_add_input" value="M" checked="checked"> 男
                            </label>
                            <label class="radio-inline">
                                <input type="radio" name="gender" id="gender2_add_input" value="F"> 女
                            </label>
                        </div>
                <%--    </div>

                    <div class="form-group">--%>
                        <label class="col-sm-2 control-label">deptName</label>
                        <div class="col-sm-3">
                            <!-- 部门提交部门id即可 -->
                            <select class="form-control" name="dId">
                                <%--查数据库中的部门--%>
                            </select>
                        </div>
                    </div>

                </form>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary">保存</button>
            </div>
        </div>
    </div>
</div>

2、新增按钮的事件,点击新增加按钮先调用depts接口查询所有部门信息(后台接口省略了)。

	    //新增员工按钮的点击事件
		$("#emp_add_modal_btn").click(function () {
			//发送ajax请求查询,查出部门信息,显示在下拉列表
				getDepts();
			$("#empAddModal").modal({
				//设置点击背景不关闭模态框
				backdrop: "static"
			});
		});
		
		//查出所有的部门信息并显示在下拉列表中
		function getDepts(){
			$.ajax({
				url: rootPath+"depts",
				type: "GET",
				success:function (result) {
					//显示部门信息在下拉列表中
					//$("#empAddModal select").append("")
				   $.each(result.extend.depts,function () {
						var  optionEle = $("<option></option>").append(this.deptName).attr("value",this.deptId);
						//把单条的部门信息添加到下拉列表, (此处用到name属性赋值)
					   optionEle.appendTo("#empAddModal select");
				   });
				}
			});
		};

注意:此处把jQuery代码放在static目录下的index.js文件中了。

3、保存按钮的点击事件

员工保存按钮的点击事件,先调用后台emp()方法,然后关闭模态款,跳转新添加数据哪一页

/员工保存按钮的点击事件
$("#emp_save_btn").click(function () {

    //1、先对提交的数据进行校验。
    if (!valiidate_add_form()) {
        return false;
    }

    //发送ajax请求emp接口,保存员工
    $.ajax({
        url: rootPath + "emp",
        type: "POST",
        data: $("#empAddModal form").serialize(),
        success: function (result) {

            if (result.code == 100) {
                //1、保存成功关闭新增模态框,且跳转到最后一页看,新增的数据
                $("#empAddModal").modal('hide');
                //跳转到最后一页,把总的记录数传进去。需要配置pagehelper的分页参数合理化。
                to_page(totalRecord);
            } else {
                //2、没有保存成功,提示那些数据错误
            }

        }
    })

});

 在index.js文件顶部声明 totalRecord,currentPage两个变量,在build_page_info()方法中赋值。关闭模态框的时候调用to_page(totalRecord);把totalRecord(总记录数)传进去。

知识点:$("#empAddModal form").serialize(), 可以将表单中的数据序列化,前提是name属性值鱼实体类的字段名一致

4、点击保存按钮时的数据校验

点击保存时先对form表单的数据校验,调用valiidate_add_form()校验数据,然后调用show_validate_msg(ele, state, msg)对输入框提示

    //1、先对提交的数据进行校验。
    if (!valiidate_add_form()) {
        return false;
    }
//校验表单数据
function valiidate_add_form() {

    //1、拿到要校验的数据,使用正则表达式
    var empName = $("#empName_add_input").val();
    //校验名字的正则表达式:大小写字母+数字6到16位,或者中文2位到5位
    var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
    if (!regName.test(empName)) {
        //alert("用户名可以是2-5位中文或者6-16位英文和数字的组合");
        show_validate_msg("#empName_add_input", "error", "用户名可以是2-5位中文或者6-16位英文和数字的组合");
        //获取员工名字输入框的父元素,设置为错误的提示
        //$("#empName_add_input").parent().addClass("has-error");
        //把员工名字输入框下一个<span>标签添加提示语
        //$("#empName_add_input").next("span").text("用户名可以是2-5位中文或者6-16位英文和数字的组合");
        return false;
    } else {
        show_validate_msg("#empName_add_input", "success", "");
        // $("#empName_add_input").parent().addClass("has-success");
        // $("#empName_add_input").next("span").text("");
    }
    //2、校验邮箱
    var email = $("#email_add_input").val();
    var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
    if (!regEmail.test(email)) {
        //alert("邮箱格式不正确");
        show_validate_msg("#email_add_input", "error", "邮箱格式不正确");
        return false;
    } else {
        show_validate_msg("#email_add_input", "success", "");
    }

    return true;
}
//显示校验结果的提示信息
function show_validate_msg(ele, state, msg) {
    //清除当前元素的校验状态
    $(ele).parent().removeClass("has-success has-error");
    $(ele).next("span").text("");
    if ("success" == state) {
        $(ele).parent().addClass("has-success");
        $(ele).next("span").text(msg);
    } else if ("error" == state) {
        $(ele).parent().addClass("has-error");
        $(ele).next("span").text(msg);
    }
};

知识点:错误提示语方式<span></span>,新的样式添加需要把旧的样式清除

显示效果图:

十:新增员工姓名重复的检查

1、写后台的检查用户名重复的方法

	    @PostMapping(value = "/checkuser")
		@ResponseBody
		public Msg checkuser(@RequestParam("empName") String empName) {
			//先判断用户名是否是合法的表达式
			String regx = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})";
			if (!empName.matches(regx)) {
				return Msg.fail().add("va_msg", "用户名必须是6-16位数字和字母的组合或者2-5位中文");
			}

			boolean result = empService.checkuser(empName);
			if (result) {
				return Msg.success();
			} else {
				return Msg.fail().add("va_msg", "用户名不可用");
			}
		}

2、给empName输入框失去焦点,检查用户是否重复

		//检查用户名是否重复
		$("#empName_add_input").change(function () {
			//发送ajax请求校验用户名是否可用
			var empName = this.value;
			$.ajax({
				url:rootPath+"checkuser",
				type:"POST",
				data:"empName="+empName,
				success:function (result) {
					if (result.code ==100){
						show_validate_msg("#empName_add_input","success","用户名可用");
						//设置保存按钮的自定义属性为success,点击保存时判断这个按钮是否可以保存
						$("#emp_save_btn").attr("ajax-va","success");
					}else{
						show_validate_msg("#empName_add_input","error",result.extend.va_msg);
						//设置保存按钮的自定义属性位error,点击保存时判断这个按钮是否可以保存
						$("#emp_save_btn").attr("ajax-va","error");
					}

				}
			})
		});

3、优化校验

点击新增员工按钮,清除form表单的数据和样式

		//清空表单样式及内容
		function reset_form(ele) {
			$(ele)[0].reset();
			//清空表单样式
			$(ele).find("*").removeClass("has-error has-success");
			$(ele).find(".help-block").text("");
		}

优化点击保存员工按钮对名字重复校验

十一:员工修改

1、给编辑按钮添加标识

var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn").append($("<span></span>")).addClass("glyphicon glyphicon-pencil").append("编辑");

2、修改员工的模态框

<!-- 员工修改的模态框 -->
<div class="modal fade" id="empUpdateModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">员工修改</h4>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="form-group">
                        <label class="col-sm-2 control-label">empName</label>
                        <div class="col-sm-10">
                            <p class="form-control-static" id="empName_update_static"></p>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">email</label>
                        <div class="col-sm-10">
                            <input type="text" name="email" class="form-control" id="email_update_input" placeholder="email@atguigu.com">
                            <span class="help-block"></span>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">gender</label>
                        <div class="col-sm-10">
                            <label class="radio-inline">
                                <input type="radio" name="gender" id="gender1_update_input" value="M" checked="checked"> 男
                            </label>
                            <label class="radio-inline">
                                <input type="radio" name="gender" id="gender2_update_input" value="F"> 女
                            </label>
                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-sm-2 control-label">deptName</label>
                        <div class="col-sm-4">
                            <!-- 部门提交部门id即可 -->
                            <select class="form-control" name="dId">
                            </select>
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary" id="emp_update_btn">更新</button>
            </div>
        </div>
    </div>
</div>

3、用.on()绑定编辑按钮的事件

			//编辑按钮的点击事件
			$(document).on("click",".edit_btn",function () {
				//1、查出部门信息,并显示部门列表,此处修改获取部门的方法,传入下拉框的id
				getDepts("#empUpdateModal select");
				//2、查单个的员工信息,并添加到修改员工模态框
				getEmp($(this).attr("edit-id"));
				//弹出员工修改的模态框
				$("#empUpdateModal").modal({
					//设置点击背景不关闭模态框
					backdrop: "static"
				});
			});

4、给getDepts(ele);增加情况原来下拉框的方法

//清空原来下列表的数据
$(ele).empty();

5、回显员工信息

			把原来的用名字改为静态框,员工姓名不可修改
			<p class="form-control-static" id="empName_update_static"></p>


			
			//查单个的员工信息,并添加到修改员工模态框
			function getEmp(id) {
				$.ajax({
					url: rootPath+"emp/"+id,
					type:"GET",
					success:function(result){
						console.log(result);
						var empData = result.extend.emp;
						$("#empName_update_static").text(empData.empName);
						$("#email_update_input").val(empData.email);
						$("#empUpdateModal input[name=gender]").val([empData.gender]);
						$("#empUpdateModal select").val([empData.did]);
					}
				});

			}

6、更新按钮的事件

//点击更新按钮
$("#emp_update_btn").click(function () {
    //验证邮箱是否合法
    var email = $("#email_update_input").val();
    var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
    if (!regEmail.test(email)) {
        //alert("邮箱格式不正确");
        show_validate_msg("#email_update_input", "error", "邮箱格式不正确");
        return false;
    } else {
        show_validate_msg("#email_update_input", "success", "");
    }
//2、发送ajax请求保存更新的员工数据
    //alert($(this).attr("edit-id"));
    $.ajax({

        url: rootPath + "emp/" +$(this).attr("edit-id"),
        type: "PUT",
        data: $("#empUpdateModal form").serialize(),
        success: function (result) {
            //1、关闭对话框
            $("#empUpdateModal").modal("hide");
            //2、回到本页面
            to_page(currentPage);
        }
    })
});

注意:springboot项目用put方法,不需要做任何配置,springmvc 需要添加:httpPutFormContentFilter过滤器

十二:批量删除

1、单个删除按钮的事件

//删除按钮的事件
$(document).on("click", ".delete_btn", function () {
    //1、弹出是否确认删除对话框
    var empName = $(this).parents("tr").find("td:eq(2)").text();
    var empId = $(this).attr("del-id");
    if (confirm("确认删除【" + empName + "】吗?")) {
        //确认,发送ajax请求删除即可
        $.ajax({
            url: rootPath + "/emp/" + empId,
            type: "DELETE",
            success: function (result) {
                //alert(result.msg);
                //回到本页
                to_page(currentPage);
            }
        });
    }

});

2、全选、全不选的CheckBox

//完成全选、全不选的功能
$("#check_all").click(function () {
    //我们这些dom原生的属性;attr获取自定义属性的值;prop修改和读取dom原生属性的值
    $(this).prop("checked");//顶部全选框的状态值

    //把所有的选中框状态值与全选框状态同步
    $(".check_item").prop("checked", $(this).prop("checked"));
});


//所有的单选框选中以后,把顶部的全选框也选中
$(document).on("click", ".check_item", function () {
    //先判断选中的item元素是否是五个
    $(".check_item:checked").length;//已经选中元素个数
    $(".check_item").length;//所有元素的个数
    //两个相等把全选框的状态设置成true
    var flag = $(".check_item:checked").length == $(".check_item").length;
    $("#check_all").prop("checked", flag);

});

3、批量删除

//批量删除的按钮
$("#emp_delete_all_btn").click(function () {
    var empNames = "";
    var del_idstr = "";
    //循环选中的item
    $.each($(".check_item:checked"), function () {

        //组装提示要删除的用户名
        empNames += $(this).parents("tr").find("td:eq(2)").text() + ",";
        //组装员工id字符串
        del_idstr += $(this).parents("tr").find("td:eq(1)").text() + "-";
    });
    //去除empNames多余的,
    empNames = empNames.substring(0, empNames.length - 1);
    //去除删除的id多余的-
    del_idstr = del_idstr.substring(0, del_idstr.length - 1);

    if (confirm("确认删除【" + empNames + "】吗?")) {
        //发送ajax请求删除
        $.ajax({
            url: rootPath + "/emps/" + del_idstr,
            type: "DELETE",
            success: function (result) {
                //alert(result.msg);
                //回到当前页面
                to_page(currentPage);
            }
        });
    }

});

后台代码:

    @DeleteMapping(value = "/emps/{ids}")
    @ResponseBody
    public Msg deleteEmpBatchIds(@PathVariable("ids") String ids){
        List<Integer> del_ids=new ArrayList<Integer>();
        String[] str_ids=ids.split("-");
        //组装id的集合
        for(String string : str_ids)
        {
            del_ids.add(Integer.parseInt(string));
        }
        boolean result =empService.deleteEmpBatchIds(del_ids);

        if (result){
            return  Msg.success();
        }else {
            return Msg.fail();
        }
    }

 

SpringMVC+Spring+MyBatis+MySql+Bootstrap+Jsp详细例程 SpringMVC+Spring+MyBatis+MySql+Bootstrap+Jsp例程,后台由SSM框架实现,前端用JSP+Bootstrap+JS实现,数据库用MySql。 本例程注释清晰,代码格式规范,后台分层清楚,内含数据库创建SQl文件,适合新手参考,访问http://204d.cn/seckill/list可查看项目,不懂之处可咨询jjxx93@126.com 立即下载

相关推荐

简洁大气的Bootstrap前台框架(Jsp版)

纯手工原创 良心制作

Bootstrap+JSP实例学习笔记一.简单的带登录功能的首页

前言 Bootstrap是流行的HTML、CSS和JS框架,用于开发响应式布局、移动设备优先的WEB项目。源自于twiteer内部的开发框架。 当前(2019-05)最新版本是v3.3.7。 官网:https://v3.bootcss.com/ 学习初衷:不能每来一个项目都重头开始吧,希望积累框架,节省时间,快速上手,尽快出效果。不用太花哨,但也不能太难看。 选一...

weixin_30779691的博客 873

基于BootStrap3的JSP项目实例教程

BootStrap实例教程

在jsp引入bootstrap

第一步:在https://v3.bootcss.com/getting-started/#top该网站下载Bootstrap,有可以看到有三种,如下图所示(本人下载的是源码) 第二步:解压下载的解压包 第三步:新建Maven工程然后将它转为一个动态web工程(如果不会,可以参考本人上一篇博客《将一个Maven工程转为一个标准的Web动态工程》) 第四步:在src下面新建一个文件夹(static...

苏世 1万+

springboot+mybatis+mysql+jsp+bootstrap+web.xml例子

springboot+mybatis+mysql+jsp+bootstrap+web.xml例子

飞牛NAS挂载115网盘避坑指南:为什么你的大文件总是传输失败?

本文深入解析了在飞牛NAS上通过AList挂载115网盘时,大文件传输失败的深层原因,包括风控机制、网络协议及兼容性问题。文章提供了从基础排查到高阶优化的系统性解决方案,并建议采用Kopia分片备份等终极策略,以实现稳定可靠的云端数据流转。

weixin_29306011的博客 1680

在JSP页面中使用Bootstrap

Bootstrap 是最受欢迎的 HTML、CSS 和 JS 框架,用于开发响应式布局、移动设备优先的 WEB 项目。官网:https://v3.bootcss.com/。 在官网下载相应版本后,导入资源【css、js、fonts】,然后在<head></head>中写 <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <me

ysmdelog的博客 2969

STM32F407与AD7766实战:如何用SPI+DMA实现高速ADC数据采集(附完整代码)

本文详细介绍了如何利用STM32F407的SPI接口与DMA控制器,高效稳定地驱动24位高精度ADC芯片AD7766,实现高速连续数据采集。通过对比传统中断方式的瓶颈,阐述了SPI+DMA方案如何大幅降低CPU负载,并提供了从硬件设计、CubeMX配置到核心驱动代码的完整实战指南,帮助工程师解决高速ADC数据采集中的性能难题。

weixin_29281941的博客 185

jsp引入并使用bootstrap和jquery——javaweb系列(五)

jsp引入并使用bootstrap和jquery——javaweb系列(五)

qq_23858785的博客 1709

CHNS数据库下载与使用指南:从申请到导入的全流程解析

面板数据是经济学与公共卫生实证研究的重要支撑。中国健康与营养调查(CHNS)自1989年持续追踪中国居民的家庭与个人健康、营养及经济行为,为研究者提供了跨度近三十年的纵向微观数据。理解CHNS的数据组织原理与申请机制,是高效利用该数据的前提。该数据广泛适用于健康经济学、膳食营养分析及公共政策评估等场景。围绕CHNS的下载流程,完整梳理了注册申请、数据文件解析以及Stata、R、Python三种工具的读取方法,并针对邮箱验证、文件损坏、ID匹配等常见问题提供排查建议,帮助研究者快速建立数据处理基础。

weixin_33624741的博客 282

别再手动填数据了!Vivado里用.coe文件给ROM IP核预装数据的保姆级教程

本文详细介绍了在Vivado中使用.coe文件为ROM IP核预装数据的全流程教程,包括文件格式规范、数据转换技巧和Vivado配置指南。通过自动化数据加载,开发者可以显著提升FPGA开发效率,避免手动输入错误,适用于查找表、波形存储等多种应用场景。

weixin_33377602的博客 337

【物联网全栈】基于springboot + bootsrap + js + jsp + mysql + mqtt

本项目实现目标: 1、用户登录注册 2、用户创建产品 3、用户创建产品下的设备 4、设备绑定 设备数据上传 5、用户查询总产品列表、总设备列表 6、用户查询设备绑定命令、上传数据记录 7、用户发送命令到设备 网站部分大概需要1个月时间,硬件部分使用ESP32S2。 1、数据库5张表 【user】【product】【device】【devicebind】【devicestatus】 分别表示:用户表、产品表、设备表、绑定命令表、消息记录表 各个表ID自增 ,一个用户对应多个产品,一个产品对应多个设备,一

sgd985437的博客 4536

arcgis计算栅格平均值

打开FC栅格数据和非水体矢量数据 利用矢量数据提取对应栅格的非水体部分 2.1打开空间分析工具à提取分析à按掩膜提取 输入对应栅格数据和矢量数据 2.2提取结果如下 进行计算FC平均值 3.1打开空间分析工具à多元分析à波段集统计 输入对应栅格和输出路径 3.2统计结果如下 ...

Z_W_H_的博客 5370

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

【实战】CANOE实现UDS安全访问过程的CAPL脚本

首先我已经有了包含安全访问算法的dll文件,并通过Diagnostics/ISO TP Configuration中加载了此dll文件,如下。在on start部分,要将“ECU qualifier“作为参数,执行diagSetTarget函数。这个函数是用于设置tester从现在开始与之通信的目标ECU,并配置/建立与该ECU的通信通道。我最近在做密钥学习上位机时,遇到一些问题:如何用CAPL脚本实现安全访问过程?ECU Qualifier可以通过加载cdd文件后,在如下位置找到。CAPL脚本如何编写。

weixin_46481662的博客 4938

【目录】专栏文章导航

从最强工具链Davinci Configurator模块学习出发掌握AUTOSAR

weixin_47571898的博客 3285

【免费下载源码】Bootstrap+JSP+MySQL搭建电商网站

Bootstrap+jsp+Mysql搭建简易电商网站,包含增删改查商品、购物车、留言评价、用户商品管理等功能。

仨仨的博客 2万+

笔试题-2023-加特兰-数字IC设计【纯净题目版】

笔试题-2023-加特兰-数字IC设计【纯净题目版】

w0shishabi的博客 2247

基于BootStrap+JSP的学生管理系统(毕业设计项目)

基于BootStrap+JSP的学生管理系统1、前言2、概述3、项目运行截图4、部分代码5、数据库结构6、总结 1、前言 自己做的毕业设计项目,只是做了比较基础的东西,没有什么比较突出的功能,后台几个模块样式相同都是几个表。 2、概述 前端使用了BootStrap框架后端代码主要使用了JSP来实现,主要功能有用户登录、首页、管理员登录、学生管理、学生成绩、上课信息、课程管理、开课信息、详细信息、角色管理、退出登录,十一个大模块,当以管理员身份登录时可以实现对数据库中的数据进行增删改查的基础操作。

weixin_52307218的博客 3524

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java项目:图书管理系统(java+SpringBoot+JSP+bootstrap+maven+mysql)

源码获取:博客首页 "资源" 里下载! 项目介绍 本系统分为管理员与普通用户两种角色; 管理员角色包含以下功能: 借书管理,图书信息管理,图书分类管理,用户管理,角色管理,还书管理,登录页面等功能。 用户角色包含以下功能: 借阅管理,图书检索,查看借还记录,查看图书详情,还书管理,登录页面等功能。 环境需要 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tom.

常年被追砍的博客 973

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

终于学会了,SpringBoot整合JSP,建议收藏不然找不到了

SpringBoot整合JSP,一个经典而且优雅的方案! 步骤 1 pom.xml <!-- servlet依赖. --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency>

java小白翻身 730

springboot整合JSP(详细配置过程+配图和说明)

springboot整合jsp使用jsp模板引擎

雾林小妖的博客 1万+

Springboot框架整合jsp开发【干货满满】

Springboot框架整合jsp开发【干货满满】

无边热爱,来日方长 2057

springBoot 中 bootstrap 与 application

springBoot 中 bootstrap 与 application 加载顺序和使用场景

快乐的小三菊的博客 8494

Spring Boot 整合 Bootstrap

Springboot整合bootstrap笔记

小凯的博客 9652

Mybatis-Spring1.0.0与Mybatis-Spring3.0.0版本在与spring整合时的区别

Failed to convert property value of type 'java.lang.String' to required type 'org.apache.ibatis.session.Configuration' for property 'configuration'; Cannot convert value of type 'java.lang.String' to required type 'org.apache.ibatis.session.Configuration'

m0_73556978的博客 1195
上一篇: seata-server-1.1.0+nacos-server-1.4.0的配置
下一篇: 我的idea注释配置
你愁啥啊
博客等级 码龄11年 8粉丝 22原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值