文章目录本专栏将从基础开始,循序渐进,由浅入深讲解Java的基本使用,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:26天高效学习Java编程
相关软件地址:软件地址
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
- 项目结构及结果展示
- 代码展示
- MainFrame模块
- RegisterUI模块
- RegisterUI模块
- JDBC模块
项目结构及结果展示大家好,今天用Java的awt组件、swing组件以及数据库JDBC写了一个仿QQ登录的界面,具体演示如下图所示,包括三个页面,分别是登录窗口(MainFrame)、注册窗口(RegisterUI)和忘记密码窗口(ForgetUI)。本文主要应用的技术有:JAVA-GUI、JAVA的awt组件、swing组件、事件处理、JDBC等,是初学者学习和练手的好项目。准备好了吗,let’s get it!
该项目的结构如下图所示:
主要有三个类:
- MainFrame是登录窗口的GUI类,效果图如下:
- RegisterUI是注册窗口的GUI类,效果图如下:
- ForgetUI是忘记密码窗口的GUI类,效果图如下:
在进行代码展示前,先对Swing组件常见的控件类进行介绍,Swing组件常见的控件类有以下几种:
MainFrame模块JLabel 标签主要用于展示 文本 或 图片,也可以 同时显示文本和图片
JButton 点击事件
JTextArea 编辑单行的文本框
JPasswordArea 一个只能输入数字的密码框 把输入的内容用其他字符回显
JTabledPlan 选项卡面板。它允许用户通过点击给定标题或图标的选项卡,在一组组件之间进行切换显示
JCheckBox 复选框,是否被选中
JPanel相当于将整个窗体划分成几个面板,然后在面板中使用布局管理器(管理按钮的布局)一个窗口只能有一个JFrame,能有多个JPlanel
Imagin.SCALE_DEFAULT 自适应JLabel的大小
getScaledInstance 创建此图像的缩放版本。返回一个新的 image 对象,默认情况下,该对象按指定的 width 和 height 呈现图像。即使已经完全加载了初始源图像,新的 image 对象也可以被异步加载
SetIcon图标将会被自动地放到按钮的上面,缺省时居中放置
setborderpainted 如果进度条应该绘制边框,则为 true;否则为 false
MainFrame的布局如下图所示:
MainFrame的代码如下:
package Frame;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class MainFrame extends JFrame implements ActionListener, FocusListener {
private static final long serialVersionUID = 1L;
private static final String _txt_account = "QQ密码/手机/邮箱";
private static final String _txt_pwd = "密码";
private static final String _txt_title = "QQ登录";
private static final String _txt_registe = "注册";
private static final String _txt_forget = "忘记密码";
private static final String _txt_blank = "";
private JTextField account;
private JPasswordField pwd;
private JLabel upper_frame;
private JPanel lower_frame, center_frame;
private JButton login, register, forget;
MainFrame() {
//控件的初始化
init();
add(upper_frame, BorderLayout.NORTH);
add(center_frame, BorderLayout.CENTER);
add(lower_frame, BorderLayout.SOUTH);
ImageIcon logo = new ImageIcon("D:/image/logo.jpg"); //左上方小图标
setIconImage(logo.getImage());
setBounds(500, 230, 430, 360); //设定大小及位置
setResizable(false); //登录框大小固定,不允许通过拖、拉改变大小
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); //设置窗口右上角的叉号,点击叉号窗口关闭 注意不能EXIT_ON_CLOSE做参数的,用它时候使用的是System.exit方法退出应用程序。故会关闭所有窗口。
setTitle(_txt_title);
setVisible(true); //说明数据模型已经构造好了,允许JVM可以根据数据模型执行paint方法开始画图并显示到屏幕上,一般放在最后一句
}
public void init() {
//账号输入块
account = new JTextField(_txt_account);
account.setName("account");
account.setForeground(Color.gray);
account.addFocusListener(this); //产生事件响应用户行为
//密码输入块
pwd = new JPasswordField(_txt_pwd);
pwd.setName("pwd");
pwd.setForeground(Color.gray);
pwd.setEchoChar(')';//启动后密码框内一定为 “密码” .
pwdaddFocusListener(this);//注册模块
=
register new JButton ()_txt_registe;.
registersetBorderPainted(false);.
registersetBorder(BorderFactory.createRaisedBevelBorder());//斜面边框(凸) .
registersetCursor(Cursor.getPredefinedCursor(Cursor.)HAND_CURSOR);.
registeraddActionListener(this);//忘记密码模块
=
forget new JButton ()_txt_forget;.
forgetsetBorderPainted(false);.
forgetsetBorder(BorderFactory.createRaisedBevelBorder());.
forgetsetCursor(Cursor.getPredefinedCursor(Cursor.)HAND_CURSOR);.
forgetaddActionListener(this);//login按钮模块
=
login new JButton ();ImageIcon
= login_image new ImageIcon ("D:/image/login_image.png");.
login_imagesetImage(.login_imagegetImage().getScaledInstance(430,35 ,Image .)SCALE_DEFAULT);.
loginsetIcon()login_image;.
loginsetBackground(Color.)white;.
loginsetBorderPainted(false);//如果进度条应该绘制边框,则为 true;否则为 false .
loginsetBorder(null);//设置此组件的边框 无 .
loginsetCursor(Cursor.getPredefinedCursor(Cursor.)HAND_CURSOR);//将光标设为 “小手”形状 .
loginaddActionListener(this);//qq登录框架上半部分(无按钮之类的内容,只有一张图片)
ImageIcon
= upper_image new ImageIcon ("D:/image/upper_image.png");.
upper_imagesetImage(.upper_imagegetImage().getScaledInstance(430,160 ,Image .)SCALE_DEFAULT);=
upper_frame new JLabel ()upper_image;//qq登录中间部分 (账号、密码、 注册、forget)
=
center_frame new JPanel ();.
center_framesetName("center_frame");.
center_framesetLayout(null);.
center_framesetLayout(newGridLayout (3,3 ,3 ,15 ));//这里用到3行3列的空间, 用空格填充 .
center_frameadd(newJLabel (,_txt_blankJLabel .)CENTER);.
center_frameadd()account;.
center_frameadd(newJLabel (,_txt_blankJLabel .)CENTER);.
center_frameadd(newJLabel (,_txt_blankJLabel .)CENTER);.
center_frameadd()pwd;.
center_frameadd(newJLabel (,_txt_blankJLabel .)CENTER);.
center_frameadd()register;.
center_frameadd(newJLabel (,_txt_blankJLabel .)CENTER);.
center_frameadd()forget;.
center_framesetBackground(Color.)white;//qq登录框架的下半部分login
=
lower_frame new JPanel ();.
lower_framesetName("lower_frame");.
lower_framesetLayout(null);//lower_frame.setLayout(new GridLayout(1, 3, 3, 15));
.
lower_framesetLayout(newGridLayout (0,1 ));.
lower_frameadd()login;}
//按钮的点击事件用actionPerformed
@Override
public
void actionPerformed (ActionEvent) e/*
* 1:如果点击了登录按钮 首先判断帐号或者密码是否为空
* 2:如果点击了注册账号就d出注册页面
* 3:如果点击了忘记密码d出找回密码页面
*/{
//处理登录(login)页面
if
(.egetSource()== ) loginString{
= user_name . accountgetText().trim();String
= user_pwd new String (.pwdgetPassword()).trim();if
("".equals()user_name)JOptionPane {
.showMessageDialog(null,"请输入帐号!!" );return
;}
if
("".equals()user_pwd)JOptionPane {
.showMessageDialog(null,"请输入密码!!" );return
;}
}
//处理注册(register)页面
if
(.egetSource()== ) registerRegisterUI{
= registerUI new RegisterUI (this);}
//处理找回密码(forget)页面
if
(.egetSource()== ) forgetForgetUI{
= forgetUI new ForgetUI (this);}
}
//鼠标的点击或移动之类的用focuslistener
@Override
public
void focusGained (FocusEvent) e//处理账号输入框 {
if
(.egetSource()== ) accountif{
(._txt_accountequals(.accountgetText())).{
accountsetText("");.
accountsetForeground(Color.)BLACK;}
}
//处理密码输入框
if
(.egetSource()== ) pwdif{
(._txt_pwdequals(.pwdgetText())).{
pwdsetText("");.
pwdsetEchoChar('*');.
pwdsetForeground(Color.)BLACK;}
}
}
@Override
public
void focusLost (FocusEvent) e//处理账号输入框 {
if
(.egetSource()== ) accountif{
("".equals(.accountgetText())).{
accountsetForeground(Color.)gray;.
accountsetText()_txt_account;}
}
//处理密码输入框
if
(.egetSource()== ) pwdif{
("".equals(.pwdgetText())).{
pwdsetForeground(Color.)gray;.
pwdsetText()_txt_pwd;.
pwdsetEchoChar(')';}}
}
public
static
void main ( String[])MainFrame args= {
new mainframe MainFrame ( );}}
package
Frame
RegisterUI模块
RegisterUI的布局和MainFrame的类似,如下图所示:
RegisterUI的代码如下:
; import.
. javaBorderLayoutawt;import.
. javaColorawt;import.
. javaCursorawt;import.
. javaGridLayoutawt;import.
. javaImageawt;import.
. java.awtActionEventevent;import.
. java.awtActionListenerevent;import.
. java.awtFocusEventevent;import.
. java.awtFocusListenerevent;import.
. javaxImageIconswing;import.
. javaxJButtonswing;import.
. javaxJFrameswing;import.
. javaxJLabelswing;import.
. javaxJOptionPaneswing;import.
. javaxJPanelswing;import.
. javaxJTextFieldswing;publicclass
RegisterUI extends JFrame implements ActionListener , FocusListenerprivate static {
final long = 1L serialVersionUID ; privateJLabel
, , upper_N, user_name_txt, user_pwd_txt; user_ques_txt//显示文字用 user_ans_txtprivate JButton
; private register_button_SJTextField
, , user_name, user_pwd; user_ques//在这里面获取用户输入 user_ansprivate JPanel
, ; tmp_Southprivate center_CenterMainFrame
; //用于关闭登录页面 如果注册成功则将刚开始的注册页面关闭 mainFramepublic RegisterUI
( MainFrame)this mainFrame. {
=;mainFrame //初始化界面 mainFrameinit
(
);//合成整体add
(
,BorderLayoutcenter_Center. );CENTERadd(
,BorderLayoutupper_N. );NORTHadd(
,BorderLayouttmp_South. );SOUTH//位置、页面大小设置setSize
(
250,400) ;setLocation(
550,300) ;ImageIcon=
new logo ImageIcon ( "D:/image/register_image.png");//左上方小图标setIconImage (
.getImagelogo());setDefaultCloseOperation(
JFrame.);HIDE_ON_CLOSEsetResizable(
false);setVisible(
true);}public
void
init ( )//上方图片部分构造 上 即为 北ImageIcon {
=
new upper_image ImageIcon ( "D:/image/register_background_image.jpg");.setImage
upper_image(.getImageupper_image().getScaledInstance(250,139, Image.
))SCALE_DEFAULT;=new
upper_N JLabel ( );upper_image//下方注册图片构造 下 即为 南=
new
tmp_South JPanel ( );//作为一个容器来放确认注册按钮= new
register_button_S JButton ( );ImageIcon=
new conform_register_image ImageIcon ( "D:/image/conform_register_image.png");.setImage
conform_register_image(.getImageconform_register_image().getScaledInstance(220,40, Image. ))SCALE_DEFAULT;.setIcon
register_button_S();conform_register_image// 不绘制边框.
setBorderPainted
register_button_S(false);// 设置边框为空.
setBorder
register_button_S(null);.setCursor
register_button_S(Cursor.getPredefinedCursor(Cursor.))HAND_CURSOR;.addActionListener
register_button_S(this);//产生事件响应用户行为. add
tmp_South();register_button_S//中间部分内容=
new
center_Center JPanel ( );=new
user_name_txt JLabel ( "用户账号",JLabel. );CENTER=new
user_pwd_txt JLabel ( "用户密码",JLabel. );CENTER=new
user_ques_txt JLabel ( "提示问题",JLabel. );CENTER=new
user_ans_txt JLabel ( "问题答案",JLabel. );CENTER=new
user_name JTextField ( );=new
user_pwd JTextField ( );=new
user_ques JTextField ( );=new
user_ans JTextField ( );.addFocusListener
user_name(this);.addFocusListener
user_pwd(this);.addFocusListener
user_ans(this);.addFocusListener
user_ques(this);.setLayout
center_Center(newGridLayout( 4,2) );.add
center_Center();user_name_txt.add
center_Center();user_name.add
center_Center();user_pwd_txt.add
center_Center();user_pwd.add
center_Center();user_ques_txt.add
center_Center();user_ques.add
center_Center();user_ans_txt.add
center_Center();user_ans}public
void
actionPerformed ( ActionEvent)/*
* 如果点击了登录按钮 首先判断帐号或者密码是否为空
*/ eif {
(
. getSourcee()==) String register_button_S= {
. username getText user_name().trim();String=
. password getText user_pwd().trim();String=
. userques getText user_ques().trim();String=
. userans getText user_ans().trim();if(
"" .equals()||username== null username ) JOptionPane. {
showMessageDialog(null,"请输入帐号!!") ;return;
}if
(
"" .equals()||password== null password ) JOptionPane. {
showMessageDialog(null,"请输入密码!!") ;return;
}if
(
"" .equals()||userques== null userques ) JOptionPane. {
showMessageDialog(null,"请输入问题!!") ;return;
}if
(
"" .equals()||userans== null userans ) JOptionPane. {
showMessageDialog(null,"请输入答案!!") ;return;
}}
}
//鼠标的点击或移动之类的用focuslistener
@Override
public
void
focusGained ( FocusEvent)//处理账号输入框 eif {
(
.getSourcee()==) . user_namesetForeground{
user_name(Color.);BLACK}//处理密码输入框
if
(
.getSourcee()==) . user_pwdsetForeground{
user_pwd(Color.);BLACK}//处理问题输入框
if
(
.getSourcee()==) . user_quessetForeground{
user_ques(Color.);BLACK}//处理答案输入框
if
(
.getSourcee()==) . user_anssetForeground{
user_ans(Color.);BLACK}}
@Override
public
void
focusLost ( FocusEvent)//处理账号输入框 eif {
(
.getSourcee()==) . user_namesetForeground{
user_name(Color.);gray}//处理密码输入框
if
(
.getSourcee()==) . user_pwdsetForeground{
user_pwd(Color.);gray}//处理问题输入框
if
(
.getSourcee()==) . user_quessetForeground{
user_ques(Color.);gray}//处理答案输入框
if
(
.getSourcee()==) . user_anssetForeground{
user_ans(Color.);gray}}
}
package
Frame
RegisterUI模块
为了掌握多种布局方式,这里RegisterUI采用的是绝对布局,相关代码如下:
; import.
. javaColorawt;import.
. javaCursorawt;import.
. javaImageawt;import.
. java.awtActionEventevent;import.
. java.awtActionListenerevent;import.
. java.awtFocusEventevent;import.
. java.awtFocusListenerevent;import.
. javaxImageIconswing;import.
. javaxJButtonswing;import.
. javaxJFrameswing;import.
. javaxJLabelswing;import.
. javaxJOptionPaneswing;import.
. javaxJTextFieldswing;publicclass
ForgetUI extends JFrame implements ActionListener , FocusListenerprivate static{
final long = 1L serialVersionUID ; privateJLabel
, , upper_N, user_name_txt, user_pwd_txt, user_ques_txt; user_ans_txt//显示文字用 user_quesprivate JButton
, ; forget_button_Sprivate submit_buttonJTextField
, , user_name; user_pwd//在这里面获取用户输入 user_ansprivate MainFrame
; //用于关闭登录页面 如果修改密码成功则将刚开始的注册页面关闭 mainFramepublic ForgetUI
( MainFrame)this mainFrame. {
=;mainFrame //页面构造 mainFrameinit
(
);//合成整体add
(
);upper_Nadd(
);user_name_txtadd(
);user_nameadd(
);submit_buttonadd(
);user_ques_txtadd(
);user_quesadd(
);user_ans_txtadd(
);user_ansadd(
);user_pwd_txtadd(
);user_pwdadd(
);forget_button_S//位置、页面大小设置setSize
(
270,430) ;setLocation(
550,300) ;setLayout(
null);//手工布局 与其他页面不同 ImageIcon =
new logo ImageIcon ( "D:/image/register_image.jpg");//左上方小图标setIconImage (
.getImagelogo());setDefaultCloseOperation(
JFrame.);HIDE_ON_CLOSEsetResizable(
false);setVisible(
true);}public
void
init ( )//上方图片部分构造 上 即为 北ImageIcon {
=
new upper_image ImageIcon ( "D:/image/forget_background_image.png");.setImage
upper_image(.getImageupper_image().getScaledInstance(270,170, Image.
))SCALE_DEFAULT;=new
upper_N JLabel ( );upper_image.setLocation
upper_N(0,0);//确定位置. setSize
upper_N(270,170) ;//设置大小//中间部分内容 绝对位置 =
new
user_name_txt JLabel ( "用户账号",JLabel. );CENTER.setSize
user_name_txt(60,20) ;.setLocation
user_name_txt(10,185) ;=new
submit_button JButton ( );.setText
submit_button("查询");.setCursor
submit_button(Cursor.getPredefinedCursor(Cursor.))HAND_CURSOR;.setSize
submit_button(60,20) ;.setLocation
submit_button(190,185) ;.addActionListener
submit_button(this);//产生事件响应用户行为= new
user_ques_txt JLabel ( "提示问题",JLabel. );CENTER.setSize
user_ques_txt(60,20) ;.setLocation
user_ques_txt(10,220) ;=new
user_ans_txt JLabel ( "问题答案",JLabel. );CENTER.setSize
user_ans_txt(60,20) ;.setLocation
user_ans_txt(10,255) ;=new
user_pwd_txt JLabel ( "重置密码",JLabel. );CENTER.setSize
user_pwd_txt(60,20) ;.setLocation
user_pwd_txt(10,290) ;=new
user_name JTextField ( );.setSize
user_name(100,30) ;.setLocation
user_name(80,185) ;=new
user_ques JLabel ( "点击查询后显示",JLabel. );CENTER.setSize
user_ques(100,30) ;.setLocation
user_ques(80,220) ;=new
user_ans JTextField ( );.setSize
user_ans(100,30) ;.setLocation
user_ans(80,255) ;=new
user_pwd JTextField ( );.setSize
user_pwd(100,30) ;.setLocation
user_pwd(80,290) ;.addFocusListener
user_name(this);.addFocusListener
user_pwd(this);.addFocusListener
user_ans(this);//下方注册图片构造 下 即为 南=
new
forget_button_S JButton ( );ImageIcon=
new conform_register_image ImageIcon ( "D:/image/conform_forget_image.png");.setImage
conform_register_image(.getImageconform_register_image().getScaledInstance(220,32, Image. ))SCALE_DEFAULT;.setIcon
forget_button_S();conform_register_image.setBorderPainted
forget_button_S(false);.setBorder
forget_button_S(null);.setCursor
forget_button_S(Cursor.getPredefinedCursor(Cursor.))HAND_CURSOR;.setSize
forget_button_S(220,32) ;.setLocation
forget_button_S(15,330) ;.addActionListener
forget_button_S(this);//产生事件响应用户行为} public
void
actionPerformed ( ActionEvent)if e( {
.getSourcee()==) String submit_button= {
. username getText user_name().trim();if(
"".equals()||username== null username ) JOptionPane. {
showMessageDialog(null,"请输入帐号!!") ;return;
}else
} } {
if
(
. getSourcee()==) if forget_button_S( {
==nulluser_name ) JOptionPane . {
showMessageDialog(null,"请输入正确账号并点击查询") ;return;
}String
=
. newpwd getText user_pwd();if(
==nullnewpwd || "" . equals())newpwdJOptionPane. {
showMessageDialog(null,"请输入新密码") ;return;
}String
=
. userans getText user_ans();if(
==nulluserans || "" . equals())useransJOptionPane. {
showMessageDialog(null,"请输入答案") ;return;
}}
}
//鼠标的点击或移动之类的用focuslistener 这里不知道为啥没变色 (哭
@Override
public
void
focusGained ( FocusEvent)//处理账号输入框 eif {
(
.getSourcee()==) . user_namesetForeground{
user_name(Color.);BLACK}//处理密码输入框
if
(
.getSourcee()==) . user_pwdsetForeground{
user_pwd(Color.);BLACK}//处理问题输入框
if
(
.getSourcee()==) //user_ques.setForeground(Color.BLACK); user_ques}{
//处理答案输入框
if
(
.getSourcee()==) . user_anssetForeground{
user_ans(Color.);BLACK}}
@Override
public
void
focusLost ( FocusEvent)//处理账号输入框 eif {
(
.getSourcee()==) . user_namesetForeground{
user_name(Color.);gray}//处理密码输入框
if
(
.getSourcee()==) . user_pwdsetForeground{
user_pwd(Color.);gray}//处理问题输入框
if
(
.getSourcee()==) //user_ques.setForeground(Color.gray); user_ques}{
//处理答案输入框
if
(
.getSourcee()==) . user_anssetForeground{
user_ans(Color.);gray}}
}
create database MyQQ;
use MyQQ;
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(20),
question varchar(100),
answer varchar(100)
);
INSERT INTO `USER` VALUES(null,'10001','123456','csdnJava哪家强','每天都要努力的小颓废');
import
JDBC模块
以上仿QQ实现了QQ的登录功能,但是对于登录只做了简单的是否为空的校验,并没有使用数据库进行查询,可以通过以下方式创建并使用数据库进行增删查改:
创建数据库,并创建User表
.
将驱动jar包导入项目(jar包地址在软件地址 的mysql目录):
JDBC *** 作代码如下:
. com.mysqlDriverjdbc;import.
. javaConnectionsql;import.
. javaDriverManagersql;import.
. javaResultSetsql;import.
. javaStatementsql;publicclass
Test public static {
void main ( String[])throws argsException // 需求:查询所有的用户, 输出到控制台 // 分析:{
// 1.创建项目,拷贝驱动jar包到模块下,并添加到classpath路径中
// 2.注册驱动
DriverManager
.
registerDriver(newDriver( ));// 3.获得连接String
=
"jdbc:mysql://localhost:3306/db_mybatis" url ; String=
"root" username ; String=
"root" password ; Connection=
DriverManager connection . getConnection(,,url)username;password// 4.创建执行sql的对象Statement
=
. statement createStatement connection();// 5.执行sql语句,处理结果String
=
"select * from user" sql ; ResultSet=
. resultSet executeQuery statement();sqlwhile(
. nextresultSet())// 取出来//System.out.print(resultSet.getObject("id")+" "); {
//System.out.print(resultSet.getObject("username")+" ");
//System.out.print(resultSet.getObject("password")+" ");
//System.out.println(resultSet.getObject("question")+" ");
//System.out.println(resultSet.getObject("answer"));
System
.
.printout(.getObjectresultSet(1)+" ");System.
.printout(.getObjectresultSet(2)+" ");System.
.printout(.getObjectresultSet(3)+" ");System.
.printlnout(.getObjectresultSet(4)+" ");System.
.printlnout(.getObjectresultSet(5));System.
.printlnout("------------------------------------------------");}=
"10001"
username ; ="1234567"
password ; // 5.2 判断用户名密码是否正确=
"select * from user where username = "
sql + + " and password =" username + ; = password.
resultSet executeQuery statement();sql//查询到了说明不为空,此时登录成功if
(
.nextresultSet())System.{
.printlnout("登录成功");}else
System
.{
.printlnout("登录失败");}// 6.释放资源
if
(
!= nullresultSet ) .close{
resultSet();}if
(
!= nullstatement ) .close{
statement();}if
(
!= nullconnection ) .close{
connection();}}
}
需要注意以上代码中的图片路径使用的是绝对路径,大家可以根据自己需要进行替换,代码已上传至Gitee,如果文章知识点有错误的地方,请指正!大家一起学习,一起进步,谢谢!
以上仅演示了简单的JDBC *** 作,由于篇幅有限,这里暂不介绍如何防登录注入、JDBC工具类的提取以及数据库连接池,后续再进行介绍。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)