这篇博客主要是分享一个基于Servlet+Jsp(el, jstl)+MyBatis的CRUD练习小项目。包括项目的源码,以及项目的逻辑。通过这个项目能够学习Java web中最基础的servlet,jsp和mybatis的使用,为后续Spring的学习打下基础。项目源代码
关键词:javaweb基础,servlet,jsp,mybatis;
基本的增删改查功能,项目采样web层、service层和dao层,三层架构。每个功能的实现都是从dao层开始,然后是web层,最后才是service层。
逻辑:通过点击“查询所有”跳转到SelectAllServlet,然后调用service,service会调用mapper。
首先创建mapper接口,并编写selectAll()。
@Select("select * from tb_brand")
@ResultMap("brandResultMap")
List<Brand> selectAll();
因为是简单的sql语句,所以使用注解开发。注意,select返回的数据库的字段与pojo的属性名并不一致,所以通过在BrandMapper.xml中的resultMap进行映射。
<resultMap id="brandResultMap" type="Brand">
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
resultMap>
column表示数据库中的字段,property表示brand类的属性名。
完成Dao层后,编写service层,创建一个BrandService类,添加一个selectAll()。
public List<Brand> selectAll(){
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
List<Brand> brands = mapper.selectAll();
sqlSession.close();
return brands;
}
这里使用了SqlSessionFactory工厂创建sqlSession,工厂只需要创建一次并且每个service方法中都要使用工厂,所以将这部分功能抽象成一个工具类SqlSessionFactoryUtils
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
public static SqlSessionFactory getSqlSessionFactory(){return sqlSessionFactory;}
service层完成后,先编写前端的jsp页面(brand.jsp)。在这里只展示关键部分。通过jstl的
<c:forEach items="${brands}" var="brand" varStatus="status">
<tr align="center">
<%-- <td>${brand.id}td>--%>
<td>${status.count}td>
<td>${brand.brandName}td>
<td>${brand.companyName}td>
<td>${brand.ordered}td>
<td>${brand.description}td>
<c:if test="${brand.status == 1}">
<td>启用td>
c:if>
<c:if test="${brand.status == 0}">
<td>禁用td>
c:if>
<td><a href="#">修改a> <a href="#">删除a>td>
tr>
c:forEach>
最后实现servlet
@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 调用service的selectAll()
List<Brand> brands = service.selectAll();
// 将查询结果封装值req
req.setAttribute("brands", brands);
// 将req请求转发至brand.jsp,brand.jsp就能通过el表达式从req中读取数据
req.getRequestDispatcher("/brand.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
逻辑:通过点击“修改”按钮,跳转到addBrand.jsp页面,在该页面中的表单填写新记录,最后通过“提交”按钮,将数据传到addServlet,addServlet会调用service,service会调用mapper接口中的add方法。
同样,先写Dao层。在mapper接口中创建add()方法。
@Insert("insert into tb_brand values(null, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status})")
void add(Brand brand);
在BrandService中编写add()方法
public void add(Brand brand){
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.add(brand);
sqlSession.commit();
sqlSession.close();
}
先写前端页面,在brand.jsp中的“新增”按钮绑定事件,然后事件触发后跳转到addBrand.jsp
按钮:
<input type="button" value="新增" id="add"><br>
通过id绑定事件
<script>
document.getElementById("add").onclick = function (){
location.href = "/ServletAndJspCRUDDemo/addBrand.jsp"
}
script>
addBrand.jsp就是一个表单,信息填完后,表单会提交到AddServlet
<form action="/ServletAndJspCRUDDemo/addservlet" method="post">
品牌名称:<input name="brandName"><br>
企业名称:<input name="companyName"><br>
排序:<input name="ordered"><br>
描述信息:<textarea rows="5" cols="20" name="description">textarea><br>
状态:
<input type="radio" name="status" value="0">禁用
<input type="radio" name="status" value="1">启用<br>
<input type="submit" value="提交">
form>
最后编写AddServlet
@WebServlet("/addservlet")
public class AddServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// addBrand.jsp的表单通过req传递到servlet,servlet从req获取相应的参数,参数的键就是表单的name。
req.setCharacterEncoding("utf-8"); // 防止中文乱码
String brandName = req.getParameter("brandName");
String companyName = req.getParameter("companyName");
String ordered = req.getParameter("ordered");
String description = req.getParameter("description");
String status = req.getParameter("status");
// 从req中获取的参数,封装成一个brand实例
Brand brand = new Brand();
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(Integer.parseInt(ordered));
brand.setDescription(description);
brand.setStatus(Integer.parseInt(status));
// 调用service的方法
service.add(brand);
// 处理完后重新将请求转发到“查询所有”页面
req.getRequestDispatcher("/selectAllServlet").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
修改功能的实现分两步,第一步是点击修改按钮后,要重新读取数据,然后在前端页面显示出来。第二步是修改完成后,重新提交。
@Select("select * from tb_brand where id = #{id}")
@ResultMap("brandResultMap")
Brand selectById(int id);
Service层
public Brand selectById(int id){
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
Brand brand = mapper.selectById(id);
sqlSession.close();
return brand;
}
先写前端。
点击修改按钮后,首先要获得当条记录的id,所以在brand.jsp中的“修改”按钮中传递id
<a href="/ServletAndJspCRUDDemo/selectByIdServlet?id=${brand.id}">修改a>
SelectByIdServlet
@WebServlet("/selectByIdServlet")
public class SelectByIdServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
Brand brand = service.selectById(Integer.parseInt(id));
req.setAttribute("brand", brand);
req.getRequestDispatcher("/update.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
最后会将请求转发至update.jsp
<form action="/ServletAndJspCRUDDemo/updateServlet" method="post">
<input type="hidden" name="id" value="${brand.id}">
品牌名称:<input name="brandName" value="${brand.brandName}"><br>
企业名称:<input name="companyName" value="${brand.companyName}"><br>
排序:<input name="ordered" value="${brand.ordered}"><br>
描述信息:<textarea rows="5" cols="20" name="description" >${brand.description}textarea><br>
状态:
<c:if test="${brand.status == 0}">
<input type="radio" name="status" value="0" checked>禁用
<input type="radio" name="status" value="1">启用<br>
c:if>
<c:if test="${brand.status == 1}">
<input type="radio" name="status" value="0">禁用
<input type="radio" name="status" value="1" checked>启用<br>
c:if>
<input type="submit" value="提交">
form>
这是个表单,通过el表达式从req中读取数据,还使用了jstl的
在前端页面完成信息编辑后,通过点击提交按钮,将新记录提交到后台,实质使用的是update sql。
Dao层
@Update("update tb_brand set brand_name = #{brandName}, company_name = #{companyName}, ordered = #{ordered}, description = #{description}, status = #{status} where id = #{id}")
void update(Brand brand);
Service层
public void update(Brand brand){
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.update(brand);
sqlSession.commit();
sqlSession.close();
}
update.jsp中的表单会提交到UpdateServlet
@WebServlet("/updateServlet")
public class UpdateServlet extends HttpServlet {
private BrandService service = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String id = req.getParameter("id");
String brandName = req.getParameter("brandName");
String companyName = req.getParameter("companyName");
String ordered = req.getParameter("ordered");
String description = req.getParameter("description");
String status = req.getParameter("status");
Brand brand = new Brand();
brand.setId(Integer.parseInt(id));
brand.setBrandName(brandName);
brand.setCompanyName(companyName);
brand.setOrdered(Integer.parseInt(ordered));
brand.setDescription(description);
brand.setStatus(Integer.parseInt(status));
service.update(brand);
req.getRequestDispatcher("/selectAllServlet").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Dao层
@Delete("delete from tb_brand where id = #{id}")
void delete(int id);
Service层
public void delete(int id){
SqlSession sqlSession = sqlSessionFactory.openSession();
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
mapper.delete(id);
sqlSession.commit();
sqlSession.close();
}
前端页面,与“修改”类似,需要获取当条记录的id,通过brand.jsp页面的删除按钮绑定。
<a href="/ServletAndJspCRUDDemo/deleteServlet?id=${brand.id}">删除a>td>
DeleteServlet
@WebServlet("/deleteServlet")
public class DeleteServlet extends HttpServlet {
private BrandService brandService = new BrandService();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
brandService.delete(Integer.parseInt(id));
req.getRequestDispatcher("/selectAllServlet").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
完结撒花!
项目比较简单,但涵盖了web端最基本的增删改查功能,可以用来练习。