当前位置: 移动技术网 > IT编程>开发语言>Java > java学生信息管理系统设计

java学生信息管理系统设计

2019年07月22日  | 移动技术网IT编程  | 我要评论

本例的学生信息添加进入数据库的事务(可以提交事务,事务回滚,用本地线程完善)

主页面index.jsp

<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
 <head>

 <title>学生信息管理</title>
 </head>

 <body>
 <a href='<c:url value="/query"/>?cmd=query'>查看学生信息</a>
 <br><br>
 <!-- 
 <a href="<c:url value='/studservlet?cmd=save' />">学生信息添加</a>
 -->
 <h2>学生信息添加</h2>
 <form action='<c:url value="/query"/>?cmd=add' method="post">
 姓名:<input type="text" name="name"/><br><br>

 <fieldset style="border: solid;border-color: red;width: 250px;">
 <legend>图书1</legend>
 书名:<input type="text" name="book"/><br><br>
 价格:<input type="text" name="price"/>
 </fieldset>
 <br>
 <fieldset style="border: solid;border-color:green;width: 250px;">
 <legend>图书2</legend>
 书名:<input type="text" name="book"/><br><br>
 价格:<input type="text" name="price"/>
 </fieldset>
 <br><br>
 <input type="submit" value="提交"/><br><br>
 </form>
 </body>
</html>

获取数据库连接的工具connutils5.java

package cn.hncu.utils;

import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
import java.lang.reflect.proxy;
import java.sql.connection;
import java.sql.drivermanager;
import java.util.arraylist;
import java.util.list;
import java.util.properties;

public class connutils5 {

 //本地线程管理对象,用于实现: 同一个线程获取的连接是同一个
 private static threadlocal< connection> t=new threadlocal<connection>();
 private final static list<connection> pool=new arraylist<connection>();
 private static int size;//由资源文件读取
 private connutils5(){

 }
 static{
 properties p=new properties();
 try {
 //下面这种方式在纯java项目中可以读取到classpath下的资源文件,但无法读取javaee项目的。因为tomcat把系统的默认类加载器改了
 //p.load( classloader.getsystemclassloader().getsystemresourceasstream("jdbc.properties"));
// p.load(classloader.getsystemresourceasstream("jdbc.properties"));

 //读取web项目的classpath下的资源文件,用这个可以
 p.load(connutils3.class.getclassloader().getresourceasstream("jdbc.properties"));
 string driver=p.getproperty("driver");
 string url=p.getproperty("url");
 string name=p.getproperty("username");
 string pwd=p.getproperty("password");
 string ssize=p.getproperty("size");
 size=integer.parseint(ssize);
 class.forname(driver);
 for(int i=0;i<size;i++){
 final connection con=drivermanager.getconnection(url,name,pwd);
 system.out.println("con=="+con);
 //更改conn.close()方法
 //用代理模式生成一个增强版的conn对象,把它的close()方法拦截更改掉
 object ncon=proxy.newproxyinstance(
  connutils3.class.getclassloader(), 
  // conn.getclass().getinterfaces(), 
  //后面这种方式不行,应该是驱动中的实现类和我们当前程序不在同一空间(类加载器不同) 
  new class[]{connection.class}, 
  new invocationhandler() {
  @override
  public object invoke(object proxy, method method, object[] args)
   throws throwable {
  if(method.getname().equals("close")){
   system.out.println("还回一个链接:"+(connection)proxy);
   pool.add((connection)proxy);
   return null;
  }
  return method.invoke(con, args);
  }
 });
 pool.add((connection)ncon);
 }
 } catch (exception e) {
 e.printstacktrace();
 }
 }
 public static synchronized connection getconnection(){
 //先从t中拿,如果有就拿出去,如果没有再到池中拿且把该对象放到t中
 connection con=t.get();
 if(con==null){

 if(pool.size()<=0){
 system.out.println("池中连接没有了...");
 try {
  thread.sleep(1000);
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 return getconnection();
 }
 con=pool.remove(0);
 t.set(con);//放到t中
 }

 return con;//拿一个移一个
 }


}

资源文件jdbc.properties

##mysql
driver=com.mysql.jdbc.driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useunicode=true&characterencoding=utf-8
username=root
password=1234
size=3
##oracle
#driver=oracle.jdbc.driver.oracledriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username=scott
#password=tiger

值对象
stud.java

package cn.hncu.domain;

import java.util.arraylist;
import java.util.list;
/*
 * 一对多中的 “一”方 值对象的建法
 */
public class stud {

 private string id;
 private string name;
 //※专为“多”方添加一个集合---体现多表中的“一对多关系”
 private list<book> books=new arraylist<book>();//注意,该集合要在构造时或之前就new出来。
 public string getid() {
 return id;
 }
 public void setid(string id) {
 this.id = id;
 }
 public string getname() {
 return name;
 }
 public void setname(string name) {
 this.name = name;
 }



 public list<book> getbooks() {
 return books;
 }
 public void setbooks(list<book> books) {
 this.books = books;
 }
 @override
 public string tostring() {
 return "id=" + id + "," + name + "," + books;
 }

}

book.java

package cn.hncu.domain;
/*
 * 一对多中的 “多”方 值对象的建法
 */
public class book {

 private integer id;
 //基本数据类型全部用包装类的声明,为以后使用框架做技术准备---包装类能够兼容框架(因为一般框架都会使用类反射)
 private string name;
 private double price;
 //※专为“一”方添加一个对象类型的变量(注意,不用studid)---体现多表中的“一对多关系”
 private stud s;//设置主人
 //private string studid;//★★不要这样设
 public integer getid() {
 return id;
 }
 public void setid(integer id) {
 this.id = id;
 }
 public string getname() {
 return name;
 }
 public void setname(string name) {
 this.name = name;
 }
 public double getprice() {
 return price;
 }
 public void setprice(double price) {
 this.price = price;
 }
 public stud gets() {
 return s;
 }
 public void sets(stud s) {
 this.s = s;
 }
 /*
 * 多表关联时的tostring()方法要注意一个陷阱,就是一方输出另一方,同时另一方又反过来输出前一方,形成无穷递归!
 */
 @override
 public string tostring() {
 return "id=" + id + "," + name + "," + price;//这里不能输出stud对象,否则无穷递归
 }

}

stud层的servlet层–queryservlet.java

package cn.hncu.stud.servlet;

import java.io.ioexception;
import java.util.list;
import java.util.map;

import javax.servlet.servletexception;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;

import cn.hncu.domain.book;
import cn.hncu.domain.stud;
import cn.hncu.stud.service.istudservice;
import cn.hncu.stud.service.studserviceimpl;

public class queryservlet extends httpservlet {

 //注入
 istudservice service=new studserviceimpl();
 public void doget(httpservletrequest request, httpservletresponse response)
 throws servletexception, ioexception {

 dopost(request, response);
 }


 public void dopost(httpservletrequest request, httpservletresponse response)
 throws servletexception, ioexception {
 string cmd=request.getparameter("cmd");
 system.out.println("cmd:"+cmd);
 if("query".equals(cmd)){
 query(request, response);
 }else if("add".equals(cmd)){
 add(request, response);
 }
 }


 public void query(httpservletrequest request, httpservletresponse response)
 throws servletexception, ioexception {
 list<map<string, string>> studs=service.query();
 request.setattribute("studs", studs);
 request.getrequestdispatcher("/jsps/show.jsp").forward(request, response);
 }
 public void add(httpservletrequest request, httpservletresponse response)
 throws servletexception, ioexception {
 //1收集参数 2组织参数(id字段留到dao中去补)
 string name[]=request.getparametervalues("name");
 system.out.println(name[0]);
 stud s=new stud();
 s.setname(name[0]);
 //图书信息
 string books[]=request.getparametervalues("book");
 //防护一下 ---价格的防护应该也要写,这里我们偷懒了
 if(books==null||books.length<=0){
 return;
 }
 string prices[]=request.getparametervalues("price");
 for(int i=0;i<books.length;i++){
 book b=new book();
 b.setname(books[i]);
 b.setprice(double.parsedouble(prices[i]));
 //※完成两个值对象的“一对多”关系的数据封装
 s.getbooks().add(b);//一方
 b.sets(s);//多方
 }
 //3调用service层
 try {
 service.save(s);
 } catch (exception e) {
 //导向失败页面
 }

 }

}

stud层的service层–
接口:

package cn.hncu.stud.service;

import java.util.list;
import java.util.map;

import cn.hncu.domain.stud;

public interface istudservice {

 public list<map<string, string>> query();
 public void save(stud stud);
}

实现类

package cn.hncu.stud.service;


import java.sql.connection;
import java.sql.sqlexception;
import java.util.list;
import java.util.map;

import cn.hncu.domain.stud;
import cn.hncu.stud.dao.bookdao;
import cn.hncu.stud.dao.bookjdbcdao;
import cn.hncu.stud.dao.studdao;
import cn.hncu.stud.dao.studjdbcdao;
import cn.hncu.utils.connutils3;

/*我们以后开发时通常都要采用一个dao独立操作一个表,系统中有几个实体表就写几个dao,
 * 以后框架都是这么干的,我们也要这样做,因为架构好!
 * 
 * 采用事务的场合:
 * 1、如果只有一个dao,但要执行多条sql语句且涉及增删改,则要开启事务
 * 2、如果一个service调用多个dao,通常也要开启事务。
 */
public class studserviceimpl implements istudservice {

 //注入
 studdao dao_stud=new studjdbcdao();
 bookdao dao_book=new bookjdbcdao();
 @override
 public list<map<string, string>> query() {
 return dao_stud.query();
 }
 @override
 public void save(stud stud) {
 connection con=null;

 try {
 con=connutils3.getconnection();
 system.out.println("拿到一个链接:"+con);
 con.setautocommit(false);
 dao_stud.save(stud);
 dao_book.save(stud.getbooks());

 system.out.println("提交一个事务...");
 con.commit();
 } catch (exception e) {
 try {
 system.out.println("回滚一个事务...");
 con.rollback();
 } catch (sqlexception e1) {
 e1.printstacktrace();
 }
 }finally{
 try {
 con.setautocommit(true);
 con.close();
 } catch (sqlexception e) {
 e.printstacktrace();
 }
 }
 }

}

stud层的dao层–
stud接口

package cn.hncu.stud.dao;

import java.util.list;
import java.util.map;

import cn.hncu.domain.stud;

public interface studdao {

 public list<map<string, string>> query();
 public void save(stud stud) throws exception;
}

stud实现类

package cn.hncu.stud.dao;

import java.sql.connection;
import java.sql.preparedstatement;
import java.sql.resultset;
import java.sql.sqlexception;
import java.sql.statement;
import java.util.arraylist;
import java.util.hashmap;
import java.util.list;
import java.util.map;
import java.util.uuid;

import cn.hncu.domain.book;
import cn.hncu.domain.stud;
import cn.hncu.utils.connutils3;

public class studjdbcdao implements studdao {

 @override
 public list<map<string, string>> query() {
 list<map<string, string>> list=new arraylist<map<string,string>>();
 //一个map就是一行数据, list<map>就是整个数据表
 connection con=null;
 try {
 con=connutils3.getconnection();
 statement st=con.createstatement();
 string sql="select * from stud";
 resultset rs=st.executequery(sql);
 while(rs.next()){
 map<string,string> m=new hashmap<string, string>();
 m.put("id", (string) rs.getobject(1));
 m.put("name", (string) rs.getobject(2));
 list.add(m);
 }
 rs.close();
 st.close();
 } catch (sqlexception e) {
 e.printstacktrace();
 }finally{
 try {
 con.close();
 } catch (sqlexception e) {
 e.printstacktrace();
 }
 }


 return list;
 }

 @override
 public void save(stud stud) throws exception {
 connection con=connutils3.getconnection();
 system.out.println("拿到一个链接:"+con);
 string sql="insert into stud values(?,?)";
 string uuid=uuid.randomuuid().tostring().replace("-", "");
 preparedstatement pst=con.preparestatement(sql);
 stud.setid(uuid);//为了"多方"即book能够拿到"一方"的id,专门补的
 pst.setstring(1, uuid);
 pst.setstring(2, stud.getname());
 system.out.println("1:"+uuid+",2:"+stud.getname());
 pst.executeupdate();
// con.close();//拿到同一个con,这里就不需要关了
 }

}

book接口

package cn.hncu.stud.dao;

import java.util.list;

import cn.hncu.domain.book;

public interface bookdao {

 public void save(list<book> books) throws exception;
}

book实现类

package cn.hncu.stud.dao;

import java.sql.connection;
import java.sql.preparedstatement;
import java.util.list;

import cn.hncu.domain.book;
import cn.hncu.utils.connutils3;

public class bookjdbcdao implements bookdao {

 @override
 public void save(list<book> books) throws exception {
 connection con=connutils3.getconnection();
 system.out.println("拿到一个链接:"+con);
 string sql="insert into book(name,price,studid) values(?,?,?)";
 preparedstatement pst=con.preparestatement(sql);
 for(book b:books){
 pst.setstring(1, b.getname());
 pst.setdouble(2, b.getprice());
 pst.setobject(3, "12132312");//异常(故意给一个不存在的外键字段,以测试事务回滚)--测事务回滚
// pst.setobject(3, b.gets().getid());
 system.out.println("1:"+b.getname()+",2:"+b.getprice()+",3:"+b.gets().getid());
 pst.addbatch();//添加到批处理
 }
 pst.executebatch();//执行批处理

// con.close();//这里拿到同一个con,这里不需要关

 }

}

显示学生信息页面jsps/show.jsp

<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
 <head>

 <title>学生信息管理</title>
 </head>

 <body>
 <h2>学生信息</h2>
 <c:foreach items="${studs}" var="x">
 ${x.id},${x.name}<br/>
 </c:foreach>
 </body>
</html>

效果图:

关于管理系统的更多内容请点击《管理系统专题》进行学习

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网