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开发)
入门 Canvas:Web 绘图的强大工具
Hopebearer_
前端 es6 javascript canva可画
文章目录入门Canvas:Web绘图的强大工具一、Canvas简介二、Canvas的基本用法(一)绘制基本图形(二)绘制文本三、Canvas的应用场景(一)数据可视化(二)游戏开发(三)图像编辑四、Canvas的动画效果五、Canvas的优势与局限性(一)优势(二)局限性六、总结入门Canvas:Web绘图的强大工具在Web开发的广阔天地中,为了满足用户对丰富、交互性强的体验的不断追求,前端技术持
Tomcat从入门到精通:全方位深度解析与实战教程
墨瑾轩
一起学学Java【一】 运维 tomcat java
一、Tomcat入门1.Tomcat简介ApacheTomcat,简称Tomcat,是一个开源的轻量级应用服务器,专为运行JavaServlet和JavaServerPages(JSP)技术设计。它是JavaWeb开发中最常用的Servlet容器之一,遵循JavaServlet和JavaServerPages规范,为开发者提供了一个稳定的、易于使用的部署环境。2.安装与启动安装下载最新版Tomca
PyCharm v2024.3.5 强大的Python IDE工具 支持M、Intel芯片
2401_89264762
python ide pycharm
PyCharm是一种PythonIDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外,该IDE提供了一些高级功能,以用于支持Django框架下的专业Web开发。应用介绍PyCharm是由JetBrains打造的一款PythonIDE,VS2010的重构插件Resharper就是出自
Java Web开发技术解析:从基础到实践的全栈指南
以恒1
java 前端 开发语言
JavaWeb开发技术解析:从基础到实践的全栈指南在互联网技术演进中,JavaWeb凭借其跨平台特性、成熟的生态系统和强大的企业级服务能力,成为构建动态Web应用的核心技术栈。本文从技术组成、开发工具、实战应用三个维度,全面解析JavaWeb的完整技术体系,并结合最新行业实践探讨其演进方向。一、JavaWeb的核心技术组成JavaWeb开发以Servlet和JSP为基石,通过分层架构实现动态网页生
全面掌握Python:从安装到基础再到进阶的系统学习之路(附代码,建议新手收藏)
der丸子吱吱吱
python 学习 开发语言 新手入门 代码
Python,作为一种现代化的高级编程语言,因其简洁易懂的语法和强大的功能,成为了数据科学、人工智能、Web开发等多个领域的首选语言。在这篇文章中,我们将从大学课本的结构来详细介绍Python,帮助大家从零基础开始,逐步深入掌握Python的各个方面。目录第一章:Python简介与安装1.1Python语言概述1.2安装Python1.3Python的开发环境1.4第一个Python程序第二章:基
从 0 到 1 搭建一个 Web 应用项目:详细步骤与踩坑记录
算法探索者
前端
一、引言在当今数字化时代,Web应用无处不在。对于开发者而言,掌握从0到1搭建Web应用项目的技能至关重要。本指南将带你逐步完成一个简单Web应用项目的搭建,分享技术选型思路以及在过程中遇到的问题和解决方案,助力你开启Web开发之旅。二、技术选型(一)前端框架:选择React.js。它具有高效的虚拟DOM机制,能够快速更新页面,提升用户体验。同时,React生态系统丰富,有大量现成的组件库和工具可
python web开发flask库安装与使用
范哥来了
python 前端 flask
要在Python中使用Flask进行Web开发,首先需要安装Flask库。Flask是一个轻量级的Web框架,它使开发者能够快速构建网站或web服务。下面是安装Flask和创建一个简单的Flask应用程序的基本步骤。安装Flask确保您的环境中已经安装了Python(推荐版本3.7或更高)。接着,您可以通过pip来安装Flask。打开命令行工具(如终端或命令提示符),然后执行以下命令:pipins
深入理解Ajax原理
lfsf802
前端技术 ajax xmlhttprequest javascript 服务器 asynchronous
1.概念ajax的全称是AsynchronousJavaScriptandXML,其中,Asynchronous是异步的意思,它有别于传统web开发中采用的同步的方式。2.理解同步异步异步传输是面向字符的传输,它的单位是字符;而同步传输是面向比特的传输,它的单位是桢,它传输的时候要求接受方和发送方的时钟是保持一致的。举个例子来说同步和异步,同步就好像我们买楼一次性支付,而异步就是买楼分期付款。所以
mysql vs oracle
HBryce24
数据库 mysql oracle 数据库
以下是Oracle数据库与MySQL数据库的详细比较,从架构设计、功能特性、性能、适用场景等多个维度进行综合分析:1.基础特性与定位Oracle:定位:面向大型企业级应用,强调高并发、高可用性和复杂事务处理能力。授权模式:闭源商业软件,需购买许可证,成本较高。架构:多进程架构(每个用户连接对应独立进程),支持分布式集群(如RAC)。MySQL:定位:轻量级开源数据库,适合中小型应用及Web开发。授
现代前端开发框架对比:React、Vue 和 Svelte 的选择指南
zhyoobo
vue.js react.js 前端
引言在当今快速发展的Web开发领域,前端框架的选择往往直接影响项目的开发效率、维护成本和用户体验。React、Vue和Svelte作为当前最受关注的三大框架,各自拥有独特的设计哲学与技术实现。本文将通过5000字的深度解析,从架构设计、开发体验、性能特征到生态系统四个维度进行全方位对比,并针对不同场景提供选型决策框架。无论您是初创团队的技术负责人,还是正在构建企业级应用的架构师,都能在此找到面向2
JavaScript基础-事件基础
難釋懷
javascript 开发语言
在现代Web开发中,交互性是网站用户体验的重要组成部分。通过使用JavaScript,我们可以捕获用户的操作并作出响应,实现动态网页效果。这一切都离不开事件(Events)的概念。本文将介绍JavaScript中事件的基础知识,包括事件类型、如何绑定事件处理器以及一些常见的实践技巧。一、什么是事件?在浏览器环境中,事件是由浏览器生成的通知,表明某种情况已经发生。这些情况可能是用户交互(如点击按钮)
Hyperlane:Rust 生态中的轻量级高性能 HTTP 服务器库,助力现代 Web 开发
LTPP
rust http 服务器 开发语言 后端 前端 面试
Hyperlane:Rust生态中的轻量级高性能HTTP服务器库,助力现代Web开发在Rust生态系统中,Hyperlane是一个备受关注的HTTP服务器库,以其轻量级、高性能和易用性脱颖而出。无论你是想快速构建一个高效的Web服务,还是需要支持实时通信的现代应用,Hyperlane都能成为你的理想选择。它不仅简化了网络服务的开发,还提供了强大的功能支持,如HTTP请求解析、响应构建、TCP通信,
TypeScript语言的网络编程
俞嫦曦
包罗万象 golang 开发语言 后端
TypeScript语言的网络编程引言随着现代网络应用程序的不断发展,对编程语言的需求也在不断提高。JavaScript作为前端开发的主要语言,凭借其动态特性和广泛的应用,成为了Web开发的中坚力量。而TypeScript作为JavaScript的超集,逐渐在开发社区中获得了越来越多的关注。其静态类型的特性使得开发者在编写大型应用程序时能够更加得心应手。尤其是在网络编程方面,TypeScript展
JavaScript 性能优化实战【详细指南】
AI筑梦师
JavaScript javascript 性能优化 开发语言
#JavaScript性能优化实战#JavaScript性能优化实战JavaScript作为现代Web开发的核心技术,其性能优化涉及多个层面,包括计算效率、DOM操作、异步处理、内存管理、网络请求优化等。随着Web发展,越来越多的新技术(如WebAssembly、OffscreenCanvas、StreamsAPI、V8TurboFan优化等)正在提升JavaScript的性能。本指南涵盖从基础优
Hyperlane:轻量、高效、安全的 Rust Web 框架新选择
LTPP
安全 rust 前端 github ssl 开发语言 后端
Hyperlane:轻量、高效、安全的RustWeb框架新选择在Web开发的世界中,框架的选择往往决定了项目的效率与未来。Hyperlane,一款基于Rust语言打造的轻量级Web框架,正以其卓越的性能、简洁的设计和可靠的安全性,迅速成为开发者的新宠。无论你是追求极致性能的资深程序员,还是希望快速上手的初学者,Hyperlane都能为你带来惊喜。让我们一起走进Hyperlane的世界,探索它的魅力
Hyperlane:Rust 语言打造的 Web 后端框架新标杆
LTPP
rust 前端 github ssl 网络协议 网络 开发语言
Hyperlane:Rust语言打造的Web后端框架新标杆在当今快节奏的数字化时代,Web应用程序的性能和开发效率成为了开发者们关注的焦点。Rust语言凭借其出色的性能、内存安全性和并发性,在Web开发领域逐渐崭露头角。而Hyperlane,作为一款专为Rust语言打造的轻量级、高性能HTTP服务器库,正以其独特的优势吸引着越来越多开发者的目光。一、性能卓越,数据说话Hyperlane在性能方面的
Django CSRF验证失败请求为什么会中断?
字节王德发
python django csrf python
在使用Django框架进行Web开发时,CSRF(跨站请求伪造)是一个需要特别注意的安全问题。CSRF保护是Django中内置的一项关键特性,它的目的是为了防止恶意网站通过用户的浏览器向你的应用程序发送不法请求。当用户在你的站点上进行敏感操作时,CSRF保护会验证请求的合法性,以阻止未授权的访问。不过,有时候开发者可能会遇到CSRF验证失败导致请求中断的情况。今天咱们就来深入聊聊这个问题,看看发生
前后端的身份认证
咖啡の猫
node.js 后端 express
在现代Web开发中,确保用户数据的安全性和隐私保护至关重要。身份认证是其中的核心环节之一,它用于验证用户的身份,并控制对资源的访问权限。本文将介绍几种常见的身份认证方法,并详细讲解如何在Node.js项目中实现这些方法。一、什么是身份认证?身份认证(Authentication)是确认用户身份的过程,通常通过用户名和密码组合或其他凭证来完成。一旦用户被认证,系统就可以基于其身份授予相应的访问权限(
JavaScript基础-获取元素
難釋懷
javascript 开发语言
在Web开发中,使用JavaScript动态地访问和操作网页上的元素是一项基本技能。通过获取页面上的特定元素,我们可以对其进行各种操作,比如修改内容、样式或属性等。本文将详细介绍几种获取DOM元素的方法,并探讨它们的特点及适用场景。一、为什么需要获取元素?在现代Web应用中,交互性是关键。无论是响应用户的输入、更新页面内容还是实现动画效果,首先都需要定位到相关的HTML元素。掌握不同的获取元素的方
聊聊Python都能做些什么
·零落·
Python入门到掌握 python 开发语言
文章目录一、Python简介二、Python都能做些什么1.Web开发2.数据分析和人工智能3.自动化运维和测试4.网络爬虫5.金融科技三、Python开源库都有哪些1.Web开发2.数据分析和科学计算3.机器学习和深度学习4.网络爬虫5.自动化和测试6.其他常用库四、相关链接一、Python简介Python是一种解释型、面向对象、动态数据类型的高级程序设计语言。它最初由GuidovanRossu
JavaScript基础-DOM 简介
難釋懷
javascript 开发语言
在现代Web开发中,JavaScript与HTML和CSS一起构成了网页的核心技术。而在这三者之中,DOM(DocumentObjectModel,文档对象模型)作为浏览器处理网页内容的一种接口,扮演着至关重要的角色。通过DOM,JavaScript能够动态地访问和操作网页的内容、结构以及样式。本文将介绍DOM的基本概念、核心组成部分以及如何使用JavaScript来操作DOM。一、什么是DOM?
HTML基础语法:写好网页的第一步
程序员
HTML基础语法:写好网页的第一步在Web开发的世界里,HTML是构建网页的基石。今天,让我们一起来了解HTML的基础语法,掌握编写规范网页的要点。一、HTML的基本构成1.HTML元素的解析HTML元素通常由三部分组成:开始标签(如)内容(实际的文本内容)结束标签(如)例如:这是一个段落2.元素的嵌套HTML元素可以相互嵌套,但必须注意正确的嵌套顺序:我的猫咪非常可爱二、元素的类型1.块级元素在
python后端常见架构_常见的后端框架
weixin_39622178
python后端常见架构
后端vs前端如果您是Web开发世界的新手,后端和前端开发之间的区别可能不那么明显,但是,了解两者之间的区别很重要。以下是前端开发人员与后端开发人员的一些区别。前端开发:前端开发人员在很大程度上负责用户所看到的内容(即网站页面),前端开发人员主要使用HTML,CSS和JavaScript。他们的主要关注点是创建出色的用户体验,并确保网站设计和布局或Web应用程序始终具有凝聚力。后端开发:另一方面,后
python的后端开发框架django,flask,flaskapi
myjzwsz
python django flask
Django、Flask和Flask-API是Python中流行的后端开发框架,它们在功能、应用场景以及架构上有不同的特点和使用场景。下面我给你详细介绍每个框架的应用示例、区别和应用场景:1.DjangoDjango是一个功能全面的Web开发框架,强调“快速开发”和“无需重新发明轮子”。它自带了很多功能,如认证、ORM(数据库映射)、表单处理、管理后台等。应用示例:社交媒体平台:像Instagra
springboot一课一得
POlse
springboot
SpringBoot学习之路:从基础到进阶SpringBoot是基于Spring框架的一个开源项目,它通过简化配置、自动化功能以及集成多种开箱即用的技术,使开发者能够更快地开发、测试和部署Java应用程序。它不仅减少了开发者的配置工作量,还为开发者提供了很多与生产环境相关的功能,使得SpringBoot成为现代Web开发、微服务架构和企业级应用开发的首选框架。本文将基于“SpringBoot一课一
探索 Rust 高效 Web 开发:Hyperlane 框架深度解析
LTPP
开发语言 rust 后端 面试 算法
探索Rust高效Web开发:Hyperlane框架深度解析在当今的Web开发领域,追求高性能、轻量级的框架一直是开发者们的不懈追求。对于Rust语言开发者而言,Hyperlane框架正以其独特的魅力崭露头角,为构建现代Web服务提供了一种卓越的解决方案。今天,让我们一同深入探索这个令人瞩目的框架。轻量与高效的完美融合Hyperlane是一款轻量级且高性能的RustHTTP服务器库,它的诞生旨在极大
基于.NET MVC实现H5页面调用手机摄像头扫描二维码完整方案
Bart_Lu
.net mvc
一、前言在移动端Web开发中,二维码扫描功能已成为常见需求。本文将介绍如何在ASP.NETMVC框架下,通过HTML5技术调用手机摄像头实现二维码扫描功能,并提供完整的代码实现方案。二、技术选型前端库:使用ZXing-js(支持浏览器二维码解析)后端框架:ASP.NETMVC5浏览器API:MediaDevicesAPI三、实现步骤1.准备工作在MVC项目中引入所需库:html运行HTML2.创建
Java Web开发核心内容全解析(上)
风铃儿~
java servlet mybatis
一、JavaWeb概述JavaWeb是指使用Java技术来解决相关web互联网领域的技术总和。在当今数字化时代,JavaWeb在构建企业级应用、电子商务平台、社交网络等方面发挥着至关重要的作用。(一)JavaWeb的体系结构JavaWeb应用的体系结构主要分为客户端层、表示层、业务逻辑层和数据访问层。1.客户端层-这是用户与Web应用交互的最前端。主要包括用户浏览器,它可以接收并显示从服务器端发送
轻量级模块化前端框架:快速构建强大的Web界面
小杰~
前端框架 前端
轻量级模块化前端框架:快速构建强大的Web界面在当今快节奏的Web开发环境中,选择一个高效且灵活的前端框架至关重要。UIkit是一个轻量级的模块化前端框架,旨在帮助开发者快速构建功能强大且响应迅速的Web界面。UIkit提供了丰富的组件和工具,使开发者能够轻松实现现代化的设计效果。无论是构建复杂的用户界面还是简单的网页布局,UIkit都能提供出色的支持。其模块化设计使得开发者可以根据项目需求灵活选
Tomcat 新手入门指南:从零开始掌握安装与配置
超级小狗
tomcat java
Tomcat新手入门指南:从零开始掌握安装与配置一、Tomcat是什么?ApacheTomcat是一个开源的轻量级Web应用服务器,专为运行JavaServlet和JSP设计。它是初学JavaWeb开发的必备工具,也是企业级应用的常见选择。核心功能:处理HTTP请求、管理Servlet生命周期、支持动态网页渲染。适用场景:开发测试环境、中小型Web应用部署、微服务架构中的容器化组件。二、快速安装T
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性能优化权威指南》