学生信息管理系统 (SSJ)

244 阅读8分钟

使用Spring+SpringMVC+JDBC(Spring的JDBCTemplate)构建学生管理系统

(1)在MyEclipse中新建Web Project,在src目录下新建po、bean、dao、biz、action包
引入Spring组件包到当前的工程:
MyEclipse—>Project Capabilities—>Add Spring Capabilities—>勾选前三个(Spring 3.1 Core Libraries、Persistence Libraries、Web Libraries—>Next—>Enable AOP Builder—>Finish)

配置MyEclipse的数据库驱动Database Driver:
Windows—>Show View—>Other...—>DB Browser—>OK—>右键New—>驱动模板Driver template选择MySQL Connection—>Connection URL填写jdbc:mysql://localhost:3306/studb—>username=root、passward=java—>添加jar包Add JARs选择mysql-connector-java-5.1.9-bin.jar—>勾选save passward—>Test Driver=successfully established—>Next—>Display the selected schemas—>Add 选择studb—>Finish
在DB Browser里可以查看数据库结构表明配置成功!

(2)配置applicationContext.xml文件,加入DataSource数据源的配置,配置JDBCTemplate并设置注解扫描,将注解类自动设置到Spring容器中。配置事务管理
配置数据源不用手写,右键—>Spring—>DataSource—>选择上面配置好的DB Driver(mycon)—>Finish
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
		
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.1.xsd
		
		"
	default-autowire="byName">
	<!-- 使用注解配置 -->
	<context:annotation-config></context:annotation-config>
	<!-- 扫描 -->
	<context:component-scan base-package="com.dao"></context:component-scan>
	<context:component-scan base-package="com.biz"></context:component-scan>
	<context:component-scan base-package="com.action"></context:component-scan>
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver">
		</property>
		<property name="url" value="jdbc:mysql://localhost:3306/studb">
		</property>
		<property name="username" value="root"></property>
		<property name="password" value="java"></property>
	</bean>
	<!-- 配置JDBCTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- jdbc的事务管理 -->
	<bean id="txmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 注解的事务通知 -->
	<tx:annotation-driven transaction-manager="txmanager"/>
	
</beans>

(3)编写实体类、dao接口和实现类,并加入注解@Service
实体类Clazz.java

package com.po;
import java.io.Serializable;

public class Clazz implements Serializable {
	private Integer cid;
	private String cname;
	
        /****** getter&setter ******/
        
	public Clazz(Integer cid, String cname) {
		super();
		this.cid = cid;
		this.cname = cname;
	}
	public Clazz() {
		super();
	}
}

实体类Student.java

package com.po;

import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Student implements Serializable {
	private Integer sid;
	private String sname;
	private String sex;
	private String address;
	private Date birthday;
	private Integer classid;
	private String cname;
	private String sdate;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(Integer sid, String sname, String sex, String address,
			Date birthday, Integer classid) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.sex = sex;
		this.address = address;
		this.birthday = birthday;
		this.classid = classid;
	}
	public Student(Integer sid, String sname, String sex, String address,
			Date birthday, Integer classid, String cname) {
		super();
		this.sid = sid;
		this.sname = sname;
		this.sex = sex;
		this.address = address;
		this.birthday = birthday;
		this.classid = classid;
		this.cname = cname;
	}
	public Student(String sname, String sex, String address, Date birthday,
			Integer classid) {
		super();
		this.sname = sname;
		this.sex = sex;
		this.address = address;
		this.birthday = birthday;
		this.classid = classid;
	}
	
        /****** getter&setter ******/
        
	public String getSdate() {
		if(birthday!=null){
			sdate=new SimpleDateFormat("yyyy-MM-dd").format(birthday);
		}
		return sdate;
	}
	public void setSdate(String sdate) {
		if(sdate!=null&&!sdate.trim().equals("")){
			try {
				birthday=new SimpleDateFormat("yyyy-MM-dd").parse(sdate);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.sdate = sdate;
	}
}

分页的实体类PageBean.java

package com.bean;

import java.io.Serializable;
import java.util.*;
public class PageBean implements Serializable {
	private int page=1;//当前页数
	private int rows=5;//每页显示的记录数
	private int maxpage;//总页数
	private List<?> pagelist;//当前页的记录集合
	public PageBean() {
		super();
		// TODO Auto-generated constructor stub
	}
	public PageBean(int page,int rows,int maxpage,List<?> pagelist){
	    super();
	    this.page=page;
	    this.rows=rows;
	    this.maxpage=maxpage;
	    this.pagelist=pagelist;
	}

    //getter&setter
}

Dao接口 IStudentDao.java

package com.dao;
import java.util.*;
import com.po.*;
public interface IStudentDao {
	public int save(Student st);
	public int update(Student st);
	public int delById(Integer sid);
	public Student findById(Integer sid);
	public List<Student> findPageAll(int page,int rows);//接收从页面传递来的当前页数和每页记录数,进行分页查询
	public int findMaxPage(int rows);//根据每页记录数来计算总页数
	public List<Clazz> doinit();//返回学生班级列表
}

Dao接口实现类StudentDao.java

package com.dao;
import ...

@Service
public class StudentDao implements IStudentDao {
	@Resource(name = "jdbcTemplate")//此处的"jdbcTemplate"与applicationContext.xml配置JDBCTemplate的id值保持一致
	private JdbcTemplate jdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public int save(Student st) {
		String sql = "insert into student(sname,sex,address,birthday,classid)"
				+ " values(?,?,?,?,?)";
		int rows = jdbcTemplate.update(
				sql,
				new Object[] { st.getSname(), st.getSex(), st.getAddress(),
						st.getBirthday(), st.getClassid() });
		if (rows > 0) {
			return rows;
		}
		return 0;
	}

	public int update(Student st) {
		String sql = "update student set sname=?,sex=?,"
				+ "address=?,birthday=?,classid=?" + " where sid=?";
		int rows = jdbcTemplate.update(
				sql,
				new Object[] { st.getSname(), st.getSex(), st.getAddress(),
						st.getBirthday(), st.getClassid(), st.getSid() });
		if (rows > 0) {
			return rows;
		}
		return 0;
	}

	public int delById(Integer sid) {
		String sql = "delete from student where sid=?";
		int rows = jdbcTemplate.update(sql, new Object[] { sid });
		if (rows > 0) {
			return rows;
		}
		return 0;
	}

	public Student findById(Integer sid) {
		String sql="select * from student where sid=?";
		Map<String,Object> map=jdbcTemplate.queryForMap(sql,new Object[]{sid});
		Student st=new Student();
		st.setSid((Integer)map.get("sid"));
		st.setSname(map.get("sname").toString());
		st.setSex(map.get("sex").toString());
		st.setAddress(map.get("address").toString());
		st.setBirthday((Date)map.get("birthday"));
		st.setClassid((Integer)map.get("classid"));
		return st;
	}

	public List<Student> findPageAll(int page, int rows) {
		String sql="select s.*,c.cname from student s,clazz c where s.classid=c.cid order by sid limit "+(page-1)*rows+","+rows+"";
		List<Student> lsst=new ArrayList<Student>();
		List<Map<String,Object>> lsmap=jdbcTemplate.queryForList(sql);
		for (Map<String, Object> map : lsmap) {
			Student st=new Student();
			st.setSid((Integer)map.get("sid"));
			st.setSname(map.get("sname").toString());
			st.setSex(map.get("sex").toString());
			st.setAddress(map.get("address").toString());
			st.setBirthday((Date)map.get("birthday"));
			st.setClassid((Integer)map.get("classid"));
			st.setCname(map.get("cname").toString());
			lsst.add(st);
		}
		return lsst;
	}

	public int findMaxPage(int rows) {
		String sql="select count(*) from student";
		long maxrow=0;
		int maxpage=1;
		
		maxrow=jdbcTemplate.queryForLong(sql);//获取表的总记录数
		
		if(maxrow>0){
			maxpage=(int) (maxrow%rows==0?maxrow/rows:maxrow/rows+1);//分页公式
			Java三元表达式:假如总记录数maxrow能整除每页记录数rows则返回结果,否则在取余结果+1,  
			得到最大页数
		}
		return maxpage;
	}

	public List<Clazz> doinit() {
		String sql="select * from clazz";
		List<Clazz> lsca=new ArrayList<Clazz>();
		List<Map<String,Object>> lsmap=jdbcTemplate.queryForList(sql);
		for (Map<String, Object> map : lsmap) {
			Clazz ca=new Clazz();
			ca.setCid((Integer)map.get("cid"));
			ca.setCname(map.get("cname").toString());
			lsca.add(ca);
		}
				
		return lsca;
	}

}

(4)编写Biz接口和实现类,并加入@Service注解,依赖于DAO类@Autowired进行装配
Biz接口 IStudentBiz.java

package com.biz;
import ...

public interface IStudentBiz {
	public int save(Student st);
	public int update(Student st);
	public int delById(Integer sid);
	public Student findById(Integer sid);
	public List<Student> findPageAll(int page,int rows);
	public int findMaxPage(int rows);
	public List<Clazz> doinit();
}

Biz接口实现类 StudentBiz.java

package com.biz;

import ...

@Service
@Transactional
public class StudentBiz implements IStudentBiz {
	@Autowired
	private IStudentDao studentDao;
	
	public IStudentDao getStudentDao() {
		return studentDao;
	}

	public void setStudentDao(IStudentDao studentDao) {
		this.studentDao = studentDao;
	}

	public int save(Student st) {
		int row=studentDao.save(st);
		return row;
	}

	public int update(Student st) {
		
		return studentDao.update(st);
	}

	public int delById(Integer sid) {
		
		return studentDao.delById(sid);
	}

	public Student findById(Integer sid) {
		
		return studentDao.findById(sid);
	}

	public List<Student> findPageAll(int page, int rows) {
		if(page<1)page=1;   //增加判断,防止出现page,rows为负数的情况
		if(rows<1)rows=5;
		return studentDao.findPageAll(page, rows);
	}

	public int findMaxPage(int rows) {
		if(rows<1)rows=5;   //增加判断,防止出现rows为负数或为0的情况
		return studentDao.findMaxPage(rows);
	}

	public List<Clazz> doinit() {
		
		return studentDao.doinit();
	}
}

(5)编写控制器类Action,并加入@Contraller进行注解,对要访问的方法进行路径映射 @RequestMapping(value="路径名称.do")
控制器接口 IAction.java

package com.action;
import ...

public interface IAction {
	public String save(HttpServletRequest request,HttpServletResponse response,Student st);
	public String update(HttpServletRequest request,HttpServletResponse response,Student st);
	public String delById(HttpServletRequest request,HttpServletResponse response,Integer sid);
	public String findById(HttpServletRequest request,HttpServletResponse response,Integer sid);
	public String findPageAll(HttpServletRequest request,HttpServletResponse response,Integer page,Integer rows);
	public String doinit(HttpServletRequest request,HttpServletResponse response);
}

控制器接口实现类 StudentAction.java

package com.action;

import ...

@Controller
public class StudentAction implements IAction {
	@Autowired
	private IStudentBiz studentBiz;
	
	public IStudentBiz getStudentBiz() {
		return studentBiz;
	}
	public void setStudentBiz(IStudentBiz studentBiz) {
		this.studentBiz = studentBiz;
	}
	
	@RequestMapping(value="save_Student.do")
	public String save(HttpServletRequest request,
			HttpServletResponse response, Student st) {
		int row=studentBiz.save(st);
		if(row>0){
			return "redirect:findPageAll_Student.do";//重定向到findPageAll_Student.do路径指定的方法
		}
		return "fail.jsp";
	}
	@RequestMapping(value="update_Student.do")
	public String update(HttpServletRequest request,
			HttpServletResponse response, Student st) {
		int row=studentBiz.update(st);
		if(row>0){
			return "redirect:findPageAll_Student.do";//重定向到findPageAll_Student.do路径指定的方法
		}
		return "fail.jsp";
	}
	@RequestMapping(value="delById_Student.do")
	public String delById(HttpServletRequest request,
			HttpServletResponse response, Integer sid) {
		int row=studentBiz.delById(sid);
		if(row>0){
			return "redirect:findPageAll_Student.do";//重定向到findPageAll_Student.do路径指定的方法
		}
		return "fail.jsp";
	}
	
	@RequestMapping(value="findById_Student.do")
	public String findById(HttpServletRequest request,
			HttpServletResponse response, Integer sid) {
		Student oldst=studentBiz.findById(sid);
		request.setAttribute("oldst",oldst);
		return "student.jsp";
	}
	@RequestMapping(value="findPageAll_Student.do")
	public String findPageAll(HttpServletRequest request,
			HttpServletResponse response, Integer page, Integer rows) {
		HttpSession session=request.getSession();
		
		/*****初始化****************/
		List<Clazz> lsca=studentBiz.doinit();
		session.setAttribute("lsca", lsca);
		/**************************/
		
		
		//从session中获取分页的实体对象
		PageBean pb=(PageBean) session.getAttribute("pb");
		pb=pb==null?new PageBean():pb;
		
		page=page==null||page<1?pb.getPage():page;
		rows=rows==null||rows<1?pb.getRows():rows;
		if(rows>20)rows=20;//限制每页最多记录数
		
		//获取总页数
		int maxpage=studentBiz.findMaxPage(rows);
		
		//获取当前页记录的集合
		List<Student> lsst=studentBiz.findPageAll(page, rows);
		
		pb.setMaxpage(maxpage);
		pb.setPage(page);
		pb.setRows(rows);
		pb.setPagelist(lsst);
		
		session.setAttribute("pb", pb);
		
		return "redirect:student.jsp";
	}
	@RequestMapping(value="doinit_Student.do")
	public String doinit(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session=request.getSession();
		List<Clazz> lsca=studentBiz.doinit();
		session.setAttribute("lsca", lsca);
		return "redirect:student.jsp";
	}
}

(6)配置springmvc-servlet.xml文件,指定springmvc的控制器注解

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
		
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.1.xsd
		
		"
	default-autowire="byName">
	<!-- 使用注解配置 -->
	<context:annotation-config></context:annotation-config>
	<!-- 扫描 -->
	<context:component-scan base-package="com.action"></context:component-scan>
	
</beans>

(7)在web.xml文件,配置Spring的启动和配置字符编码的过滤器
打开WEB—INF目录下Web.xml文件
添加Spring的启动:在Context Parameters栏->Parameter name:contextConfigLocation、Parameter value:classpath:applicationContext.xml

配置监听器Listener添加org.springframework.web.context.ContextLoaderListener

配置过滤器Filter:在Add new filter—> 添加org.springframework.web.filter.CharacterEncodingFilter,在Initial Parameter栏添加encoding--utf-8
在Add new filter mapping—>URL pattern栏添加/*

配置Springmvc的Servlet(DispatcherServlet)
Servlets—>Add new servlet—>添加servlet name:springmvc、servlet class:org.springframework.web.servlet.DispatcherServlet
Add new servlet mapping—>添加servlet name:springmvc、URL Patterns=*.do

(8)编写jsp页面部署测试

二、JdbcTemplate

JdbcTemplate原理: Java程序员在以后的工作中很重要的一点就是得和数据库打交道,但是代码和数据库是两个不相干的,怎么使用代码对数据库进行操作呢,这个时候就用到JDBC。
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。 而多的这个template,就是模板,是Spring框架为我们提供的.所以JdbcTemplate就是Spring对JDBC的封装,通俗点说就是Spring对JDBC的封装的模板。
JDBC的基本原理:通过Connection这个类获取数据库的连接,然后通过PreparedStatement类处理SQL语句,再通过它的.setObject方法传入数据,最后通过方法.executeUpdate()和.executeQuery()执行更新。
对于JdbcTemplate,SpringIoC容器将管理数据库连接的数据源dataSource当作普通Java Bean一样管理,然后将数据源dataSource注入到JdbcTemplate中,JdbcTemplate的dataSource属性就是注入配置的数据源。

JdbcTemplate主要常用方法:
· execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
· update方法:update方法用于执行新增、修改、删除等语句,注意返回值类型为int,即受影响的行数,类似executeUpdate(sql);
· batchUpdate方法:batchUpdate方法则用于执行批处理相关语句;
· query方法及queryForXXX方法:用于执行查询相关语句;
· call方法:用于执行存储过程、函数相关语句。