Java研学-三层架构实现简单登录操作

一 登录流程

登录流程
  将服务器资源给有权限的人访问,只有登录的管理员可以访问员工信息进行 CRUD

二 三层架构

  Web 开发中的最佳实践:分层开发模式将整个业务应用划分为:表现层、业务逻辑层、数据访问层。区分层次的目的即为了“高内聚低耦合”的思想。
  表现层(Predentation Layer):MVC,负责处理与界面交互的相关操作。
  业务层(Business Layer):Service,负责复杂的业务逻辑计算和判断。
  持久层(Persistent Layer):DAO,负责将业务逻辑数据进行持久化存储。

三 代码实现

1 数据库表

管理员表

CREATE TABLE `users` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(255) DEFAULT NULL,`password` varchar(255) DEFAULT NULL,`headImg` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO user(username, password,headImg) VALUES('yellow', '111111','null');

员工信息表

CREATE TABLE `employee` (`id` bigint(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) DEFAULT NULL,`salary` double(10,2) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;
INSERT INTO employee(name, salary) VALUES('kai', '6379');

2 创建实体类

Users

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Users {private  Long id;private  String username;private  String password;private  String headImg;
}

Employee

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {private Long id;private String name;private Double salary;
}

3 创建对应的mapper文件

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tj.mapper.UserMapper"><!--根据账号查询--><select id="queryByUsername" resultType="Users">SELECT * from users WHERE username=#{username}</select><!--修改头像--><update id="updateImg">update users set headImg =#{headImg} WHERE id=#{id}</update>
</mapper>

EmployeeMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tj.mapper.EmployeeMapper"><!--增加商品--><insert id="add">insert into employee (name,salary)values(#{name},#{salary})</insert><!--修改--><update id="update">update employee set name=#{name},salary=#{salary}WHERE id=#{id}</update><!--删除--><delete id="delete">delete from employee WHERE id=#{id}</delete><!--根据id查询--><select id="selectOne" resultType="Employee">SELECT * from employee WHERE id=#{id}</select><!--查询所有--><select id="list" resultType="Employee">SELECT * from employee</select><!--查询总条数--><select id="queryCount" resultType="int">SELECT count(*) from employee</select><!--分页查询--><select id="queryPage" resultType="Employee">SELECT * from employee limit #{start},#{pageSize}</select>
</mapper>

4 创建resources文件

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///play_web
jdbc.user=root
jdbc.password=root

log4j.properties

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.cn.tj=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"></properties><typeAliases><package name="cn.tj.domain"/></typeAliases><environments default="dev"><environment id="dev"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.user}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><mapper resource="mappers/EmployeeMapper.xml"></mapper><mapper resource="mappers/UserMapper.xml"></mapper></mappers>
</configuration>

5 创建Dao层接口

UserDao

public interface UserDao {//根据账号查询Users queryByUsername(String username);//修改头像int updateImg(Users users);
}

EmployeeDao

public interface EmployeeDao {/*增加*/int add(Employee employee);/*修改*/int update(Employee employee);/*删除*/int delete(Long id);/*查询所有*/List<Employee> list();/*根据id查询*/Employee selectOne(Long id);/*查询总条数*/int queryCount(QueryObject qo);/*分页查询*/List<Employee> queryPage(QueryObject qo);
}

6 创建Dao层实现类

UserDaoImpl

public class UserDaoImpl implements UserDao {private SqlSession sqlSession= MybatisUtil.getSqlSession();@Overridepublic Users queryByUsername(String username) {return sqlSession.selectOne("cn.tj.mapper.UserMapper.queryByUsername", username);}@Overridepublic int updateImg(Users users) {return sqlSession.update("cn.tj.mapper.UserMapper.updateImg",users);}
}

EmployeeDaoImpl

public class EmployeeDaoImpl implements EmployeeDao {/*定义成员变量*/private SqlSession sqlSession= MybatisUtil.getSqlSession();@Overridepublic int add(Employee employee) {int row = sqlSession.insert("cn.tj.mapper.EmployeeMapper.add", employee);return row;}@Overridepublic int update(Employee employee) {int row= sqlSession.update("cn.tj.mapper.EmployeeMapper.update",employee);return row;}@Overridepublic int delete(Long id) {int row= sqlSession.delete("cn.tj.mapper.EmployeeMapper.delete",id);return row;}@Overridepublic List<Employee> list() {List<Employee> list = sqlSession.selectList("cn.tj.mapper.EmployeeMapper.list");return list;}@Overridepublic Employee selectOne(Long id) {Employee employee= sqlSession.selectOne("cn.tj.mapper.EmployeeMapper.selectOne", id);return employee;}@Overridepublic int queryCount(QueryObject qo) {return sqlSession.selectOne("cn.tj.mapper.EmployeeMapper.queryCount",qo);}@Overridepublic List<Employee> queryPage(QueryObject qo) {return sqlSession.selectList("cn.tj.mapper.EmployeeMapper.queryPage",qo);}
}

7 编写登录 Servlet

UserServlet

@WebServlet("/user")
@MultipartConfig
public class UserServlet extends HttpServlet {private UserService userService =new UserServiceImpl();@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");String cmd = req.getParameter("cmd");if ("login".equals(cmd)){login(req,resp);//登录}else if("logout".equals(cmd)){logout(req,resp);//退出登录}else if("updateImg".equals(cmd)){updateImg(req,resp);}}/*修改头像*/private void updateImg(HttpServletRequest req, HttpServletResponse resp) {try {//上传新图片Part part = req.getPart("headImg");String path=getServletContext().getRealPath("/upload") +"/";String headImg = UploadUtil.uploadImg(req, resp, part,path);//获取登录账号对象HttpSession session = req.getSession();Users user= (Users) session.getAttribute("USER_IN_SESSION");//修改头像user.setHeadImg(headImg);//保存新头像名称userService.updateImg(user);//把session中的对象更新一下session.setAttribute("USER_IN_SESSION",user);//修改完毕跳转查询商品resp.sendRedirect("/employee");} catch (Exception e) {e.printStackTrace();}}/*退出登录*/private void logout(HttpServletRequest req, HttpServletResponse resp) {try {//获取sessionHttpSession session = req.getSession();
//            session.invalidate();//销毁sessionsession.removeAttribute("username");//跳转到登录页面resp.sendRedirect("login.jsp");} catch (IOException e) {e.printStackTrace();}}/*用户登录*/private void login(HttpServletRequest req, HttpServletResponse resp) {try {//获取表单的参数String username = req.getParameter("username");String password = req.getParameter("password");//调用业务层登录方法Users users = userService.login(username, password);//账号密码正确:登录成功,将登录账号显示到商品的列表页面HttpSession session = req.getSession();session.setAttribute("USER_IN_SESSION",users);resp.sendRedirect("/employee");} catch (Exception e) {try {req.setAttribute("msg",e.getMessage());req.getRequestDispatcher("/login.jsp").forward(req,resp);} catch (Exception ex) {ex.printStackTrace();}}}
}

8 编写登录页面

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>登录</title>
</head>
<body>
<h3>用户登录</h3>
<form action="/user?cmd=login" method="post"><%--登录错误提示--%><span style="color: red">${msg}</span><p>账号:<input type="text" name="username"></p><p>密码:<input type="password" name="password"></p><p><input type="submit" value="登录"></p>
</form>
</body>
</html>

9 登录后跳转操作员工信息

EmployeeServlet

@WebServlet("/employee")
public class EmployeeServlet extends HttpServlet {private EmployeeService employeeService=new ProductServiceImpl();@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置编码格式req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");// 登录权限判断 操作员工需要先登录HttpSession session = req.getSession();Users users = (Users) session.getAttribute("USER_IN_SESSION");if (users==null){//如果没有登录,跳转登录页面,给出提示req.setAttribute("msg","请先登录再操作!");req.getRequestDispatcher("/login.jsp").forward(req,resp);return;}//获取请求分发的参数String cmd = req.getParameter("cmd");if ("delete".equals(cmd)){//调用删除delete(req,resp);}else if("input".equals(cmd)){//跳转到增加或修改页面input(req,resp);} else if("saveOrUpdate".equals(cmd)){//保存增加或修改商品saveOrUpdate(req,resp);}else{//查询所有list(req,resp);}}/*增加修改保存*/private void saveOrUpdate(HttpServletRequest req, HttpServletResponse resp) {//封装员工对象Employee employee=new Employee();/*将参数的获取及封装对象过程抽取成一个方法*/req2product(req,employee);/*根据请求中是否携带id判断执行增加或者修改操作*/String id = req.getParameter("id");if (StringUtil.hasLength(id)){employee.setId(Long.valueOf(id));//执行修改employeeService.update(employee);}else{//调用dao方法执行增加保存操作employeeService.add(employee);}try {//跳转到查询resp.sendRedirect("/employee");} catch (IOException e) {e.printStackTrace();}}/*封装的获取请求参数的方法*/private void req2product(HttpServletRequest req, Employee employee) {//获取请求中表单参数String name = req.getParameter("name");//验证输入的表单参数不能为空if (StringUtil.hasLength(name)){//编辑员工姓名employee.setName(name);}String salary = req.getParameter("salary");if (StringUtil.hasLength(salary)){employee.setSalary(Double.valueOf(salary));}}/*跳转到编辑页面*/private void input(HttpServletRequest req, HttpServletResponse resp) {//根据请求中是否携带id判断是增加或者修改操作String id = req.getParameter("id");if (StringUtil.hasLength(id)){//请求中携带了id执行修改//根据id查询员工Employee employee = employeeService.selectOne(Long.valueOf(id));//将查询的员工存储到作用域req.setAttribute("employee",employee);}try {//跳转到WEB-INF下面的页面:input.jspreq.getRequestDispatcher("/WEB-INF/views/employee/input.jsp").forward(req,resp);} catch (Exception e) {e.printStackTrace();}}/*分页查询所有*/private void list(HttpServletRequest req, HttpServletResponse resp) {try {/*客户端如果传入了当前页码和每页显示条数则设置给qo对象,如果没有传入则使用默认值*/String currentPage = req.getParameter("currentPage");String pageSize = req.getParameter("pageSize");QueryObject qo=new QueryObject();if (StringUtil.hasLength(currentPage)){qo.setCurrentPage(Integer.valueOf(currentPage));}if (StringUtil.hasLength(pageSize)){qo.setPageSize(Integer.valueOf(pageSize));}//调用service分页查询的方法PageResult<Employee> pageResult = employeeService.queryByPage(qo);//将查询的结果存储到请求作用域req.setAttribute("pageResult",pageResult);//转发到列表页面req.getRequestDispatcher("/WEB-INF/views/employee/list.jsp").forward(req,resp);} catch (Exception e) {e.printStackTrace();}}/*删除*/private void delete(HttpServletRequest req, HttpServletResponse resp) {try {//获取目标idString id = req.getParameter("id");//调用删除方法int row = employeeService.delete(Long.valueOf(id));//删除完毕跳转到查询resp.sendRedirect("/employee");} catch (IOException e) {e.printStackTrace();}}
}

10 展示与编辑员工页

input.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>员工编辑页面</title>
</head>
<body>
<h3>员工编辑</h3>
<form action="/employee?cmd=saveOrUpdate" method="post"><input type="hidden" name="id" value="${employee.id}"><p>姓名:<input type="text" name="name" value="${employee.name}"></p><p>工资:<input type="number" name="salary" step="0.01" value="${employee.salary}"></p><p><input type="submit" value="保存"></p>
</form>
</body>
</html>

list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入核心标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>员工信息页面</title>
</head>
<body>
<center><h3>员工列表</h3><p>当前登录账号:${sessionScope.USER_IN_SESSION.username}</p><p><%--点击跳转到上传头像的表单页面--%><a href="/headImg.jsp"><%--头像--%><img src="/upload/${sessionScope.USER_IN_SESSION.headImg}" width="100px" height="100px"><p>${sessionScope.USER_IN_SESSION.headImg}</p></a></p><p><a href="/employee?cmd=input">增加员工</a></p><p><a href="/user?cmd=logout">退出登录</a></p><%--分页跳转的表单--%><form action="/employee" method="post"><table border="1px" cellpadding="0" cellspacing="0"width="800px"><thead><tr><th>序号</th><th>姓名</th><th>工资</th><th>操作</th></tr></thead><tbody><%--动态展示员工列表数据--%><c:forEach items="${pageResult.list}" varStatus="vs" var="employee"><tr class="trClass"><td>${vs.count}</td><td>${employee.name}</td><td>${employee.salary}</td><td><a href="/employee?cmd=input&id=${employee.id}">修改员工信息</a>&nbsp;&nbsp;<%--                    <a href="/employee?cmd=delete&id=${employee.id}">删除员工信息</a>--%><a href="#" onclick="deleteTr(${employee.id})">删除员工信息</a></td></tr></c:forEach></tbody><tfoot><tr align="center"><td colspan="9"><a href="/employee?currentPage=1&pageSize=${pageResult.pageSize}">首页</a>&nbsp;&nbsp;<a href="/employee?currentPage=${pageResult.prevPage}&pageSize=${pageResult.pageSize}">上一页</a>&nbsp;&nbsp;<a href="/employee?currentPage=${pageResult.nextPage}&pageSize=${pageResult.pageSize}">下一页</a>&nbsp;&nbsp;<a href="/employee?currentPage=${pageResult.totalPage}&pageSize=${pageResult.pageSize}">末页</a>&nbsp;&nbsp;当前是第 ${pageResult.currentPage}/${pageResult.totalPage}&nbsp;&nbsp;一共${pageResult.totalCount}条数据&nbsp;&nbsp;跳转到第<input type="text" name="currentPage" value="${pageResult.currentPage}"onchange="changePagesize()" style="width: 50px">&nbsp;&nbsp;每页<select name="pageSize" onchange="changePagesize()"><option value="3" ${pageResult.pageSize==3?'selected':''}>3</option><option value="6" ${pageResult.pageSize==6?'selected':''}>6</option><option value="9" ${pageResult.pageSize==9?'selected':''}>9</option></select>条数据&nbsp;&nbsp;</td></tr></tfoot></table></form>
</center><%--鼠标移动到当前行,实现背景颜色高亮显示--%>
<script>//获取所有的行元素:不包含表头var trs = document.getElementsByClassName("trClass");//遍历行元素集合for(var i=0;i<trs.length;i++){//鼠标移入:当前行高亮,背景变成灰色trs[i].onmouseover=function (){this.style.backgroundColor="gray";}//鼠标移出:恢复原来背景颜色trs[i].onmouseout=function (){this.style.backgroundColor="";}}
</script><%--删除确认表--%>
<script>function deleteTr(id){//确认删除var b= window.confirm("确定要删除选中的员工信息吗?");if(b){//确定删除,执行后台删除操作window.location="/employee?cmd=delete&id="+id;}}
</script><%--分页表单提交函数--%>
<script>function changePagesize(){document.forms[0].submit();}
</script>
</body>
</html>

headImg.jsp – 修改头像

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>头像上传</title>
</head>
<body>
<h3>修改头像</h3>
<form action="/user?cmd=updateImg" method="post" enctype="multipart/form-data"><p>头像:<input type="file" name="headImg"></p><p><input type="submit" value="提交"></p>
</form>
</body>
</html>

11 service层接口

UserService

public interface UserService {//登录方法public Users login(String username, String password);//修改头像public int updateImg(Users users);
}

EmployeeService

public interface EmployeeService {/*增加*/int add(Employee employee);/*修改*/int update(Employee employee);/*删除*/int delete(Long id);/*查询所有*/List<Employee> list();/*根据id查询*/Employee selectOne(Long id);/*分页查询*/PageResult<Employee> queryByPage(QueryObject qo);
}

12 service实现类

UserServiceImpl

public class UserServiceImpl implements UserService {private UserDao userDao=new UserDaoImpl();@Overridepublic Users login(String username, String password) {Users users = userDao.queryByUsername(username);//判断账号if(users==null){//账号错误throw new RuntimeException("账号错误");}//判断密码if(!users.getPassword().equals(password)){//密码错误throw new RuntimeException("密码错误");}return users;}@Overridepublic int updateImg(Users users) {int row = userDao.updateImg(users);return row;}
}

ProductServiceImpl

public class ProductServiceImpl implements EmployeeService {private EmployeeDao employeeDao=new EmployeeDaoImpl();@Overridepublic int add(Employee employee) {return employeeDao.add(employee);}@Overridepublic int update(Employee employee) {return employeeDao.update(employee);}@Overridepublic int delete(Long id) {return employeeDao.delete(id);}@Overridepublic List<Employee> list() {return employeeDao.list();}@Overridepublic Employee selectOne(Long id) {return employeeDao.selectOne(id);}/*分页查询*/@Overridepublic PageResult<Employee> queryByPage(QueryObject qo) {//查询总条数int totalCount = employeeDao.queryCount(qo);if(totalCount==0){return new PageResult<>(qo.getCurrentPage(),qo.getPageSize(),0, Collections.emptyList());}//查询分页商品集合List<Employee> list = employeeDao.queryPage(qo);//创建分页对象PageResult<Employee> pageResult=new PageResult<>(qo.getCurrentPage(),qo.getPageSize(),totalCount,list);return pageResult;}
}

13 分页QO

QueryObject

@Setter
@Getter
public class QueryObject {private Integer currentPage=1;private Integer pageSize=3;public int getStart(){return   (currentPage-1)*pageSize;//计算查询的起始索引}
}

14 所需的工具类

MybatisUtil

public class MybatisUtil {private static  SqlSessionFactory factory=null;static {try {InputStream rs = Resources.getResourceAsStream("mybatis-config.xml");factory = new SqlSessionFactoryBuilder().build(rs);} catch (IOException e) {e.printStackTrace();}}public static SqlSession getSqlSession(){return factory.openSession(true);}
}

PageResult

@Setter
@Getter
public class PageResult<T> {//上一页private  Integer prevPage;//下一页private  Integer nextPage;//总条数private  Integer totalCount;//总页数private Integer totalPage;//当前页码private Integer currentPage;//每页显示条数private Integer pageSize;//查询的集合private List<T> list;/*初始化分页对象有参构造*/public  PageResult(Integer currentPage,Integer pageSize,Integer totalCount,List<T> list){this.currentPage=currentPage;this.pageSize=pageSize;this.totalCount=totalCount;this.list=list;//总页数=总条数/每页显示条数 当求模运算值不等于0的时候总页数加1this.totalPage=(this.totalCount%this.pageSize==0)?(this.totalCount/this.pageSize):(this.totalCount/this.pageSize+1);//上一页this.prevPage=(this.currentPage==1)?(1):(this.currentPage-1);//下一页this.nextPage=(this.currentPage==this.totalPage)?(this.totalPage):(this.currentPage+1);}
}

StringUtil

public class StringUtil {public static boolean hasLength(String s){//判断输入的表单参数是否为空return s!=null && s.trim().length()!=0;}
}

UploadUtil

public class UploadUtil {public static String uploadImg(HttpServletRequest req, HttpServletResponse resp,Part part,String path){try {//上传文件的类型String contentType = part.getContentType();if (!contentType.startsWith("image")){//上传的不是图片,页面给出提示req.setAttribute("errorMsg","上传的文件必须是图片!");req.getRequestDispatcher("register.jsp").forward(req,resp);return null;}//获取文件的名称:pic.pngString fileName = part.getSubmittedFileName();//获取源文件类型或后缀名String type= fileName.substring(fileName.lastIndexOf("."));String s = UUID.randomUUID().toString().replace("-","");//使用uuid生成32位随机字符//设置新的文件名称String newfilename=s+type;//设置上传的目标目录地址
//            String path="D:\\java\\upload\\";//将上传的文件保存到目标地址part.write(path+newfilename);return newfilename;} catch (Exception e) {e.printStackTrace();}return null;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计-----SSH校园精品课程网前后台

项目介绍 本项目是很不错的一个校园精品课程网源码&#xff0c;前台和后台源码都有&#xff0c;分为管理员与学生两种角色&#xff1b; 前台功能&#xff1a;网站首页&#xff0c;校园新闻&#xff0c;课程中心&#xff0c;资源下载&#xff0c;互动交流&#xff0c;个人中心…

树状结构查询 - 华为OD统一考试

OD统一考试 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 通常使用多行的节点、父节点表示一棵树&#xff0c;比如&#xff1a; 西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲 输入一个节点之后&#xff0c;请打印出来树中他的所有下层节点。 …

删除sys_file表中的文件信息后同步操作表单中对应的文件字段信息

需求&#xff1a;由于系统的表单文件上传/删除操作与表单的保存操作不同时进行&#xff0c;所以需要调整 细节&#xff1a;&#xff08;某个表&#xff1a;A表&#xff09;表单的文件字段只是保存了上传文件的id&#xff0c;名称&#xff0c;真正的文件保存是保存在一个系统的文…

Retrieval-Augmented Generation for Large Language Models: A Survey

PS: 梳理该 Survey 的整体框架&#xff0c;后续补充相关参考文献的解析整理。本文的会从两个角度来分析总结&#xff0c;因此对于同一种技术可能在不同章节下都会有提及。第一个角度是从整体框架的迭代来看&#xff08;对应RAG框架章节&#xff09;&#xff0c;第二个是从RAG中…

转专业(UPC练习)

题目描述 根据教育部的规定&#xff0c;大学生进校后符合条件的可申请转专业。在校本科生在完成大学一年级课程&#xff0c;进入二年级之前&#xff0c;符合以下条件之一者&#xff0c;可以申请转专业&#xff1a;&#xff08;1&#xff09;在某一学科方面确有特长的学生&#…

IPv6路由协议---IPv6动态路由(OSPFv3-5)

OSPFv3各链路状态通告类型 4.Inter-Area-Router-LSA区域间路由器(4类LSA) 边界路由器(ABR)产生的第4类LSA,在Area 范围内泛洪,描述了到本AS内其他区域的ASBR路由器信息; 每各Inter-Area-Router-LSA包含一个ASBR路由器信息,LSA中的能力选项(Options)与所描述的ASBR …

【模块系列】STM32TCS3472

前言 手上正好有TCS3472模块&#xff0c;也正好想在加深一下自己对I2C协议的理解和应用&#xff0c;所以就写了这个代码库出来。参考的资料主要来源于TCS3472的数据手册&#xff0c;和arduino中MH_TCS3472库的宏定义&#xff0c;和函数名称&#xff0c;我就没有重新命名&#x…

【System Verilog and UVM实力进阶2】SVA语法

毛主席说过&#xff1a;没有调查就没有发言权。 《SVA介绍——学习SVA语法》系列第二讲 本文还是延续上一篇的风格&#xff0c;语言内容尽可能简单明了&#xff0c;有问题大家相互讨论&#xff0c;共同进步。需要电子书的朋友可以给我发邮件。tommi.weiqq.com 1.16 "ended…

Spring MVC 参数接收

参数接收 Springmvc中&#xff0c;接收页面提交的数据是通过方法形参来接收&#xff1a; 处理器适配器调用springmvc使用反射将前端提交的参数传递给controller方法的形参 springmvc接收的参数都是String类型&#xff0c;所以spirngmvc提供了很多converter&#xff08;转换器…

光鉴科技的反卷思维,让科技不再难做

文 | 智能相对论 作者 | 陈壹 中国企业的全球竞争力&#xff0c;正从“拼人力、拼产能”转为“拼技术、拼创新”的新阶段。据世界知识产权组织发布的《世界知识产权指标报告》显示&#xff0c;2022年中国专利申请量约160万件&#xff0c;排名世界第一。而在最近发布的全球百强…

MySQL:索引失效场景总结

1 执行计划查索引 通过执行计划命令可以查看查询语句使用了什么索引。 EXPLAIN SELECT * FROM ods_finebi_area WHERE areaName = 福建 执行查询计划后,key列的值就是被使用的索引的名称,若key列没有值表示查询未使用索引。 2 在什么列上创建索引 (1)列经常被用于where…

网络安全B模块(笔记详解)- nmap扫描渗透测试

nmap扫描渗透测试 1.通过BT5对服务器场景Linux进行TCP同步扫描 (使用工具Nmap,使用参数n,使用必须要使用的参数),并将该操作使用命令中必须要使用的参数作为Flag提交; Flag:sS 2.通过BT5对服务器场景Linux进行TCP同步扫描 (使用工具Nmap,使用参数n,使用必须要使用的参数…