Web开发实训——学生信息管理系统(JSP+Servlet+Ajax+MySQL)
内容比较长、是完整的开发过程,可以根据目录查看感兴趣的地方。
目录
核心思路
开发环境
完成结果
一、前端页面编写
二、导入相关依赖包
三、创建数据库
四、构建Servlet相关类
1、实体类:Student.java
2、Servlet连接数据库父类:SQL.java
3、Student数据表操作类:StudentSQL.java
五、具体功能实现
1、页面内容的加载
2、添加学生记录
3、编辑学生记录
4、删除学生记录
六、拓展与完善
七、一点感想
八、完整源代码下载
核心思路
前端HTML页面,构成JSP页面
后端Servlet管理
后端使用JDBC连接数据库
开发环境
Dreamweaver CC 2018
Eclipse EE
MySQL 5.7
完成结果
实现学生信息管理系统,能够对学生信息进行查看、增加、修改、删除、搜索、排序等功能;
不包含任何框架,如JQurry;
一、前端页面编写
使用DW CC2018将整个系统的页面静态的编写出来。完成情况如下图所示: HTML的部分没有太大的问题,在这里也不再赘述和放置源码。 静态页面编写完成后,即可在Eclipse中新建JSP文件,将HTML代码放入。
二、导入相关依赖包
在整个系统中将会需要用到的第三方包有下列几个: 这些包都可以在Maven的第三方包下载网页下载。
三、创建数据库
在MySQL数据库中提前放入我们所需要的数据。 这里根据我的需要构建如下数据表: 并放入几行数据。
四、构建Servlet相关类
在构建服务端Servlet之前,我们需要根据java类的功能创建如下三个包:
Servlet包(用来存放Servlet类)
dao包(用来存放使用第三方库的接口或类)
entity包(实体包,用来存放实体类对象)
这样分有一个好处就是分门别类,结构比较清晰。
下面我们分别说明各个类的作用及内容
1、实体类:Student.java
我们首先建立一个实体类方便我们对数据库中每一行的数据对象进行管理。 Student类的内容可以和数据库中的字段一一对应。
public class Student {
private String id;
private String name;
private String classes;
private String phone;
private String mail;
private float grade_web;
private float grade_learning;
public Student ( String id, String name, String classes, String phone, String mail, float grade_web,
float grade_learning) {
this . id = id;
this . name = name;
this . classes = classes;
this . phone = phone;
this . mail = mail;
this . grade_web = grade_web;
this . grade_learning = grade_learning;
}
}
2、Servlet连接数据库父类:SQL.java
在这个类中我们会使用JDBC来连接数据库。
private static String dbUrl = "jdbc:mysql://localhost:3306/studentinfo?characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false" ;
private static String name;
private static String password;
private static String jdbcName = "com.mysql.jdbc.Driver" ;
private Connection connection = null;
在这其中我们先初始化以上几个变量。其中dburl中 “localhost:3306”是数据库配置时分配的端口号;“studentinfo”是我们要连接的数据库的名称。 然后我们需要初始化登录MySQL时的用户名和密码;
连接数据库:
protected Connection connectSQL ( ) {
connection = null;
try {
Class. forName ( jdbcName) ;
connection = DriverManager. getConnection ( dbUrl, name, password) ;
System. out. println ( "MySQL数据库连接成功" ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
System. out. println ( "MySQL数据库连接失败" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
System. out. println ( "数据库驱动异常" ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
System. out. println ( "连接数据库时其他异常" ) ;
}
return connection;
}
关闭数据库:
protected static void closeSQL ( Connection con, PreparedStatement pstmt, ResultSet rs) {
try {
if ( rs != null)
rs. close ( ) ;
if ( pstmt != null)
pstmt. close ( ) ;
if ( con != null)
con. close ( ) ;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
System. out. println ( "MySQL关闭失败" ) ;
}
System. out. println ( "MySQL关闭成功" ) ;
}
数据库操作:
public int executeUpdate ( String sql, Object[ ] obj) {
connection = connectSQL ( ) ;
PreparedStatement pstmt = null;
try {
pstmt = prepareStatement ( connection, sql, obj) ;
int i = pstmt. executeUpdate ( ) ;
return i;
} catch ( SQLException e) {
e. printStackTrace ( ) ;
return 0 ;
} finally {
closeSQL ( connection, pstmt, null) ;
}
}
protected PreparedStatement prepareStatement ( Connection con, String sql, Object [ ] obj) {
PreparedStatement pstmt= null;
try {
int index= 1 ;
pstmt = con. prepareStatement ( sql) ;
if ( pstmt!= null&& obj!= null) {
for ( int i = 0 ; i < obj. length; i++ ) {
pstmt. setObject ( index, obj[ i] ) ;
index++ ;
}
}
} catch ( SQLException e1) {
e1. printStackTrace ( ) ;
}
return pstmt;
}
通过上述三个部分的内容我们已经可以连接数据库、关闭数据库和对数据库进行操作了。接下来就是针对每一个数据表进行对应需要的功能了。
3、Student数据表操作类:StudentSQL.java
这个类需要继承上面建立的SQL类,作为其子类。 因为上面这个父类其实可以看做是一个接口,并没有细化到每一个数据表的每一个操作。因此我们需要在这个StudentSQL类中实现一些我们需要的方法函数,如对Student数据表的增删查改等方法。
根据我们系统的需要我们可以构造一下几个方法:
(1)遍历数据、显示数据表中所有信息
根据SQL里的方法我们直接构造出这样的方法:
public List< Student> search ( String sql, Object. . . params) {
List< Student> list = new ArrayList < Student> ( ) ;
Connection con= this . connectSQL ( ) ;
PreparedStatement pstmt= null;
ResultSet rs= null;
try {
pstmt= this . prepareStatement ( con, sql, params) ;
rs= pstmt. executeQuery ( ) ;
while ( rs. next ( ) ) {
Student student= new Student ( rs. getString ( 1 ) , rs. getString ( 2 ) , rs. getString ( 3 ) , rs. getString ( 4 ) , rs. getString ( 5 ) , rs. getFloat ( 6 ) , rs. getFloat ( 7 ) ) ;
list. add ( student) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
closeSQL ( con, pstmt, rs) ;
}
return list;
}
public List< Student> findall ( ) {
String sql= "SELECT * FROM student" ;
return search ( sql) ;
}
接下来的其他对数据库的操作都可以根据这个来改写了
(2)条件查询、查询是否存在该条记录 在这个数据表中每一条记录有一个唯一主键:学号id,我们可以根据这唯一主键进行条件搜索,以此判断是否存在该条记录。
public boolean findone ( Student student) {
String sql= "select * from student where id=" + student. getId ( ) ;
List< Student> list= search ( sql) ;
if ( list. isEmpty ( ) ) {
System. out. println ( "不存在对应记录" ) ;
return false ;
}
else {
System. out. println ( "存在该条记录" ) ;
return true ;
}
(3)新增一条记录 在新增记录的时候需要注意的一点是,如果学号id已存在,即数据库中已存在该条记录,那么应该无法插入,因此,在插入前我们先进行一步判断,判断该记录是否存在,若不存在,则插入。
public int insert ( Student student) {
boolean existed= findone ( student) ;
if ( ! existed) {
String sql= "INSERT INTO student (id,name,class,phone,mail,grade_web,grade_learning) VALUE(?,?,?,?,?,?,?)" ;
return executeUpdate ( sql, new Object [ ] { student. getId ( ) , student. getName ( ) , student. getClasses ( ) , student. getPhone ( ) , student. getMail ( ) , student. getGrade_web ( ) , student. getGrade_learning ( ) } ) ;
}
else
return 0 ;
}
(4)修改一条记录 同样在修改一条记录的时候我们也需要进行记录存在与否的判断,只有存在该条记录我们才能进行修改。
public int update ( Student student) {
boolean existed= findone ( student) ;
if ( existed) {
String sql= "update student set id=?,name=?,class=?,phone=?,mail=?,grade_web=?,grade_learning=? where id=?" ;
return executeUpdate ( sql, new Object [ ] { student. getId ( ) , student. getName ( ) , student. getClasses ( ) , student. getPhone ( ) , student. getMail ( ) , student. getGrade_web ( ) , student. getGrade_learning ( ) , student. getId ( ) } ) ;
}
else
return 0 ;
}
(5)删除一条记录 与修改一条记录的思路相同,判断存在性、删除。
public int delete ( Student student) {
boolean existed= findone ( student) ;
if ( existed) {
String sql= "delete from student where id=?" ;
return executeUpdate ( sql, new Object [ ] { student. getId ( ) } ) ;
}
else
return 0 ;
}
(6)条件查询、根据一个字段值进行查询 根据某一个字段和一个关键词来进行搜索,类似于上面查询记录是否存在的升级版。
public List< Student> find_condition ( String row, String condition) {
String sql = "select * from student where " + row + " = \"" + condition + "\"" ;
return search ( sql) ;
}
我对数据库不是很熟悉,不知道MySQL可不可以进行全局搜索,即不需要字段进行关键词的匹配搜索。有哪位大佬知道的,可以分享一下,一起讨论,学习。
一个与数据库相关的类就已经构造完成了。接下来就是构造Servlet类,以此作为服务端主体。接下来,我会根据具体功能结合前端JSP的内容进行分析。
五、具体功能实现
1、页面内容的加载
当页面在首次加载的时候就应该默认显示出所有记录,即当页面元素全部加载完毕之后前端需要发送一个请求给服务端,服务端根据请求内容(这里就是遍历数据库并返回所有结果)返回给客户端结果。我采用的方式是Ajax发送请求的方式。
通过调用JS里面 window.onload() 函数就可以完成加载完页面元素时的下一步操作。
window. onload = function ( ) {
var whole_page= document. getElementById ( "whole_page" ) ;
whole_page. style. width= ( window. screen. availWidth- 15 ) + "px" ;
whole_page. style. height= window. screen. availHeight+ "px" ;
requestAjax ( "show_all_student" ) ;
}
通过requestAjax函数进行Ajax请求。
Ajax请求的具体操作很简单,网上也有很多教程和例子,我就直接放上我的代码了。
var req;
function requestAjax ( param) {
var url= "ShowServlet?control=" + param;
if ( window. XMLHttpRequest) {
req = new XMLHttpRequest ( ) ;
}
else if ( window. ActiveXObject) {
req = new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
}
req. open ( "POST" , url, true ) ;
req. onreadystatechange = callback;
req. send ( null ) ;
}
在Ajax请求之后返回的内容和操作都将在callback回调函数中进行。 我们先看服务端接受ajax请求。 在上面Ajax请求中,我们可以看到url是ShowServlet ,也就是会向ShowServlet发送请求。 问号?后面的是请求所带的参数,参数以键值对的形式存在:健名=键值 ,此时我的参数为:control=show_alll_student 就可以被发送给服务端。 接下来我们还设置了请求的方式:在req.open函数中设置了以POST请求 的方式。服务器端就将在doPost()函数中接收请求。
需要注意的是:我们在传参和后面传递值得时候都需要注意一点就是 编码方式要统一,建议都采用UTF-8的编码方式进行传值,否则会出现中文乱码的情况。 首先设置编码方式: request.setCharacterEncoding(“utf-8”); response.setCharacterEncoding(“utf-8”); response.setContentType(“text/html;charset=utf-8”);
在通过getParameter方法获取传递过来的参数。
String control= request. getParameter ( "control" ) ;
List< Student> list = null;
if ( control== null) {
return ;
}
else if ( control. equals ( "show_all_student" ) )
list= studentSQL. findall ( ) ;
通过这样的方式我们就可以将我们所需要的记录保存到一个ArrayList中了,可这样的对象数组的形式我们是无法传递回客户端的。因此,我们要做出一定的改变。 一个方法就是将这些数据转化成JSON数据,再转化成JSONString,这样就可以传递JSONString了。
我们可以通过JSONArray的数据结构保存多个JSON对象。
for ( Student student: list) {
JSONObject json = new JSONObject ( ) ;
json. put ( "id" , student. getId ( ) ) ;
json. put ( "name" , student. getName ( ) ) ;
json. put ( "classes" , student. getClasses ( ) ) ;
json. put ( "phone" , student. getPhone ( ) ) ;
json. put ( "mail" , student. getMail ( ) ) ;
json. put ( "grade_web" , student. getGrade_web ( ) ) ;
json. put ( "grade_learning" , student. getGrade_learning ( ) ) ;
jsonArray. add ( json) ;
}
PrintWriter out = response. getWriter ( ) ;
out. print ( jsonArray) ;
out. flush ( ) ;
out. close ( ) ;
这样,服务端的工作就结束了,已经将值传递出去了。现在轮到客户端来接收这些数据了。
var dataspan= document. getElementById ( "data" ) ;
var data= "" ;
function callback ( ) {
if ( req. readyState == 4 && req. status == 200 ) {
var jsonArray_str = req. responseText;
data= dataspan. innerHTML;
var jsonArray = JSON . parse ( jsonArray_str) ;
for ( json in jsonArray) {
var data_one= " "+ jsonArray[ json] . id+ " "+ " "+ jsonArray[ json] . name+ " "+ " "+ jsonArray[ json] . classes+ " "+ " "+ jsonArray[ json] . phone+ " "+ " "+ jsonArray[ json] . mail+ " "+ " "+ jsonArray[ json] . grade_web+ " "+ " "+ jsonArray[ json] . grade_learning+ " ";
var tail = ' + ' οnclick="popup_window(this)"' + '>编辑 + ' οnclick="delete_note(this)"' + ' >删除 ';
data_one= ""+ data_one+ tail+ " " ;
data+= data_one;
}
dataspan. innerHTML= data;
}
}
客户端接收到这些JSONString之后又转化成原来的JSONArray,通过遍历我们就能得到我们想要的数据。 要想将这些数据按照网页的内容框架显示出来,我们还需要下面几步调整。
首先,确定我们要将数据放入到一个表格 中,表头是固定的。name我们提前写好表头:
< table id= "data" >
< tr>
< th rowspan= "2" > 学号< / th>
< th rowspan= "2" > 姓名< / th>
< th rowspan= "2" > 班级< / th>
< th rowspan= "2" > 电话< / th>
< th rowspan= "2" > 邮箱< / th>
< th colspan= "2" > 学科成绩< / th>
< th rowspan= "2" > 操作< / th>
< / tr>
< tr>
< th> Web技术< / th>
< th> 机器学习< / th>
< / tr>
< / table>
有很多种方式将数据放入到这个表格中,我采用的是直接将内容写入到表格的innerHTML中。也就是上面callback函数中,先获取了表格(id=data)的innerHTML,此时还只是表头,接下来,将数据通过data这个String一一写入;最后再放入到表格的innerHTML中。
到这里,我们的显示数据的过程就已经完成了。 如果现在我们运行客户端和服务端我们就可以看到一个初始默认显示全部记录的结果。
2、添加学生记录
添加学生记录客户端需要有所输入,这时我们采用表单的方式就会方便很多。 这里我设置了一个div来让用户填写表单,当点击添加学生按钮时,显示div,其余时刻,或div内点击取消时,隐藏div。可以看作是一个简易版的网页弹窗的形式。 只需要设置display方式就可以了。 用户就可以根据提示填写表单。最后点击确定提交表单。 在定义表单时我们就可以定义请求的地址和请求的方式:
< form class = " new_window_form" method = " get" action = " ShowServlet" >
ShowServlet就可以通过GET方式进行请求。 在服务端这边,还是一样
先设置编码方式:
request. setCharacterEncoding ( "utf-8" ) ;
response. setCharacterEncoding ( "utf-8" ) ;
response. setContentType ( "text/html;charset=utf-8" ) ;
接收参数 通过request.getParameter()方法获取参数,在这里就是表单的内容。获取到单独的一条条String内容后我们可以构造一个Student对象,把数据放入其中,方便管理和下一步的操作。
String id = request. getParameter ( "id" ) ;
String name = request. getParameter ( "name" ) ;
String classes = request. getParameter ( "class" ) ;
String phone = request. getParameter ( "phone" ) ;
String mail = request. getParameter ( "mail" ) ;
float grade_web = Float. parseFloat ( request. getParameter ( "grade_web" ) ) ;
float grade_learning = Float. parseFloat ( request. getParameter ( "grade_learning" ) ) ;
Student student = new Student ( id, name, classes, phone, mail, grade_web, grade_learning) ;
最后调用StudentSQL中的insert函数就可以插入数据库了。然后通过:
response. sendRedirect ( "index.jsp" ) ;
返回原来的index.jsp。
3、编辑学生记录
编辑和新建一样都是需要用户输入来进行操作的,因此还是通过表单的方式进行。只需要动态的方式改变表单的标题和内容就可以了,这样就只需要一个表单。 同新建不同的是,编辑时,我们需要预留原来的值在表单当中。 而我们发现,表格的每一行后面都有一个编辑,那么问题来了:如何区分用户点击的是哪个行的编辑呢? 只有确定了用户点击的是哪一行,我们才能将值赋在表单当中。
这里有两种方法提供参考:
动态赋给编辑一个id; id的值可以为整条记录或是该条记录的学生id号,但这样的方式,在弹出表单的时候还要进行一次Ajax请求来获取表单的其他值的内容。
通过兄弟结点的方式获得表格该行其他列的内容 查询相关资料后我们发现,可以通过parentNode和children来获取一个结点的父节点和子节点,这样我们就可以获取到一个结点的兄弟节点,即一个表格的一行的其他内容。
这里我采用的是第二种方法。
else {
document. getElementById ( "window_title" ) . innerHTML= "编辑一条记录" ;
document. getElementById ( "submit_btn" ) . value= "edit" ;
document. getElementById ( "id" ) . value = btn. parentNode. parentNode. children[ 0 ] . textContent;
document. getElementById ( "name" ) . value = btn. parentNode. parentNode. children[ 1 ] . textContent;
document. getElementById ( "class" ) . value = btn. parentNode. parentNode. children[ 2 ] . textContent;
document. getElementById ( "phone" ) . value = btn. parentNode. parentNode. children[ 3 ] . textContent;
document. getElementById ( "mail" ) . value = btn. parentNode. parentNode. children[ 4 ] . textContent;
document. getElementById ( "grade_web" ) . value = btn. parentNode. parentNode. children[ 5 ] . textContent;
document. getElementById ( "grade_learning" ) . value = btn. parentNode. parentNode. children[ 6 ] . textContent;
}
获取了该行数据的其他值,用户进行编辑更改,点击确定按钮提交表单。接下来的这些操作就和新建一样了。服务端接收到这些参数后,调用StudentSQL的update函数就可以修改数据库中的值了。
4、删除学生记录
删除学生记录不需要用户进行输入我们就可以不用表单的形式,而采用Ajax请求的方式进行删除。
和编辑一样,我们先获取到一个点击删除的该行的数据,因为删除在数据库操作时只需要用到一个唯一标识符:主键学号id即可,因此我们将学号id通过Ajax请求传递给服务端。
服务端接收到学号id后,直接调用StudentSQL.delete()方法就可以完成数据库的删除操作了。
**到目前为止,整个学生信息管理系统的基本功能就已经完成了。接下来就是一些拓展和完善部分**
六、拓展与完善
1、数据有效性
在新建和编辑的时候我们可以验证输入内容的有效性和合法性。如输入的学号是否为正整数纯数字、电话号码、邮箱是否为正确格式的电话号码和邮箱、输入的成绩的值是否在0~100以内,还有一个重要的内容就是输入不能为空。
验证有效性最简单的方法就是正则表达式。
function check_id ( element) {
var id_text= element. value;
var id_msg = document. getElementById ( "id_msg" ) ;
if ( id_text. length== 0 )
id_msg. innerHTML= "学号不能为空!" ;
else if ( ! ( /^[0-9]\d*$/ . test ( id_text) ) )
id_msg. innerHTML= "请输入正确的学号!" ;
else
id_msg. innerHTML= "" ;
}
function check_phone ( element) {
var phone_msg= document. getElementById ( "phone_msg" ) ;
var phone_text= element. value;
if ( ! ( /^1[3456789]\d{9}$/ . test ( phone_text) ) )
phone_msg. innerHTML= "请填写正确的手机号码!" ;
else
phone_msg. innerHTML= "" ;
}
function check_mail ( element) {
var mail_msg= document. getElementById ( "mail_msg" ) ;
var mail_text= element. value;
if ( ! ( /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/ . test ( mail_text) ) )
mail_msg. innerHTML= "请填写正确的邮箱地址!" ;
else
mail_msg. innerHTML= "" ;
}
function check_grade ( element) {
var web_msg= document. getElementById ( "web_msg" ) ;
var learning_msg= document. getElementById ( "learning_msg" ) ;
var grade= parseFloat ( element. value) ;
if ( grade< 0.0 || grade> 100 ) {
if ( element. id== "grade_web" )
web_msg. innerHTML= "请输入正确的成绩!" ;
else if ( element. id== "grade_learning" )
learning_msg. innerHTML= "请输入正确的成绩!" ;
}
else {
if ( element. id== "grade_web" )
web_msg. innerHTML= "" ;
else if ( element. id== "grade_learning" )
learning_msg. innerHTML= "" ;
}
}
在表单填写过程中,可以采用onblur 函数来调用以上这些函数,当输入框失去焦点时进行判断。
< input type = " text" autocomplete = " off" placeholder = " 学号" name = " id" id = " id" onblur = " check_id(this)" required />
2、搜索框
在编写静态页面时,我们就已经设置了一个搜索框,现在我们来实现搜索框的功能。我们这里的搜索框有两种:
数据库搜索框,即在数据库中搜索满足条件的记录,显示对应记录。
另一种是页面搜索框,即搜索页面内容,并将结果高亮显示。
下面分别实现两种搜索框。
(1)数据库搜索框 对数据库进行搜索时,因为只有一个搜索框,没有对应的字段值,无法通过一个“select”和“where”来进行搜索,因此我们在进行数据库搜索的时候就需要遍历数据库的字段名,先遍历字段的名字,在分别赋值给”where“来进行搜索。
public List< String> getColumn ( Object. . . params) {
List< String> list= new ArrayList < String> ( ) ;
String sql = "desc student" ;
Connection con= this . connectSQL ( ) ;
PreparedStatement pstmt= null;
ResultSet rs= null;
try {
pstmt= this . prepareStatement ( con, sql, params) ;
rs= pstmt. executeQuery ( ) ;
while ( rs. next ( ) ) {
String string = rs. getString ( 1 ) ;
list. add ( string) ;
}
} catch ( SQLException e) {
e. printStackTrace ( ) ;
} finally {
closeSQL ( con, pstmt, rs) ;
}
return list;
}
接下来在客户端JS中写调用的函数,进行服务端请求,采用表单,Ajax等形式都可以,我这里采用的是Ajax的形式。
搜索框点击搜索按钮调用onclick 函数,在函数中我们就可以进行Ajax请求。
function search_database ( ) {
var key = document. getElementById ( "search_key" ) . value;
if ( key== "" ) {
requestAjax ( "control=show_all_student" ) ;
return ;
}
var param = "control=search&value=" + key;
requestAjax ( param) ;
}
服务器端一样的响应请求。
else if ( control. equals ( "search" ) ) {
String key = request. getParameter ( "value" ) ;
List< String> columnList = studentSQL. getColumn ( ) ;
for ( String column: columnList) {
List< Student> array = new ArrayList < Student> ( ) ;
array = studentSQL. find_condition ( column, key) ;
list. addAll ( array) ;
}
}
这样就可以完成对一个关键词的搜索并保存到一个List中返回给客户端前端显示。
拓展: 一般来说我们在进行搜索的时候都希望能有模糊搜索的功能,在进行数据库搜索时可以进行模糊搜索。 只需要改动一点点就可以了:只需要在数据库操作类StudentSQL类中的条件搜索函数中改成利用正则表达式进行搜索就可以了。
public List< Student> find_condition ( String row, String condition) {
String sql = "select * from student where " + row + " REGEXP \"" + condition + "\"" ;
return search ( sql) ;
}
如果当我们搜索“2”时,理论上应该是显示“小花”和小刚两条记录。
但是会出现下面这种情况,原因是一条记录匹配了2次或多次,我们要把重复的记录去掉。 我们可以利用Set没有重复性的特点,将ArrayList转化为Set,来去重。 考虑到对象类型的Set集合无法去重,我们先在Student类里重写equals方法 和hashCode方法 。
@Override
public boolean equals ( Object obj) {
if ( obj == null)
return false ;
if ( this == obj)
return true ;
if ( obj instanceof Student ) {
Student student = ( Student) obj;
if ( student. getId ( ) . equals ( this . id)
&& student. getName ( ) . equals ( this . name)
&& student. getClasses ( ) . equals ( this . classes)
&& student. getPhone ( ) . equals ( this . phone)
&& student. getMail ( ) . equals ( this . mail)
&& student. getGrade_web ( ) == this . grade_web
&& student. getGrade_learning ( ) == this . grade_learning)
return true ;
}
return false ;
}
@Override
@SuppressWarnings ( "deprecation" )
public int hashCode ( ) {
Float float_web = new Float ( grade_web) ;
Float float_learning = new Float ( grade_learning) ;
return id. hashCode ( ) * name. hashCode ( ) * classes. hashCode ( ) * phone. hashCode ( ) * mail. hashCode ( ) * float_web. hashCode ( ) * float_learning. hashCode ( ) ;
}
关于为什么要重写而不能直接使用set的去重功能,具体可以参考这篇博文。
https://blog.csdn.net/lavorange/article/details/80420087
经过set去重我们就可以完后曾模糊搜索的功能了。
else if ( control. equals ( "search" ) ) {
String key = request. getParameter ( "value" ) ;
List< String> columnList = studentSQL. getColumn ( ) ;
for ( String column: columnList) {
List< Student> array = new ArrayList < Student> ( ) ;
array = studentSQL. find_condition ( column, key) ;
list. addAll ( array) ;
}
Set< Student> set = new HashSet < Student> ( list) ;
List< Student> temp_list = new ArrayList < Student> ( set) ;
list= temp_list;
}
最后向前端输出list内容就可以了。
(2)页面内容搜索框 页面内容搜索框就只包含前端的内容了,不需要进行后端的操作。在搜索框中输入关键词,能够将表格中的搜索结果高亮显示出来。
大概思路如下: 首先通过innerHTML 获取到我们要搜索的区域的所有内容(包含标签代码!!! ),然后通过split函数 将关键词两边的内容分开,然后给关键词加上style属性,再用join函数 合在一起就可以了。
但是这样做有一个弊端,就是,如果搜索的内容是某些关键词或标签(如搜索“div”、“span”)时,就会出现报错,因为你将代码标签也算作字符串的一部分了。因此要解决这个去掉标签的问题。
我也没有想到一个很好的方法,网上查到的资料有说可以使用正则表达式来去标签,鉴于当前系统只需要搜索表格内容,即网页内容不复杂,甚至说很单一,因为只有
和两种标签,所以我将 标签一同加入到搜索的关键词当中,这样就不会出现搜索内容为标签时报错的情况了。
理论上是这个样子的,因为还是不太熟悉正则表达式,暂时还没有实现出该功能。
七、一点感想
写完一整个系统,真实感受就是全栈式开发好累(其实还是自己太菜了)。学到了许多新东西,但是还是有很多地方不会的,像上面的搜索,还有其他的一些骚操作都没有。路漫漫其修远兮啊。 花了很长时间写这篇博文记录一下整个开发过程,不断回顾和反思当初一开始没有写好的地方。挺有收获的。
八、完整源代码下载
下载地址
你可能感兴趣的:(Web开发)
PHP环境搭建详细教程
好看资源平台
前端 php
PHP是一个流行的服务器端脚本语言,广泛用于Web开发。为了使PHP能够在本地或服务器上运行,我们需要搭建一个合适的PHP环境。本教程将结合最新资料,介绍在不同操作系统上搭建PHP开发环境的多种方法,包括Windows、macOS和Linux系统的安装步骤,以及本地和Docker环境的配置。1.PHP环境搭建概述PHP环境的搭建主要分为以下几类:集成开发环境:例如XAMPP、WAMP、MAMP,这
Spring MVC 全面指南:从入门到精通的详细解析
一杯梅子酱
技术栈学习 spring mvc java
引言:SpringMVC,作为Spring框架的一个重要模块,为构建Web应用提供了强大的功能和灵活性。无论是初学者还是有一定经验的开发者,掌握SpringMVC都将显著提升你的Web开发技能。本文旨在为初学者提供一个全面且易于理解的学习路径,通过详细的知识点分析和实际案例,帮助你快速上手SpringMVC,让学习过程既深刻又高效。一、SpringMVC简介1.1什么是SpringMVC?Spri
基于JavaWeb开发的Java+SpringMvc+vue+element实现上海汽车博物馆平台
网顺技术团队
成品程序项目 java vue.js 汽车 课程设计 spring boot
基于JavaWeb开发的Java+SpringMvc+vue+element实现上海汽车博物馆平台作者主页网顺技术团队欢迎点赞收藏⭐留言文末获取源码联系方式查看下方微信号获取联系方式承接各种定制系统精彩系列推荐精彩专栏推荐订阅不然下次找不到哟Java毕设项目精品实战案例《1000套》感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人文章目录基
两种方法判断Python的位数是32位还是64位
sanqima
Python编程 电脑 python 开发语言
Python从1991年发布以来,凭借其简洁、清晰、易读的语法、丰富的标准库和第三方工具,在Web开发、自动化测试、人工智能、图形识别、机器学习等领域发展迅猛。 Python是一种胶水语言,通过Cython库与C/C++语言进行链接,通过Jython库与Java语言进行链接。 Python是跨平台的,可运行在多种操作系统上,包括但不限于Windows、Linux和macOS。这意味着用Py
什么是 PHP? 为什么用 PHP? 谁在用 PHP?
m0_37438181
永远学习 php 开发语言
一、什么是PHP?PHP(HypertextPreprocessor,超文本预处理器)是一种广泛应用于Web开发的通用开源脚本语言。PHP主要用于服务器端编程,可以嵌入HTML中,与数据库进行交互,生成动态网页内容。它具有以下特点:简单易学:语法相对简单,容易上手,对于初学者来说是一个不错的选择。跨平台性:可以在多种操作系统上运行,如Windows、Linux、Unix等。丰富的函数库:提供了大量
SpringBoot2:web开发常用功能实现及原理解析-整合EasyExcel实现Excel导入导出功能
生产队队长
Spring All excel spring boot
1、工程包结构主要是这5个Java类2、导入EasyExcel包这里同时贴出其他相关springboot的基础包org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-devtoolsruntimetrueorg.springframework.bootspring-boot-config
Web开发详解
你可以自己看
前端
要做Web开发,就好像你在厨房里要做一顿丰盛的晚餐,从准备食材到最后上桌,整个过程得协调得当。Web开发的流程有前端、后端、数据库、API,以及其他的工具和技术来共同组成。别担心,听起来复杂,但我会给你讲得生动有趣,让你感受到Web开发的美妙。1.前端开发(Web开发的颜值担当)前端就是用户能直接看到和互动的部分,给人的第一印象尤为重要,简直就是网站的“面子工程”。1.1HTML-构建页面骨架HT
React 前端应用结合 Nginx 部署指南及常见错误排查
蜗牛去旅行吧
前端 react.js nginx
在现代Web开发中,React已成为构建用户界面的流行选择,而Nginx则是一个高性能的Web服务器,广泛用于静态文件的托管和负载均衡。在本篇博客中,我们将详细介绍如何将一个React应用部署到Nginx上,并探讨在部署过程中可能遇到的常见错误及其解决方案。部署步骤1.准备React应用首先,确保你已经创建了一个React应用。如果还没有,可以使用CreateReactApp快速生成一个基础项目:
Java 学习路线:语言、框架、中间件与数据库
高危型
java
Java是一门功能强大、应用广泛的编程语言,适用于企业级应用、Web开发、大数据处理、Android开发等各种场景。这里为大家介绍了一下我认为较为合适的学习路线一、Java基础1.1Java语言基础1.1.1安装JDK和IDE安装JDK:下载JDK:访问Oracle官网,下载最新的JavaDevelopmentKit(JDK)。安装JDK:按照操作系统要求安装JDK并配置环境变量。Windows上
Json格式化
微赚淘客系统@聚娃科技
json
Json格式化大家好,我是微赚淘客机器人的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!Json格式化:让数据更亮眼,解密Json的奇妙世界在现代Web开发中,Json(JavaScriptObjectNotation)已经成为数据交换的标准之一。然而,对于人眼来说,一串紧凑的Json字符串并不直观,而经过格式化处理后的Json却如同一幅清晰的画面。本文将深入探讨Json格式化的重要性、实现方法以
CTF——web方向学习攻略
一则孤庸
CTF 网络安全 CTF
1计算机基础操作系统:熟悉Linux命令,方便使用Kali。网络技术:HCNA、CCNA。编程能力:拔高项,有更好。2web应用HTTP协议:必须掌握web开发框架web安全测试3数据库数据库基本操作SQL语句数据库优化4刷题
生成一个完整的App代码通常不会仅仅通过单一的文件或几种语言的简单组合来完成,因为App的开发涉及前端用户界面、后端逻辑处理、数据库管理以及可能的第三方服务集成等多个方面。不过,我可以为你提供一个概念
NewmanEdwarda2
前端 ui 数据库
前端(用户界面)yinanjinying.comHTML/CSS/JavaScript(原生Web开发)对于简单的WebApp,你可以直接使用HTML来构建页面结构,CSS来设置样式,JavaScript来添加交互性。React(JavaScript/TypeScript)对于更复杂的单页应用(SPA),React是一个流行的选择。它允许你构建可复用的UI组件。Flutter(Dart)如果你想要
利用Leaflet.js创建交互式地图:绘制固定尺寸的长方形
小金子J
前端框架 WebGIS javascript 开发语言 ecmascript 前端框架 信息可视化
在现代Web开发中,交互式地图已成为展示地理位置数据的重要工具。Leaflet.js是一个轻量级、功能丰富的开源JavaScript库,用于构建移动友好的交互式地图。在本文中,我们将探讨如何利用Leaflet.js在地图上绘制一个固定尺寸的长方形,扩展我们之前实现的单个多边形绘制功能。背景我们已经实现了一个功能,允许用户在地图上绘制任意形状的多边形。现在,我们希望在此基础上增加一个新功能:用户可以
asp.net core的入门教学
21软件外包1班-庞兴南
asp.net 后端
什么是ASP.NETCoreasp.netcore是一个基于HTML和ASP的动态Web开发框架,主要用于web应用程序的开发。它是一个轻量级框架,使用HTML、ASP、CSS、JavaScript等技术。它易于使用和部署,可以快速构建web应用程序。asp.netcore提供了丰富的功能,包括模板引擎、文件解析、数据处理和用户管理等。本文将介绍asp.netcore的主要功能和特点,并提供使用方
探索未来Web开发的精简之道:ASP.NET Core 8.0 Minimal API 示例项目
尚舰舸Elsie
探索未来Web开发的精简之道:ASP.NETCore8.0MinimalAPI示例项目随着微服务和云原生架构的兴起,轻量级API成为了开发社区的新宠。ASP.NETCore8.0MinimalAPIExample正是这样一个项目,它集成了最新技术栈,简化了API开发过程,让开发者能够以最少的代码实现强大的功能。本文将带你深入了解这一开源杰作,揭示其技术魅力,并探索其应用场景。项目介绍ASP.NET
Servlet 文件上传
lly202406
开发语言
Servlet文件上传在JavaWeb开发中,文件上传是一个常见的需求。Servlet作为一种服务器端的技术,可以轻松实现文件上传功能。本文将详细介绍如何在Servlet中处理文件上传,包括环境配置、代码实现以及常见问题的解决方案。环境配置1.添加依赖在项目的pom.xml文件中,添加ApacheCommonsFileUpload库的依赖。这个库提供了易于使用的API来处理文件上传。commons
异步任务处理:FastAPI结合Celery的实战典范
赖蓉旖Marlon
异步任务处理:FastAPI结合Celery的实战典范fastapi-celeryExampleofhowtohandlebackgroundprocesseswithFastAPI,Celery,andDocker项目地址:https://gitcode.com/gh_mirrors/fas/fastapi-celery在现代Web开发中,异步处理和后台任务调度成为了提高应用性能与响应速度的关键
前后端时间转换的那些常见问题及处理方法
繁依Fanyi
状态模式 python 算法 java 开发语言 android github
在现代的Web开发中,前后端分离的架构已经成为主流,尤其是在SpringBoot和Vue.js的组合中。开发者在这种架构下经常遇到的一个问题就是如何处理时间的转换和显示。前端和后端对时间的处理方式不同,可能会导致时间在传递过程中出现问题,比如时区不同步、格式不一致等。因此,本文将详细讨论在SpringBoot+Vue前后端分离架构中如何处理时间转换问题,并提供一些解决方案。一、前后端时间处理的常见
HTML/CSS/JavaScript 全景指南:构建现代Web应用的基石
一杯梅子酱
技术栈学习 前端 html css
引言:在Web开发中,HTML、CSS和JavaScript是三个不可或缺的技术,它们共同构成了前端开发的核心。本文旨在全面解析这三个技术的关键知识点,探讨它们之间的联系,并通过实际案例加深理解,最后分享一些宝贵的经验总结。一、HTML:内容的骨架1.基本结构标签的使用:,,文本内容:,至链接与图像:,列表:,,表格:,,,表单:,,,,2.语义化标签,,,,,3.案例创建一个简单的网页:Html
Java 学习路线:适合小白的超细学习路线及实例代码
Dreams°123
后端 java eclipse jvm spring tomcat ide intellij-idea
Java学习路线:适合小白的超细学习路线及实例代码一、入门基础1.1、Java基础语法1.2、面向对象编程(OOP)二、核心Java编程2.1、数据结构和算法基础2.2、输入输出(I/O)三、进阶Java编程3.1、多线程编程3.2、网络编程四、高级应用4.1、数据库编程4.2、Web开发4.3、框架与库五、实践项目与进阶学习(留作业啦)5.1、实践项目5.2、持续学习一、入门基础1.1、Java
11- 【JavaWeb】Cookie 、Session、Filter、Listener
weixin_44329069
JavaWeb hive python hadoop
了解Cookie、Session、Filter和Listener是JavaWeb开发中非常重要的部分。1.CookieCookie是服务器在客户端浏览器上存储的小数据片段,用于在不同请求之间保持状态。Cookie通常用于保存用户信息、跟踪会话、保存用户偏好等。示例:创建和读取Cookie设置Cookie(在Servlet中):@WebServlet("/setCookie")publicclass
Rust在Web开发中的并发模型
编程小智星
网络
Rust是一种系统编程语言,以其高效、安全和并发性而著称。随着Web应用规模的不断扩大和复杂性的增加,对并发处理能力的需求也日益突出。Rust作为一种新兴的编程语言,在Web开发中展现出了强大的并发处理能力。本文将深入探讨Rust在Web开发中的并发模型,分析其核心特性以及如何在Web应用中发挥优势。一、Rust并发模型概述Rust的并发模型主要基于其独特的所有权系统和无锁数据结构。所有权系统通过
【Python百日进阶-Web开发-Peewee】Day295 - 查询示例(四)聚合1
岳涛@心馨电脑
Dash python 前端 dash
文章目录14.6聚合14.6.1计算设施数量Countthenumberoffacilities14.6.2计算昂贵设施的数量Countthenumberofexpensivefacilities14.6.3计算每个成员提出的建议数量。Countthenumberofrecommendationseachmembermakes.14.6.4列出每个设施预订的总空位Listthetotalslots
二 整合web开发
guideEmotion
一整合Servlet1通过注解扫描完成Servlet组件的注册1.编写servlet@WebServlet(name="FirstServlet",urlPatterns="/first")publicclassFirstServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletRe
【Python百日进阶-Web开发-Peewee】Day289 - Peewee 的扩展(九)pwiz / 架构迁移(上)
岳涛@心馨电脑
数据库 python dash 前端
文章目录13.15pwiz,模型生成器13.15.1命令行选项13.16架构迁移SchemaMigrations13.16.1示例用法13.16.2支持的操作13.15pwiz,模型生成器pwiz是peewee附带的一个小脚本,能够自省现有数据库并生成适合与底层数据交互的模型代码。如果您已经有一个数据库,pwiz可以通过生成具有正确列关联和外键的骨架代码来给您一个很好的提升。如果您使用安装peew
10个非常基础的 Javascript 问题
2401_86367399
面试辅导大厂内推 javascript 开发语言 ecmascript
作者简介:CSDN全栈领域优质创作者、HDZ核心组成员粉丝福利:粉丝群每周送6-9本书,不定期送各种小礼品(往期获奖记录)直接跳到末尾去评论区领书本文特别适合正在寻找Javascript开发工作的初学者。我搜索了许多Javascript面试问题,这10个对我来说似乎最重要。让我们深入研究一下。1.什么是Javascript?Javascript是一种用于Web开发的编程语言。JavaScript在
在JavaScript中实现简单的发布/订阅模式
2401_85812053
javascript 开发语言 ecmascript
在现代Web开发中,发布/订阅模式是一种常见的设计模式,它允许不同部分的应用程序之间进行解耦和通信。这种模式特别适用于事件驱动的编程模型,能够有效地管理复杂的交互和数据流。本文将详细介绍如何在JavaScript中实现一个简单的发布/订阅模式,包括其工作原理、实现步骤以及实际应用示例。1.理解发布/订阅模式发布/订阅模式是一种消息传递模式,允许对象之间进行通信而不需要彼此直接引用。它主要由两个角色
Gateway Timeout504: 网关超时的完美解决方法
潘多编程
gateway
引言在Web开发中,遇到HTTP状态码504(GatewayTimeout)是相当常见的。这个状态码表示前端服务器(如负载均衡器或代理服务器)作为网关工作时,在尝试访问后端服务器处理请求时未能及时得到响应。本文将探讨导致504错误的原因以及如何有效地诊断和解决这类问题。GatewayTimeout是什么?HTTP状态码504表示前端服务器已经收到了客户端的请求,并且知道应该由哪个后端服务器来处理该
移动WEB开发(第四天)__响应式布局
加蓓努力我先飞
5.移动web开发资料 前端
移动WEB开发(第四天)__响应式布局移动端WEB开发之响应式布局1.0响应式开发原理1.1响应式开发原理1.2响应式布局容器2.0bootstrap的介绍2.1Bootstrap简介2.2bootstrap优点2.3版本简介2.4bootstrap基本使用2.5bootstrap布局容器2.6bootstrap栅格系统3.0阿里百秀案例制作3.1技术选型移动端WEB开发之响应式布局1.0响应式开
如何优化PHP的数据库查询性能提高自己的动手能力?
xiaohuojian1
数据库 php oracle
如何优化PHP的数据库查询性能:提升动手能力与技术基础在Web开发中,数据库是应用程序的核心组成部分。优化数据库查询性能不仅可以显著提高应用的响应速度,还能提升用户体验和系统的可扩展性。本文将探讨如何在PHP中优化数据库查询性能,包括高效查询编写、https://github.com/xhj3/索引使用、缓存策略以及性能监控。1.编写高效的SQL查询编写高效的SQL查询是提升数据库性能的第一步。以
Java 并发包之线程池和原子计数
lijingyao8206
Java计数 ThreadPool 并发包 java线程池
对于大数据量关联的业务处理逻辑,比较直接的想法就是用JDK提供的并发包去解决多线程情况下的业务数据处理。线程池可以提供很好的管理线程的方式,并且可以提高线程利用率,并发包中的原子计数在多线程的情况下可以让我们避免去写一些同步代码。
这里就先把jdk并发包中的线程池处理器ThreadPoolExecutor 以原子计数类AomicInteger 和倒数计时锁C
java编程思想 抽象类和接口
百合不是茶
java 抽象类 接口
接口c++对接口和内部类只有简介的支持,但在java中有队这些类的直接支持
1 ,抽象类 : 如果一个类包含一个或多个抽象方法,该类必须限定为抽象类(否者编译器报错)
抽象方法 : 在方法中仅有声明而没有方法体
package com.wj.Interface;
[房地产与大数据]房地产数据挖掘系统
comsci
数据挖掘
随着一个关键核心技术的突破,我们已经是独立自主的开发某些先进模块,但是要完全实现,还需要一定的时间...
所以,除了代码工作以外,我们还需要关心一下非技术领域的事件..比如说房地产
&nb
数组队列总结
沐刃青蛟
数组队列
数组队列是一种大小可以改变,类型没有定死的类似数组的工具。不过与数组相比,它更具有灵活性。因为它不但不用担心越界问题,而且因为泛型(类似c++中模板的东西)的存在而支持各种类型。
以下是数组队列的功能实现代码:
import List.Student;
public class
Oracle存储过程无法编译的解决方法
IT独行者
oracle 存储过程
今天同事修改Oracle存储过程又导致2个过程无法被编译,流程规范上的东西,Dave 这里不多说,看看怎么解决问题。
1. 查看无效对象
XEZF@xezf(qs-xezf-db1)> select object_name,object_type,status from all_objects where status='IN
重装系统之后oracle恢复
文强chu
oracle
前几天正在使用电脑,没有暂停oracle的各种服务。
突然win8.1系统奔溃,无法修复,开机时系统 提示正在搜集错误信息,然后再开机,再提示的无限循环中。
无耐我拿出系统u盘 准备重装系统,没想到竟然无法从u盘引导成功。
晚上到外面早了一家修电脑店,让人家给装了个系统,并且那哥们在我没反应过来的时候,
直接把我的c盘给格式化了 并且清理了注册表,再装系统。
然后的结果就是我的oracl
python学习二( 一些基础语法)
小桔子
pthon 基础语法
紧接着把!昨天没看继续看django 官方教程,学了下python的基本语法 与c类语言还是有些小差别:
1.ptyhon的源文件以UTF-8编码格式
2.
/ 除 结果浮点型
// 除 结果整形
% 除 取余数
* 乘
** 乘方 eg 5**2 结果是5的2次方25
_&
svn 常用命令
aichenglong
SVN 版本回退
1 svn回退版本
1)在window中选择log,根据想要回退的内容,选择revert this version或revert chanages from this version
两者的区别:
revert this version:表示回退到当前版本(该版本后的版本全部作废)
revert chanages from this versio
某小公司面试归来
alafqq
面试
先填单子,还要写笔试题,我以时间为急,拒绝了它。。时间宝贵。
老拿这些对付毕业生的东东来吓唬我。。
面试官很刁难,问了几个问题,记录下;
1,包的范围。。。public,private,protect. --悲剧了
2,hashcode方法和equals方法的区别。谁覆盖谁.结果,他说我说反了。
3,最恶心的一道题,抽象类继承抽象类吗?(察,一般它都是被继承的啊)
4,stru
动态数组的存储速度比较 集合框架
百合不是茶
集合框架
集合框架:
自定义数据结构(增删改查等)
package 数组;
/**
* 创建动态数组
* @author 百合
*
*/
public class ArrayDemo{
//定义一个数组来存放数据
String[] src = new String[0];
/**
* 增加元素加入容器
* @param s要加入容器
用JS实现一个JS对象,对象里有两个属性一个方法
bijian1013
js对象
<html>
<head>
</head>
<body>
用js代码实现一个js对象,对象里有两个属性,一个方法
</body>
<script>
var obj={a:'1234567',b:'bbbbbbbbbb',c:function(x){
探索JUnit4扩展:使用Rule
bijian1013
java 单元测试 JUnit Rule
在上一篇文章中,讨论了使用Runner扩展JUnit4的方式,即直接修改Test Runner的实现(BlockJUnit4ClassRunner)。但这种方法显然不便于灵活地添加或删除扩展功能。下面将使用JUnit4.7才开始引入的扩展方式——Rule来实现相同的扩展功能。
1. Rule
&n
[Gson一]非泛型POJO对象的反序列化
bit1129
POJO
当要将JSON数据串反序列化自身为非泛型的POJO时,使用Gson.fromJson(String, Class)方法。自身为非泛型的POJO的包括两种:
1. POJO对象不包含任何泛型的字段
2. POJO对象包含泛型字段,例如泛型集合或者泛型类
Data类 a.不是泛型类, b.Data中的集合List和Map都是泛型的 c.Data中不包含其它的POJO
 
【Kakfa五】Kafka Producer和Consumer基本使用
bit1129
kafka
0.Kafka服务器的配置
一个Broker,
一个Topic
Topic中只有一个Partition() 1. Producer:
package kafka.examples.producers;
import kafka.producer.KeyedMessage;
import kafka.javaapi.producer.Producer;
impor
lsyncd实时同步搭建指南——取代rsync+inotify
ronin47
1. 几大实时同步工具比较 1.1 inotify + rsync
最近一直在寻求生产服务服务器上的同步替代方案,原先使用的是 inotify + rsync,但随着文件数量的增大到100W+,目录下的文件列表就达20M,在网络状况不佳或者限速的情况下,变更的文件可能10来个才几M,却因此要发送的文件列表就达20M,严重减低的带宽的使用效率以及同步效率;更为要紧的是,加入inotify
java-9. 判断整数序列是不是二元查找树的后序遍历结果
bylijinnan
java
public class IsBinTreePostTraverse{
static boolean isBSTPostOrder(int[] a){
if(a==null){
return false;
}
/*1.只有一个结点时,肯定是查找树
*2.只有两个结点时,肯定是查找树。例如{5,6}对应的BST是 6 {6,5}对应的BST是
MySQL的sum函数返回的类型
bylijinnan
java spring sql mysql jdbc
今天项目切换数据库时,出错
访问数据库的代码大概是这样:
String sql = "select sum(number) as sumNumberOfOneDay from tableName";
List<Map> rows = getJdbcTemplate().queryForList(sql);
for (Map row : rows
java设计模式之单例模式
chicony
java设计模式
在阎宏博士的《JAVA与模式》一书中开头是这样描述单例模式的:
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式的结构
单例模式的特点:
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
饿汉式单例类
publ
javascript取当月最后一天
ctrain
JavaScript
<!--javascript取当月最后一天-->
<script language=javascript>
var current = new Date();
var year = current.getYear();
var month = current.getMonth();
showMonthLastDay(year, mont
linux tune2fs命令详解
daizj
linux tune2fs 查看系统文件块信息
一.简介:
tune2fs是调整和查看ext2/ext3文件系统的文件系统参数,Windows下面如果出现意外断电死机情况,下次开机一般都会出现系统自检。Linux系统下面也有文件系统自检,而且是可以通过tune2fs命令,自行定义自检周期及方式。
二.用法:
Usage: tune2fs [-c max_mounts_count] [-e errors_behavior] [-g grou
做有中国特色的程序员
dcj3sjt126com
程序员
从出版业说起 网络作品排到靠前的,都不会太难看,一般人不爱看某部作品也是因为不喜欢这个类型,而此人也不会全不喜欢这些网络作品。究其原因,是因为网络作品都是让人先白看的,看的好了才出了头。而纸质作品就不一定了,排行榜靠前的,有好作品,也有垃圾。 许多大牛都是写了博客,后来出了书。这些书也都不次,可能有人让为不好,是因为技术书不像小说,小说在读故事,技术书是在学知识或温习知识,有
Android:TextView属性大全
dcj3sjt126com
textview
android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接。可选值(none/web/email/phone/map/all) android:autoText 如果设置,将自动执行输入值的拼写纠正。此处无效果,在显示输入法并输
tomcat虚拟目录安装及其配置
eksliang
tomcat配置说明 tomca部署web应用 tomcat虚拟目录安装
转载请出自出处:http://eksliang.iteye.com/blog/2097184
1.-------------------------------------------tomcat 目录结构
config:存放tomcat的配置文件
temp :存放tomcat跑起来后存放临时文件用的
work : 当第一次访问应用中的jsp
浅谈:APP有哪些常被黑客利用的安全漏洞
gg163
APP
首先,说到APP的安全漏洞,身为程序猿的大家应该不陌生;如果抛开安卓自身开源的问题的话,其主要产生的原因就是开发过程中疏忽或者代码不严谨引起的。但这些责任也不能怪在程序猿头上,有时会因为BOSS时间催得紧等很多可观原因。由国内移动应用安全检测团队爱内测(ineice.com)的CTO给我们浅谈关于Android 系统的开源设计以及生态环境。
1. 应用反编译漏洞:APK 包非常容易被反编译成可读
C#根据网址生成静态页面
hvt
Web .net C# asp.net hovertree
HoverTree开源项目中HoverTreeWeb.HVTPanel的Index.aspx文件是后台管理的首页。包含生成留言板首页,以及显示用户名,退出等功能。根据网址生成页面的方法:
bool CreateHtmlFile(string url, string path)
{
//http://keleyi.com/a/bjae/3d10wfax.htm
stri
SVG 教程 (一)
天梯梦
svg
SVG 简介
SVG 是使用 XML 来描述二维图形和绘图程序的语言。 学习之前应具备的基础知识:
继续学习之前,你应该对以下内容有基本的了解:
HTML
XML 基础
如果希望首先学习这些内容,请在本站的首页选择相应的教程。 什么是SVG?
SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
SVG 用来定义用于网络的基于矢量
一个简单的java栈
luyulong
java 数据结构 栈
public class MyStack {
private long[] arr;
private int top;
public MyStack() {
arr = new long[10];
top = -1;
}
public MyStack(int maxsize) {
arr = new long[maxsize];
top
基础数据结构和算法八:Binary search
sunwinner
Algorithm Binary search
Binary search needs an ordered array so that it can use array indexing to dramatically reduce the number of compares required for each search, using the classic and venerable binary search algori
12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
刘星宇
c 面试
12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
1.gets()函数
问:请找出下面代码里的问题:
#include<stdio.h>
int main(void)
{
char buff[10];
memset(buff,0,sizeof(buff));
ITeye 7月技术图书有奖试读获奖名单公布
ITeye管理员
活动 ITeye 试读
ITeye携手人民邮电出版社图灵教育共同举办的7月技术图书有奖试读活动已圆满结束,非常感谢广大用户对本次活动的关注与参与。
7月试读活动回顾:
http://webmaster.iteye.com/blog/2092746
本次技术图书试读活动的优秀奖获奖名单及相应作品如下(优秀文章有很多,但名额有限,没获奖并不代表不优秀):
《Java性能优化权威指南》