用到的知识点
- springIOC
- springAOP
- 事务管理
- jdbcTemplate
- servlet
代码展示
- 效果图
- 项目结构:重点标注了baseServlet,有人可能没这么用过
- 导入jar包
- 数据库表:怎么简单怎么来
- 实体类
package com.bjsxt.pojo;
public class Brand {
private int id;
private String name;
//get、set,构造函数等略
}
package com.bjsxt.pojo;
import java.util.Date;
public class Product {
private int pid;
private String pname;
private double price;
private Date prodate;
private int brandid;
private Brand brand;
//get、set,构造函数等略
}
- Dao接口
商品类别dao
package com.bjsxt.dao;
import java.util.List;
import com.bjsxt.pojo.Brand;
public interface BrandDao {
List<Brand> selAll();
}
package com.bjsxt.dao;
import java.util.Date;
import java.util.List;
import com.bjsxt.pojo.Product;
public interface ProductDao {
List<Product> selAll();
Product selById(int pid);
int add(Product product);
int upd(Product product);
int del(int pid);
/**
* 用于测试事务
* 修改功能通过多个service方法实现
*/
int updProName(String pname,int pid);
int updProPrice(double price,int pid);
int updProBrand(int brandid,int pid);
int updProDate(Date prodate,int pid);
}
- dao接口实现类
@Component
public class BrandDaoImpl implements BrandDao {
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public List<Brand> selAll() {
String sql="select * from brand";
RowMapper<Brand> rowMapper = new BeanPropertyRowMapper<Brand>(Brand.class);
return jdbcTemplate.query(sql, rowMapper);
}
}
@Component
public class ProductDaoImpl implements ProductDao{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Product> selAll() {
String sql="select * from product";
RowMapper<Product> rowMapper = new BeanPropertyRowMapper<Product>(Product.class);
List<Product> list = jdbcTemplate.query(sql, rowMapper);
String sql2="select * from brand where id=?";
for (int i = 0; i < list.size(); i++) {
Product product = list.get(i);
RowMapper<Brand> brandRowMapper = new BeanPropertyRowMapper<Brand>(Brand.class);
Brand brand = jdbcTemplate.queryForObject(sql2, brandRowMapper,product.getBrandid());
product.setBrand(brand);
}
return list;
}
@Override
public Product selById(int pid) {
String sql="select * from product where pid=?";
RowMapper<Product> rowMapper = new BeanPropertyRowMapper<Product>(Product.class);
Product product = jdbcTemplate.queryForObject(sql, rowMapper,pid);
return product;
}
@Override
public int add(Product product) {
String sql = "insert into product(pname,price,prodate,brandid) values(?,?,?,?)";
return jdbcTemplate.update(sql, product.getPname(),product.getPrice(),product.getProdate(),product.getBrandid());
}
@Override
public int upd(Product product) {
String sql = "update product set pname=?,price=?,prodate=?,brandid=? where pid=?";
return jdbcTemplate.update(sql, product.getPname(),product.getPrice(),product.getProdate(),product.getBrandid(),product.getPid());
}
@Override
public int del(int pid) {
String sql = "delete from product where pid=?";
return jdbcTemplate.update(sql, pid);
}
//剩下的略
}
- service接口
public interface BrandService {
List<Brand> selAll();
}
public interface ProductService {
List<Product> selAll();
Product selById(int pid);
int add(Product product);
int upd(Product product);
int del(int pid);
}
- service接口实现类
@Service
public class BrandServiceImpl implements BrandService{
@Autowired
private BrandDao brandDao;
@Override
public List<Brand> selAll() {
return brandDao.selAll();
}
}
@Service
public class ProductServiceImpl implements ProductService{
@Autowired
private ProductDao productDao;
@Override
public List<Product> selAll() {
return productDao.selAll();
}
@Override
public Product selById(int pid) {
return productDao.selById(pid);
}
@Override
public int add(Product product) {
return productDao.add(product);
}
@Override
public int upd(Product product) {
int flag = 0;
if(product != null && product.getBrandid() != 0) {
flag = productDao.updProBrand(product.getBrandid(), product.getPid());
}
if(product != null && product.getPname()!=null) {
flag = productDao.updProName(product.getPname(), product.getPid());
}
if(product != null && product.getProdate()!=null) {
flag = productDao.updProDate(product.getProdate(), product.getPid());
}
/**
*原来设计是准备设置数据库price>0,使用修改功能的时候修改为负数,导致修改功能报错,查看事务是否回滚;
*结果~~mysql没有实现check约束,于是手动制造错误
*/
System.out.println(1/0);
if(product != null && product.getPrice() != 0) {
flag = productDao.updProPrice(product.getPrice(), product.getPid());
}
return flag;
}
@Override
public int del(int pid) {
return productDao.del(pid);
}
}
- servlet代码展示
package com.bjsxt.servlet;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
/**
* 一个servlet会接收到多个请求,为了方便起见:
* 向上抽取baseServlet,用于动态调用自定义servlet中的方法
* 根据请求中method参数的值,调用对应servlet中的方法
* 使用方式:自定义servlet继承该类,直接书写相关业务代码即可
*
*/
public abstract class BaseServlet extends HttpServlet {
/**
* Servlet中本来不能使用@Autowired注入bean,因为servlet没有交给spring来管理
* 该方法对Spring Web Application Context之外的类提供@Autowired注入功能
*/
@Override
public void init(ServletConfig config) throws ServletException{
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
}
/**
* 子类接收到请求后,会先执行该类中的service方法
* 在service方法中,会使用反射技术执行子类中对应的方法
*/
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//获取请求参数
String methodName=req.getParameter("method");
try {
//获取子类信息(方法中的this代表调用该方法的对象)
Class cla=this.getClass();
//通过方法名、参数列表,获取子类中的指定方法
Method m=cla.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
//执行子类对象的该方法
m.invoke(this, req,resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.bjsxt.servlet;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import com.bjsxt.pojo.Brand;
import com.bjsxt.pojo.Product;
import com.bjsxt.service.BrandService;
import com.bjsxt.service.ProductService;
/**
* WebServlet("/pro")相当于在web.xml中配置了
* <servlet>
* <servlet-name>proservlet</servlet-name>
* <servlet-class>com.bjsxt.servlet.ProductServlet</servlet-class>
* </servlet>
* <servlet-mapping>
* <servlet-name>proservlet</servlet-name>
* <url-pattern>/pro</url-pattern>
* </servlet-mapping>
*/
@WebServlet("/pro")
public class ProductServlet extends BaseServlet{
@Autowired
private BrandService brandService;
@Autowired
private ProductService productService;
public void selAll(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Product> list = productService.selAll();
request.setAttribute("list", list);
request.getRequestDispatcher("/list.jsp").forward(request, response);
}
public void toAdd(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Brand> list = brandService.selAll();
request.setAttribute("list", list);
request.getRequestDispatcher("/add.jsp").forward(request, response);
}
public void add(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String pname = request.getParameter("pname");
double price = 0;
String priceStr = request.getParameter("price");
if(priceStr != null && !priceStr.equals("")) {
price = Double.parseDouble(priceStr);
}
Date prodate = null;
String prodateStr = request.getParameter("prodate");
if(prodateStr != null && !prodateStr.equals("")) {
try {
prodate = new SimpleDateFormat("yyyy-mm-dd").parse(prodateStr);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int brandid = 0;
String brandidStr = request.getParameter("brandid");
if(brandidStr != null && !brandidStr.equals("")) {
brandid = Integer.parseInt(brandidStr);
}
Product product = new Product(pname, price, prodate, brandid);
productService.add(product);
response.sendRedirect(request.getContextPath()+"/pro?method=selAll");
}
public void toUpdate(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int pid = 0;
String pidStr = request.getParameter("pid");
if(pidStr != null && !pidStr.equals("")) {
pid = Integer.parseInt(pidStr);
}
Product product = productService.selById(pid);
request.setAttribute("product", product);
List<Brand> list = brandService.selAll();
request.setAttribute("list", list);
request.getRequestDispatcher("/upd.jsp").forward(request, response);
}
public void update(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int pid = 0;
String pidStr = request.getParameter("pid");
if(pidStr != null && !pidStr.equals("")) {
pid = Integer.parseInt(pidStr);
}
String pname = request.getParameter("pname");
double price = 0;
String priceStr = request.getParameter("price");
if(priceStr != null && !priceStr.equals("")) {
price = Double.parseDouble(priceStr);
}
Date prodate = null;
String prodateStr = request.getParameter("prodate");
if(prodateStr != null && !prodateStr.equals("")) {
try {
prodate = new SimpleDateFormat("yyyy-mm-dd").parse(prodateStr);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int brandid = 0;
String brandidStr = request.getParameter("brandid");
if(brandidStr != null && !brandidStr.equals("")) {
brandid = Integer.parseInt(brandidStr);
}
Product product = new Product(pid,pname, price, prodate, brandid);
productService.upd(product);
response.sendRedirect(request.getContextPath()+"/pro?method=selAll");
}
public void delete(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int pid = 0;
String pidStr = request.getParameter("pid");
if(pidStr != null && !pidStr.equals("")) {
pid = Integer.parseInt(pidStr);
}
productService.del(pid);
response.sendRedirect(request.getContextPath()+"/pro?method=selAll");
}
}
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>spring-curd</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!-- 注册 ContextLoaderListener:监听ServletContext,当其初始化时,创建spring容器对象,并且将spring容器对象放到ServletContext作用域当中 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 为ContextLoaderListener指定spring配置文件的路径及名称 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 注册字符编码过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.bjsxt.*"></context:component-scan>
<!-- 加载jdbc属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 注册c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 配置Spring的jdbcTemplate 并注入一个dataSource数据源 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 注册事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="tx_advice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="sel*" propagation="REQUIRED" read-only="true" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="upd*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(* com.bjsxt.service..*.*(..))" id="tx_point" />
<aop:advisor advice-ref="tx_advice" pointcut-ref="tx_point" />
</aop:config>
<!-- 配置事务注解驱动 -->
<!-- <tx:annotation-driven transaction-manager="transactionManager"/> -->
</beans>
- jsp代码
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>商品信息列表</title>
</head>
<body>
<a href="pro?method=toAdd" style="margin-left: 30%;">添加</a>
<br>
<table border="1" width="60%" align="center">
<tr bgcolor="aqua">
<th>商品编号</th>
<th>商品名称</th>
<th>价格</th>
<th>商品类型</th>
<th>生产日期</th>
<th>操作</th>
</tr>
<c:forEach items="${list }" var="pro">
<tr>
<td>${pro.pid }</td>
<td>${pro.pname }</td>
<td>${pro.price }</td>
<td>${pro.brand.name }</td>
<td>${pro.prodate }</td>
<td>
<a href="pro?method=toUpdate&pid=${pro.pid }">编辑</a>
<a href="pro?method=delete&pid=${pro.pid }">删除</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>添加商品</title>
</head>
<body>
<form action="pro">
<input type="hidden" name="method" value="add">
<table align="center">
<tr>
<td>商品名称:</td>
<td><input type="text" name="pname"></td>
</tr>
<tr>
<td>商品价格:</td>
<td><input type="text" name="price"></td>
</tr>
<tr>
<td>商品类型:</td>
<td>
<select name="brandid">
<c:forEach items="${list }" var="brand">
<option value="${brand.id }">${brand.name }</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<td>生产日期:</td>
<td><input type="text" name="prodate"></td>
</tr>
<tr>
<td clospan=2>
<input type="submit" value="提交">
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
</html>
upd.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>修改商品信息</title>
</head>
<body>
<form action="pro">
<input type="hidden" name="method" value="update">
<input type="hidden" name="pid" value="${product.pid }">
<table align="center">
<tr>
<td>商品名称:</td>
<td><input type="text" name="pname" value="${product.pname }"></td>
</tr>
<tr>
<td>商品价格:</td>
<td><input type="text" name="price" value="${product.price }"></td>
</tr>
<tr>
<td>商品类型:</td>
<td>
<select name="brandid">
<c:forEach items="${list }" var="brand">
<option value="${brand.id }" ${product.brandid==brand.id?'selected':'' }>${brand.name }</option>
</c:forEach>
</select>
</td>
</tr>
<tr>
<td>生产日期:</td>
<td><input type="text" name="prodate" value="${product.prodate }"></td>
</tr>
<tr>
<td clospan=2>
<input type="submit" value="提交">
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
</html>
项目中出现的问题总结
- jdbcTemplate实现curd:参考productDaoImpl
- servlet中注入service:参考baseServlet的init方法
- mysql数据库没有实现check约束:引用官方的话,MySQL只是可以使用check约束,但不会强制的遵循check约束!