- 8.接下来配置扫描器,将mybatis接口的实现加入到ioc容器中
<property name=“sqlSessionFactoryBeanName”
value=“SqlSessionFactoryBean” />
- 9.接下来进行实物控制的配置
- 10.开启事务:
开启基于注解的事务,使用xml的形式的事务(比较重要的事务都会用xml配置的方式)
<bean id=“DataSourceTransactionManager”
class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”>
aop:config
<aop:pointcut
expression=“execution(* com.service…*(…))” id=“txPoint” />
<aop:advisor advice-ref=“txAdvice” pointcut-ref=“txPoint” />
</aop:config>
<tx:advice id=“txAdvice” transaction-manager=“DataSourceTransactionManager”>
tx:attributes
<tx:method name=“*” />
<tx:method name=“get*” read-only=“true” />
</tx:attributes>
</tx:advice>
============================================================================
-
1.先在po中创建对应的bean
-
2.在mapper中创建mapper接口;(就举一个例子:在mapper中创建EmpMapper接口:
public interface EmpMapper {
public List getEmpInfo();
}
- 3.在resource的mapper中创建对应的xml文件;EMpMapper.xml文件;
select * from tbl_emp
=============================================================================
- 1.如果不放心,可以在test文件中创建一个测试类
public static void main(String[] args) {
//1.创建springIoc容器/ssmProject/src/main/
ApplicationContext ioc=new ClassPathXmlApplicationContext(“…/…/resources/conf/spring.xml”);
//2,从容器中获取mapper
EmpMapper bean=ioc.getBean(EmpMapper.class);
List lemp=bean.getEmpInfo();
if(lemp.size()>=1) {
for(Emp e:lemp) {
System.out.println(e.getEmp_name()+“=”+e.getEamil());
}
}
}
- 2也可以进行单元测试:
1.先在pom.xml中导入spring test 这一单元测试类
2.在这个测试类上添加注解
/帮我们创建容器
@RunWith(SpringJUnit4ClassRunner.class)
//指定创建容器时使用哪个配置文件
@ContextConfiguration(locations= {“classPath:spring.xml”})
3.需要哪一个组件直接使用注解@Autowired进行自动装载(注:这个自动装载必须写在方法外面)
@Autowired
EmpMapper empMapper;
4.需要测试哪一个方法就在这个方法上面添加注解@Test,测试的详细代码如下:
//帮我们创建容器
@RunWith(SpringJUnit4ClassRunner.class)
//指定创建容器时使用哪个配置文件
@ContextConfiguration(locations = { “classpath:conf/spring.xml” })
public class Test1 {
@Autowired
EmpMapper empMapper;
@Test
public void testEmpMaaper() {
List lEmps = empMapper.getEmpInfo();
System.out.println(lEmps.size());
if (lEmps.size() >= 1) {
for (Emp em : lEmps) {
System.out.println(em.getEmp_name() + “=” + em.getEamil());
}
}
}
}
- 3.为了方便操作,我们要在spring.xml文件中进行配置一个可以批量执行的sqlSession
//此处的SqlSessionFactoryBean对应的是157行的SqlSessionFactoryBean
- 4.在刚刚我们创建的测试类中写测试语句,但是在写测试语句之前必须编写对应的mapper文件:
EmpMapper:
public interface EmpMapper {
public List getEmpInfo();
public void updateEmpById(Emp emp);
}
EmpMapper:对应的emp.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>select * from tbl_emp
update tbl_emp
emp_name=#{emp_name},
gender=#{gender},
eamil=#{eamil},
dept_id=#{dept_id},
where emp_id=#{emp_id}
测试语句:
//帮我们创建容器
@RunWith(SpringJUnit4ClassRunner.class)
//指定创建容器时使用哪个配置文件
@ContextConfiguration(locations = { “classpath:conf/spring.xml” })
public class Test1 {
@Autowired
EmpMapper empMapper;
@Autowired
SqlSession sqlSession;
//用于查询
@Test
public void getEmpInfo() {
List lEmps = empMapper.getEmpInfo();
System.out.println(lEmps.size());
if (lEmps.size() >= 1) {
for (Emp em : lEmps) {
System.out.println(em.getEmp_name() + “=” + em.getEamil());
}
}
}
//用于更新
@Test
public void updateEmpById() throws IOException {
Emp m = new Emp(1,“zx”, “female”, “123@qq.com”, 1);
EmpMapper empMapper=sqlSession.getMapper(EmpMapper.class);
empMapper.updateEmpById(m);
}
//用于批量的插入数据
@Test
public void insertDeptByBATCH() {
DeptMapper OCM=sqlSession.getMapper(DeptMapper.class);
for(int i=0;i<10;i++) {
String id=UUID.randomUUID().toString().substring(0, 5);
OCM.insertByDept(new Dept(id));
}
}
}
注:对应的bean的构造方法没有添加,请自己添加
===========================================================================
-
1.主页面的执行流程:访问Index.jsp页面->index.jsp页面发送出查询信息列表的请求->EmpController来接受请求,然后查询出员工数据->跳转到list,jsp页面进行展示
-
2.在index.jsp中创建的内容:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<jsp:forward page=“/emp”></jsp:forward>
- 3.创建对应的控制器EmpController:
public class EmpController {
public String getAllEmpInfo() {
//我们有视图解析器所以返回的list,会自动给它添加前缀和后缀
return “list”;
}}
- 4.由于视图解析对应的地址是
所以先在/WEB-INF/view/目录下创建list,jsp:
- 5.开始向数据库取数据,具体步骤是:先创建service接口->在serviceImpl中来实现具体的接口->在controller层中调用这个接口即可;
<1>.创建EmpService:
public interface EmpService {
public List getALlEmpInfo();
}
<2>在serviceImpl中来实现具体的接口EmpServiceImpl:
public class EmpServiceImpl implements EmpService {
// service依赖于Dao
@Autowired
EmpMapper eMapper;
@Override
public List getALlEmpInfo() {
// TODO Auto-generated method stub
return eMapper.getEmpInfo();
}
}
但是如果数据较为庞大,每一次都查询所有的数据太过于繁琐,所以引入分页的组件PageHelper:
1.现在pom中引入pageHepler插件(直接在maven仓库中搜索pagehelper,选择对应的版本下载即可)
2.在mybatis的全局配置中注册分页组件:
3.引用组件也特别简单,只需要在查询之前调用PageHelper.startPage方法即可;
在EmpController的getAllEmpInfo()方法中调用,注意一定要写在查询之前,而且后面紧跟的这个查询就是分页查询;
接下来就对查询的分页结果进行包装,其中PageInfo中包含了这个页面的所有信息,所以只需要将pageInfo交给页面接收就行了:
PageInfo page=new PageInfo(lemp,5);//5:表示每次只显示5页的导航菜单
代码详情:
@Controller
public class EmpController {
@Autowired
EmpService empService;
//拦截emp请求
@RequestMapping(“/emp”)
public String getAllEmpInfo(@RequestParam(value=“pn”,defaultValue=“1” ) Integer pn) {
Map<String, Object> map = new HashMap<String, Object>();
//为了方便快速查询,所以引入PageHelper分页查询
//表示从第pn查,每一页显示5条数据
PageHelper.startPage(pn, 5);//后面紧跟的这个查询就是分页查询
List lemp=empService.getALlEmpInfo();
//将查询的分页结果进行包装,其中PageInfo中包含了这个页面的所有信息,所以只需要将pageInfo交给页面接受就行了
PageInfo page=new PageInfo(lemp,5);//5:表示每次只显示5页的导航菜单
map.put(“pageInfo”,page );
//我们有视图解析器所以返回的list,会自动给它添加前缀和后缀
return “list”;
}
}
=====================================================================================
- 1.创建一个单元测试类, 代码如下:
package com.test;
//@RunWith帮我们创建容器
//@ContextConfiguration指定创建容器时使用哪个配置文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { “classpath:conf/spring.xml”, “classpath:conf/spring-mvc.xml” })
@WebAppConfiguration
public class Test2 {
// 传入spring-mvc的ioc;
// 注:@Autowired只能装配IOC里面的,所以在上面添加了一个WebAppConfiguration注解,拿到web的ioc容器
@Autowired
WebApplicationContext context;
// 虚拟单元测试请求,获取处理结果
MockMvc mocMvc;
// 每次使用之前都要初始化一次,所以添加一个before注解
@Before
public void initMockMvc() {
// 只有先创建才能使用
mocMvc = MockMvcBuilders.webAppContextSetup(context).build();// 这个mocMvc就能模拟我的mvc请求
}
@Test
public void testPage() throws Exception {
// 模拟请求拿到返回值
MvcResult result = mocMvc.perform(MockMvcRequestBuilders.get(“/emp”).param(“pn”, “1”)).andReturn();
// 请求成功以后,请求域中会有pageInfo,那么我们就可以去取出进行验证
MockHttpServletRequest request = result.getRequest();
PageInfo pageInfo = (PageInfo) request.getAttribute(“pageInfo”);
System.out.println(“当前页码=” + pageInfo.getPageNum());
System.out.println(“总页码=” + pageInfo.getPages());
System.out.println(“总记录数=” + pageInfo.getTotal());
System.out.println(“在页面需要连续显示的页码=”);
int pageNu[] = pageInfo.getNavigatepageNums();
for (int nu : pageNu) {
System.out.print(nu + " ");
}
// 获取员工数据
List leEmps = pageInfo.getList();
for (Emp e : leEmps) {
System.out.println(e.toString());
}
}
}
========================================================================================
1.路径的问题:
-
1.web路径,不以/开始的相对路径,找资源,以当前文件为基准,特别容易出问题
-
2.web路径以/开始的相对路径,找资源,以服务器为基准(http://localhost:3306/weservice/)
也就是说在找资源时要加上http://localhost:3306/weservice/,但是为了避免是写错误或者麻烦,我们可以使用这种方法来自动获取路径:
<%
pageContext.setAttribute(“App_Path”, request.getContextPath());
%>
取值: A p p P a t h / 资 源 路 径 : 比 如 我 的 要 找 / s s m P r o j e c t / s r c / m a i n / w e b a p p / j s / j q u e r y 3 . 3.1. j s 文 件 , 那 么 就 可 以 直 接 写 : {App_Path}/资源路径: 比如我的要找/ssmProject/src/main/webapp/js/jquery_3.3.1.js文件,那么就可以直接写: AppPath/资源路径:比如我的要找/ssmProject/src/main/webapp/js/jquery3.3.1.js文件,那么就可以直接写:{App_Path}/js/jquery_3.3.1.js
2.由于所有的操作都是对list.jsp的操作,所以直接给出源码:
list.jsp文件:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
href=“https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css”>
SSM-CRUD
新增
删除
编辑
删除
- 首页
aria-hidden=“true”>«
- 1
- 2
- 3
- 4
- 5
aria-hidden=“true”>»
- 末页
-
=========================================================================
1.由于表格的行数都是根据后台数据自动产生,所以我们要使用遍历:目前推荐c:foreach语句:
使用此语句,先引入核心标签库:<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c” %>
注:如果报错,就先在pom中引入jstl标签库
javax.servlet
jstl
1.2
目前就只有这一个版本,不要引用错了
2.话不多说直接看代码:
同样是list.jsp文件“
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
员工列表 href=“https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css”>
<%
pageContext.setAttribute(“App_Path”, request.getContextPath());
%>
致一科技@Zhiyi Technology
新增
删除
emp_id emp_name gender eamil dept_id 操作
<c:forEach items=“${pageInfo.list }” var=“emp”>
${emp.emp_id} ${emp.emp_name} ${emp.gender} ${emp.eamil} ${emp.dept_id}编辑
删除
</c:forEach>
当前第${pageInfo.pageNum}页,总共 p a g e I n f o . p a g e s 页 , 共 {pageInfo.pages}页,共 pageInfo.pages页,共{pageInfo.total}条记录
- 首页
<c:if test=“${pageInfo.hasPreviousPage }”>
aria-hidden=“true”>«
</c:if>
<c:forEach items=“${pageInfo.navigatepageNums }” var=“num”>
<c:if test=“${num==pageInfo.pageNum}”>
- ${num}
</c:if>
<c:if test=“${num!=pageInfo.pageNum}”>
- ${num}
</c:if>
</c:forEach>
<c:if test=“${pageInfo.isHasNextPage() }”>
aria-hidden=“true”>»
</c:if>
- 末页
-
=============================================================================
- 1.由于上面的方式只适用于客户端浏览器的交互,所以将返回的数据封装成json,前台进行接收,并进行解析就可以了
具体流程:index.jsp发送json请求进行员工分页的数据查询->服务器将查出的数据以json字符串的形式返回浏览器——>浏览器收到js字符串,使用js进行解析
- 2.为了方便放回json,所以重新写一个方法直接返回pageInfo,要返回json必须添加一个注解@ResponseBody,但是要返回jason,就先导入jackson的包
maven下:搜索jackson->jackson DataBind->选择你需要的版本
- 3.导入完成之后,在原来EmpConntroller层中添加一个新的方法,直接返回pageInfo对象:
为了让浏览器知道查询或者修改等成功与否,需要添加一个状态类来显示状态信息,在po里新创建一个msg对象,通用的返回类
public class Msg {
private Integer code;//状态码(规定100:成功,200:失败)
private String msg;//提示信息
private Map<String, Object> extend=new HashMap<String, Object>();//用户要返回给浏览器的数据
public Msg() {}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map<String, Object> getExtend() {
return extend;
}
public void setExtend(Map<String, Object> extend) {
this.extend = extend;
}
public static Msg success() {
Msg result=new Msg();
result.setCode(100);
result.setMsg(“deal success”);
return result;
}
public static Msg fail() {
Msg result=new Msg();
result.setCode(200);
result.setMsg(“deal failure”);
return result;
}
}
- 4.EmpController中修改的内容:
@Controller
public class EmpController {
@Autowired
EmpService empService;
@ResponseBody
@RequestMapping(“/emp”)
public Msg getEmps(@RequestParam(value=“pn”,defaultValue=“1” ) Integer pn) {
//为了方便快速查询,所以引入PageHelper分页查询
//表示从第pn查,每一页显示5条数据
PageHelper.startPage(pn, 5);//后面紧跟的这个查询就是分页查询
List lemp=empService.getALlEmpInfo();
//将查询的分页结果进行包装,其中PageInfo中包含了这个页面的所有信息,所以只需要将pageInfo交给页面接受就行了
PageInfo page=new PageInfo(lemp,5);//5:表示每次只显示5页的导航菜单
return Msg.success().add(“pageInfo”,page );//返回的不仅有状态消息,其中由于add方法,也将
}
}
=========================================================================
1.重新改造Index页面,让它发出ajax请求:
代码详情如下:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
员工列表 href=“https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css”>
<%
pageContext.setAttribute(“App_Path”, request.getContextPath());
%>
致一科技@<span
style=“font-family: STXingkai; color: graytext;”>Zhiyi
Technology
新增
删除
emp_id emp_name gender eamil dept_id 操作
当前第页 ,总共页,共条记录========================================================================
- 1.在第十三步中我们已经动态创建好了员工信息列表,接下来就是创建分页导航条:
对应的代码如下:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
员工列表 href=“https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css”>
<%
pageContext.setAttribute(“App_Path”, request.getContextPath());
%>
致一科技@<span
style=“font-family: STXingkai; color: graytext;”>Zhiyi
Technology
新增
删除
emp_id emp_name gender eamil dept_id 操作
==========================================================================
- 1.在上一步骤,基本流程已经走完,但是点击页面跳转问题并未解决,接下来进行解决;
代码如下:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
员工列表 href=“https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css”>
<%
pageContext.setAttribute(“App_Path”, request.getContextPath());
%>
致一科技@<span
style=“font-family: STXingkai; color: graytext;”>Zhiyi
Technology
新增
删除
emp_id emp_name gender eamil dept_id 操作
==============================================================================
1. 这个模态框是引用bootStrap中的javaScript组件中模态框的案例
具体代码详情如下:
<%@ page language=“java” contentType=“text/html; charset=utf-8”
pageEncoding=“utf-8”%>
<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
员工列表 href=“https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css”>
<%
pageContext.setAttribute(“App_Path”, request.getContextPath());
%>
aria-labelledby=“myModalLabel”>
<button type=“button” class=“close” data-dismiss=“modal”
aria-label=“Close”>
×
新增员工信息
<input type=“text” class=“form-control” id=“inputName”
placeholder=“姓名”>
name=“inlineRadioOptions” id=“genderMan” value=“男” checked=“checked”> 男
name=“inlineRadioOptions” id=“genderGirl” value=“女”> 女
name=“inlineRadioOptions” id=“genderOthers” value=“女”>
女
<input type=“email” class=“form-control” id=“inputEmail”
placeholder=“Email@gmail.com”>
Close
Save changes
致一科技@<span
style=“font-family: STXingkai; color: graytext;”>Zhiyi
Technology
新增
删除
emp_id emp_name gender eamil dept_id dept_Name 操作
=============================================================================
1.每一次点击应该新增一次ajax请求来获取部门信息到添加的下拉框中
2.在编写此功能之前要先有一个方法专门返回部门信息数据,故在Controller层添加一个控制器DepController:
@Controller
public class DepController {
@Autowired
DepService depService;
@ResponseBody
@RequestMapping(“/depts”)
public Msg getDepts() {
List lDepts=depService.getALlDeptInfo();
return Msg.success().add(“depts”, lDepts);
}
}
但是缺少相应的服务层,以及dao层
对应的service:
刷面试题
刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
-
前端字节跳动真题解析
-
【269页】前端大厂面试题宝典
最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。