自定义MVC框架实现增删改查

news2024/11/25 8:12:19

目录

一、环境搭建

二、导入配置文夹

1.中央控制器xml

2.增删改配置文件

3.导入工具类

 三、编写后端代码

1. 通用增删改查

2. BookDao类

 3. book实现增删改查类

4. 分页助手类

四、编写前端代码

1. 数据显示主界面

         2. 默认运行显示所有数据servlet

3. 新增、修改共用页面


一、环境搭建

对上一篇的内容优化,将之前写好的frmework包导成jar包

 

再导入相关jar包

 

二、导入配置文夹

1.中央控制器xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>mymvc_crud</display-name>
  <servlet>
    <servlet-name>mvc</servlet-name>
    <servlet-class>com.zking.framework.DispatchServlet</servlet-class>
    <init-param>
      <param-name>configurationLocation</param-name>
      <param-value>/mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>mvc</servlet-name>
    <url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>

2.增删改配置文件

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<action path="/book" type="com.zking.web.BookAction">
<!-- 	 查询:BookList.jsp		返回值:list -->
<!-- 	 * 增删改确定:book.action?methodName=list		返回值:toList -->
<!-- 	 * 增加修改跳转对应界面:bookEdit.jsp			返回值:toEdit -->
		<forward name="list" path="/bookList.jsp" redirect="false" />
		<forward name="toList" path="/book.action?methodName=list" redirect="true" />
		<forward name="toEdit" path="/bookEdit.jsp" redirect="false" />
	</action>
	
</config>

 

3.导入工具类

 进入此JSP自定义通用分页链接查看分装工具类目录

 

 

 三、编写后端代码

1. 通用增删改查

package com.zking.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.zking.util.DBAccess;
import com.zking.util.PageBean;

/**
 * 所有Dao层的父类
 * 
 * @author 云村小威
 *
 * @2023年7月3日 下午10:52:21
 */
public class BaseDao<T> {
	/**
	 * 通用的增删改方法
	 * 
	 * @param book
	 * @throws Exception
	 */
	public void executeUpdate(String sql, T t, String[] attrs) throws Exception {
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = con.prepareStatement(sql);
		/*
		 * 思路: 1.从传进来的t中读取属性值 2.往预定义对象中设置了值
		 * 
		 * t->book f->bid
		 */
		for (int i = 0; i < attrs.length; i++) {
			Field f = t.getClass().getDeclaredField(attrs[i]);
			f.setAccessible(true);
			pst.setObject(i + 1, f.get(t));
		}
		pst.executeUpdate();
	}

	/**
	 * 通用分页查询
	 * 
	 * @param sql
	 * @param clz
	 * @return
	 * @throws Exception
	 */
	public List<T> executeQuery(String sql, Class<T> clz, PageBean pageBean) throws Exception {
		List<T> list = new ArrayList<T>();
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = null;
		ResultSet rs = null;

		/*
		 * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...)
		 */
		if (pageBean != null && pageBean.isPagination()) {
			// 必须分页(列表需求)
			String countSQL = getCountSQL(sql);
			pst = con.prepareStatement(countSQL);
			rs = pst.executeQuery();
			if (rs.next()) {
				pageBean.setTotal(String.valueOf(rs.getObject(1)));
			}

			// 挪动到下面,是因为最后才处理返回的结果集
			String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据
			pst = con.prepareStatement(pageSQL);
			rs = pst.executeQuery();
		} else {
			// 不分页(select需求)
			pst = con.prepareStatement(sql);// 符合条件的所有数据
			rs = pst.executeQuery();
		}

		while (rs.next()) {
			T t = clz.newInstance();
			Field[] fields = clz.getDeclaredFields();
			for (Field f : fields) {
				f.setAccessible(true);
				f.set(t, rs.getObject(f.getName()));
			}
			list.add(t);
		}
		return list;
	}

	/**
	 * 将原生SQL转换成符合条件的总记录数countSQL
	 * 
	 * @param sql
	 * @return
	 */
	private String getCountSQL(String sql) {
		return "select count(1) from (" + sql + ") t";
	}

	/**
	 * 将原生SQL转换成pageSQL
	 * 
	 * @param sql
	 * @param pageBean
	 * @return
	 */
	private String getPageSQL(String sql, PageBean pageBean) {
		return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows();
	}
}

2. BookDao类

package com.zking.dao;

import java.util.List;

import com.zking.entity.Book;
import com.zking.util.BaseDao;
import com.zking.util.PageBean;
import com.zking.util.StringUtils;

/**
 * bookdao类
 * @author 云村小威
 *
 * @2023年7月3日 下午10:51:39
 */
public class BookDao extends BaseDao<Book>{
	/*
	 * public void add(Book book) throws Exception {
		String sql = "insert into t_mvc_book values(?,?,?)";
		Connection con = DBAccess.getConnection();
		PreparedStatement pst = con.prepareStatement(sql);
		pst.setObject(1, book.getBid());
		pst.setObject(2, book.getBname());
		pst.setObject(3, book.getPrice());
		pst.executeUpdate();
		}
		增删改查的通用套路
		1.建立链接
		2.预定义对象PreparedStatement
		3.设置占位符的?的值
		4.pst.executeUpdate();
		1.
	 */
	public void add(Book book) throws Exception {
		String sql = "insert into t_mvc_book values(?,?,?)";
		super.executeUpdate(sql, book, new String[] {"bid","bname","price"});
	}
	
	public void edit(Book book) throws Exception {
		String sql = "update t_mvc_book set bname = ?, price = ? where bid = ?";
		super.executeUpdate(sql, book, new String[] {"bname","price","bid"});
	}
	
	public void delete(Book book) throws Exception {
		String sql = "delete from t_mvc_book where bid = ?";
		super.executeUpdate(sql, book, new String[] {"bid"});
	}
	
	public List<Book> list(Book book,PageBean pageBean) throws Exception {
		String sql = "select * from t_mvc_book where 1=1 ";
		String bname = book.getBname();
		if(StringUtils.isNotBlank(bname)) {
			sql += " and bname like '%"+bname+"%'";
		}
		return super.executeQuery(sql, Book.class, pageBean);
	}
	
}

 

 3. book实现增删改查类

package com.zking.web;

import java.util.List;

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

import com.zking.dao.BookDao;
import com.zking.entity.Book;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.PageBean;

/**
 * book工作类
 * @author 云村小威
 *
 * @2023年7月3日 下午10:53:52
 */
public class BookAction extends ActionSupport implements ModelDriver<Book>{
	private Book book = new Book();
	private BookDao bookDao = new BookDao();
	@Override
	public Book getModel() {
		return book;
	}
	
	/*
	 * 增删改最终都要跳回查询界面
	 * 分析增删改查一共有多少结果集的配置
	 * 查询:BookList.jsp		返回值:list
	 * 增删改确定:book.action?methodName=list		返回值:toList
	 * 增加修改跳转对应界面:bookEdit.jsp			返回值:toEdit
	 */
	public String add(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookDao.add(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}
	
	public String list(HttpServletRequest req, HttpServletResponse resp) {
		try {
			PageBean pageBean = new PageBean();
			pageBean.setRequest(req);
			List<Book> list = bookDao.list(book,pageBean);
			req.setAttribute("books", list);
			req.setAttribute("pageBean", pageBean);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "list";
	}
	
	public String delete(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookDao.delete(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}
	
	public String edit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			bookDao.edit(book);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}
	/**
	 * 跳转到新增修改页面
	 * @param req
	 * @param resp
	 * @return
	 */
	public String toEdit(HttpServletRequest req, HttpServletResponse resp) {
		try {
			/*
			 * 如果是跳转修改页面,那么需要做bid条件的精准查询
			 */
			if(book.getBid() != 0) {
				List<Book> list = bookDao.list(book, null);
				req.setAttribute("b", list.get(0));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toEdit";
	}
}

4. 分页助手类

package com.zking.tag;

import com.zking.util.PageBean;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * Page助手类
 * 
 * @author 云村小威
 *
 */
public class PageTag extends BodyTagSupport {
	private static final long serialVersionUID = 1L;

	private PageBean pageBean;

	public PageBean getPageBean() {
		return pageBean;
	}

	public void setPageBean(PageBean pageBean) {
		this.pageBean = pageBean;
	}

	@Override
	public int doStartTag() throws JspException {
		// 获取流
		JspWriter out = pageContext.getOut();
		try {
			out.print(toHTML());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}

	/**
	 * JSP自定义页面内容展示
	 * 
	 * @return
	 */
	private String toHTML() {
		StringBuilder sb = new StringBuilder();

		// 这里拼接的是一个上一次发送的请求以及携带的参数,唯一改变的就是页码
		sb.append("<form id='pageBeanForm' action='" + pageBean.getUrl() + "' method='post'>");
		sb.append("<input type='hidden' name='page'>");
		// 重要设置拼接操作,将上一次请求参数携带到下一次
		Map<String, String[]> paMap = pageBean.getParameterMap();
		if (paMap != null && paMap.size() > 0) {
			Set<Map.Entry<String, String[]>> entrySet = paMap.entrySet();
			for (Map.Entry<String, String[]> entry : entrySet) {
				for (String val : entry.getValue()) {
					if (!"page".equals(entry.getKey())) {
						sb.append("<input type='hidden' name='" + entry.getKey() + "' value='" + val + "'>");
					}
				}
			}
		}
		sb.append("</form>");
		
		/**
		 * 页码数据配置
		 */
		int page = pageBean.getPage(); //当前页码
		int max = pageBean.getMaxPage();//最大页码
		int before = page > 4 ? 4 : page - 1;//当前页码前面的页码
		int after = 10 - 1 - before;//当前页码后面的页码
		
		//如果最大页码没有10页,就显示当前页面后面的所有页码 max - page
		after = page + after > max ? max - page : after;
		// 初始页码和结束页码值判断 disabled
		boolean startFlag = page == 1;
		boolean endFlag = max == page;

		// 拼接分页条
		sb.append("<ul class='pagination'>");
		sb.append("<li class='page-item " + (startFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(1)'>首页</a></li>");
		sb.append("<li class='page-item " + (startFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.getPrevPage() + ")'>&lt;</a></li>");

		// 代表了当前页的前4页
		for (int i = before; i > 0; i--) {
			sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage(" + (page - i) + ")'>"
					+ (page - i) + "</a></li>");
		}

		sb.append("<li class='page-item active'><a class='page-link' href='javascript:gotoPage(" + pageBean.getPage()
				+ ")'>" + pageBean.getPage() + "</a></li>");

		// 代表了当前页的后5页
		for (int i = 1; i <= after; i++) {
			sb.append("<li class='page-item'><a class='page-link' href='javascript:gotoPage(" + (page + i) + ")'>"
					+ (page + i) + "</a></li>");
		}

		sb.append("<li class='page-item " + (endFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.getNextPage() + ")'>&gt;</a></li>");
		sb.append("<li class='page-item " + (endFlag ? "disabled" : "")
				+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.getMaxPage() + ")'>尾页</a></li>");
		sb.append(
				"<li class='page-item go-input'><b>到第</b><input class='page-link' type='text' id='skipPage' name='' /><b>页</b></li>");
		sb.append("<li class='page-item go'><a class='page-link' href='javascript:skipPage()'>确定</a></li>");
		sb.append("<li class='page-item'><b>共" + pageBean.getTotal() + "条</b></li>");
		sb.append("</ul>");

		// 拼接分页的js代码
		sb.append("<script type='text/javascript'>");
		sb.append("function gotoPage(page) {");
		sb.append("document.getElementById('pageBeanForm').page.value = page;");
		sb.append("document.getElementById('pageBeanForm').submit();");
		sb.append("}");
		sb.append("function skipPage() {");
		sb.append("var page = document.getElementById('skipPage').value;");
		sb.append("if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > " + max + ") {");
		sb.append("alert('请输入1~N的数字');");
		sb.append("return;");
		sb.append("}");
		sb.append("gotoPage(page);");
		sb.append("}");
		sb.append("</script>");

		return sb.toString();
	}
}

 

四、编写前端代码

1. 数据显示主界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>	
<%@taglib uri="http://jsp.ycxw.cn" prefix="w" %>	
<!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">
<link
	href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
	rel="stylesheet">
<script
	src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍列表</title>
<style type="text/css">
.page-item input {
	padding: 0;
	width: 40px;
	height: 100%;
	text-align: center;
	margin: 0 6px;
}

.page-item input, .page-item b {
	line-height: 38px;
	float: left;
	font-weight: 400;
}

.page-item.go-input {
	margin: 0 10px;
}
</style>
</head>
<body>
<c:if test="${empty books }">
<jsp:forward page="/BookServlet"></jsp:forward>
</c:if>
	<form class="form-inline"
		action="${pageContext.request.contextPath }/book.action?methodName=list" method="post">
		<div class="form-group mb-2">
			<input type="text" class="form-control-plaintext" name="bname" placeholder="请输入书籍名称">
				<input name="pagination" value="false" type="hidden">
		</div>
		<button type="submit" class="btn btn-primary mb-2">查询</button>
		<a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/book.action?methodName=toEdit">新增</a>
	</form>

	<table class="table table-striped">
		<thead>
			<tr>
				<th scope="col">书籍ID</th>
				<th scope="col">书籍名</th>
				<th scope="col">价格</th>
				<th scope="col">操作</th>
			</tr>
		</thead>
		<tbody>
			<c:forEach  var="b" items="${books }">
			<tr>
				<td>${b.bid }</td>
				<td>${b.bname }</td>
				<td>${b.price }</td>
				<td>
					<a href="${pageContext.request.contextPath }/book.action?methodName=toEdit&bid=${b.bid}">修改</a>
					<a href="${pageContext.request.contextPath }/book.action?methodName=delete&bid=${b.bid}">删除</a>
				</td>
			</tr>
			</c:forEach>
		</tbody>
	</table>
	<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
	<w:page pageBean="${pageBean }"></w:page>
</body>
</html>

2. 默认运行显示所有数据servlet

package com.zking.web;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.sendRedirect(request.getContextPath()+"/book.action?methodName=list");
	}

}

3. 新增、修改共用页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://jsp.ycxw.cn" prefix="z"%>	
<%@ 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">
<link
	href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
	rel="stylesheet">
<script
	src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>书籍新增/修改</title>
</head>
<body>
	<form class="form-inline"
		action="${pageContext.request.contextPath }/book.action?methodName=${empty b ? 'add' : 'edit'}" method="post">
		书籍ID:<input type="text" name="bid" value="${b.bid }"><br>
		书籍名称:<input type="text" name="bname" value="${b.bname }"><br>
		书籍价格:<input type="text" name="price" value="${b.price }"><br>
		<input type="submit">
	</form>


</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/718772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决uni-app微信小程序底部输入框,键盘弹起时页面整体上移问题

存在问题 做了一个记录页面&#xff08;类似单方聊天页&#xff09;&#xff0c;输入框在底部&#xff1b;当弹出键盘时&#xff0c;页面整体上移&#xff0c;页面头信息会消失不见 需要实现效果&#xff1a; 比如一个记录页面&#xff0c;需要在键盘弹出时&#xff1a; 底…

解析ASEMI代理海矽美快恢复二极管SFP6012A的性能与应用

编辑-Z 在电子元件领域&#xff0c;快恢复二极管是一种重要的半导体器件&#xff0c;它在电路中起到关键的保护和控制作用。今天&#xff0c;我们将重点介绍一款优秀的快恢复二极管——SFP6012A&#xff0c;深入探讨其性能特点和应用领域。 一、SFP6012A快恢复二极管的性能特点…

chatglm docker镜像,一键部署chatglm本地知识库

好久没有写文章了&#xff0c;今天有空&#xff0c;记录一下chatglm本地知识库的docker镜像制作过程。 核心程序是基于“闻达”开源项目&#xff0c;稍作改动。 制作镜像&#xff1a; docker tag chatglm:v1 ch1949/chatglm:latest docker push ch1949/chatglm:latest 使用 …

性能测试小白‘壁咚’~~~

很多时候&#xff0c;我们都知道软件有黑白盒测试&#xff0c;但往往还遗漏掉了一个性能测试。 性能测试种类&#xff1a; 负载测试压力测试并发测试配置测试可靠性测试容量测试 1、负载测试 &#xff08;1&#xff09;定义 负载测试是指逐步增加系统负载&#xff0c;测试系统…

NSS [SWPUCTF 2021 新生赛]easy_md5

NSS [SWPUCTF 2021 新生赛]easy_md5 先看题目&#xff0c;md5弱比较&#xff0c;可以0e&#xff0c;数组&#xff0c;或者强碰撞。 payload&#xff1a; GET&#xff1a; ?name[]1 POST&#xff1a;password[]7

【面试系列】八股文之线程篇202306

union all和union的区别 union all&#xff1a;包含重复行 union&#xff1a;不包含重复行 线程池的shutdown()与shutdownNow()方法的区别 shutdown()&#xff0c;调用shutdown方法&#xff0c;线程池会拒绝接收新的任务&#xff0c;处理中的任务和阻塞队列中的任务会继续处…

redis基础及哨兵集群部署、故障切换

一、概述 Redis是一个开源的&#xff0c;使用C语言编写&#xff0c;支持网络&#xff0c;可基于内存工作亦可持久化&#xff08;AOF、RDB&#xff09;的日志型&#xff0c;key-values&#xff08;键值对&#xff09;数据库&#xff0c;一个速度极快的非关系型数据库&#x…

R语言APSIM模型及批量模拟

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。 APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物…

Python 数据类型转换

文章目录 每日一句正能量前言隐式类型转换实例实例 显式类型转换实例实例实例实例 每日一句正能量 在人生的道路上&#xff0c;即使一切都失去了&#xff0c;只要一息尚存&#xff0c;你就没有丝毫理由绝望。因为失去的一切&#xff0c;又可能在新的层次上复得。 前言 有时候&…

HOT41-二叉树的层序遍历

leetcode原题链接&#xff1a;二叉树的层序遍历 题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&…

redis如何实现持久化

RDB快照 RDB是一种快照存储持久化方式&#xff0c;具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中&#xff0c;默认保存的文件名为dump.rdb&#xff0c;而在Redis服务器启动时&#xff0c;会重新加载dump.rdb文件的数据到内存当中恢复数据。 开启RDB持久化方式 开启…

Vue生态及实践 - Vue Router(2)

目录 导航守卫 解析流程 代码演示 router.js pages/Foo.vue router/router.js router/history/base.js router/util/async.js router/components/RouterView.vue 接上一篇文章~&#xff0c;代码部分会有部分重叠&#xff0c;想看完整版的代码&#xff0c;看这篇文章的…

END-TO-END OPTIMIZED IMAGE COMPRESSION论文阅读

END-TO-END OPTIMIZED IMAGE COMPRESSION 文章目录 END-TO-END OPTIMIZED IMAGE COMPRESSION单词重要不重要 摘要&#xff1a; 单词 重要 image compression 图像压缩 quantizer 量化器 rate–distortion performance率失真性能 不重要 a variant of 什么什么的一个变体 …

大数据之flink容错机制

大数据之flink容错机制https://blog.51cto.com/dashujutongmeng/5241407

Spring Batch 批处理框架

一、SpringBatch 介绍 Spring Batch 是一个轻量级、全面的批处理框架&#xff0c;旨在支持开发对企业系统的日常操作至关重要的健壮的批处理应用程序。Spring Batch 建立在人们期望的 Spring Framework 特性&#xff08;生产力、基于 POJO 的开发方法和一般易用性&#xff09;…

从零开始 Spring Boot 60:一个实体映射到多个表

从零开始 Spring Boot 60&#xff1a;一个实体映射到多个表 图源&#xff1a;简书 (jianshu.com) 在之前的文章中我们讨论了 JPA 中的一对一关系&#xff0c;实际上存在一种特殊的一对一关系&#xff0c;即将一个实体映射到多张表&#xff0c;本文会讨论这种关系。 我之前提过…

elementui实现表格自定义排序

需求说明&#xff1a; 1、第一行不参与排序 2、实现带%排序 3、实现null值排序 4、实现值相等不排序 5、实现含有占位符‘–‘排序放到最后 效果图如下&#xff1a; <template> <div><template><el-table border :data"previewTableData" style…

ROS学习之从yaml文件中读取多传感器坐标系之间的静态TF关系并发布Topic

文章目录 0 引言1 工作空间创建并初始化2 创建ROS程序包3 创建yaml读取函数3.1 yaml文件3.2 读取函数 4 创建静态TF关系的发布主函数5 创建launch文件6 编辑CMakeLists.txt7 编译运行7.1 编译7.2 运行 0 引言 机器人中经常使用多种传感器来做定位和建图&#xff0c;而多个传感…

找出一个List中每个元素出现的次数

文章目录 一、需求&#xff1a;找出一个list中&#xff0c;每个元素出现的次数1. 普通实现&#xff08;hashmap&#xff09;&#xff1a;1.1 代码实现&#xff1a;1.2运行结果&#xff1a;1.3 案例分析&#xff1a; 2. 普通实现&#xff08;HashSet#Collections.frequency&…

Flask学习笔记(2)应用部署

本文将介绍如何部署Flask应用。   部署Flask应用&#xff0c;主要是要运用多线程与多进程&#xff0c;提高接口的并发能力。我们以下面的Python代码&#xff08;server.py&#xff09;为例进行演示&#xff1a; # -*- coding: utf-8 -*- import time import datetime from f…