单例设计模式
MVC
事务
Web Servlet
单例设计模式的应用
1.单例设计模式主要是为了在同一个包中调用的对象都是同一个对象,即只有一个实例
2.利用java中的WindowsBuilder创建的工程JFrame工程来结合数据库,实现用户的登录,注册,注销,改密操作,下面是例子
package com.baidu.sqlfinal;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import com.baidu.sql.SQLOperate;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JPasswordField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Color;
public class SQLFinal extends JFrame {
private JPanel contentPane;
private JTextField textFieldUserName;
private JPasswordField passwordFieldPass;
private JPasswordField passwordFieldPassAgain;
private JPasswordField passwordFieldChange;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SQLFinal frame = new SQLFinal();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public SQLFinal() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 308, 384);
contentPane = new JPanel();
contentPane.setBackground(Color.WHITE);
contentPane.setForeground(Color.BLACK);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
textFieldUserName = new JTextField();
textFieldUserName.setBounds(99, 10, 138, 27);
contentPane.add(textFieldUserName);
textFieldUserName.setColumns(10);
JLabel label = new JLabel("用户名");
label.setBounds(25, 16, 54, 15);
contentPane.add(label);
JLabel label_1 = new JLabel("密码");
label_1.setBounds(25, 71, 54, 15);
contentPane.add(label_1);
/***
* 点击事件,用来判断数据库中有没有用户名和密码对,如果有则登录成功
*/
JButton button = new JButton("登录");
button.setBounds(167, 220, 93, 23);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String userName=textFieldUserName.getText();
char[] a=passwordFieldPass.getPassword();
String passWord=new String(a);
Judge is=new Judge();
boolean isRight=is.judge(userName, passWord);
if (isRight) {
boolean isSingIn=SQLOperate.newInstance().signIn(userName, passWord);
if (isSingIn) {
System.out.println("成功登录");
}else{
System.out.println("登录失败用户名或密码错误");
}
}else{
System.out.println("用户名或密码格式错误");
}
passWord=null;
userName=null;
}
});
contentPane.add(button);
/***
* 点击事件,用来向数据库中写入新的密码和用户名对,
*/
JButton button_1 = new JButton("注册");
button_1.setBounds(35, 220, 93, 23);
button_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String userName=textFieldUserName.getText();
char[] a=passwordFieldPass.getPassword();
char[] a1=passwordFieldPassAgain.getPassword();
String passWord=new String(a);
String passAgain=new String(a1);
if (passWord.equals(passAgain)) {
SQLRegistered.newInstance().registered(userName, passWord);
}else{
System.out.println("两次输入的密码不一致请重新输入");
}
passWord=null;
userName=null;
}
});
contentPane.add(button_1);
/***
* 点击事件,用来删除数据库中的一项数据
*/
JButton button_2 = new JButton("注销");
button_2.setBounds(35, 268, 93, 23);
button_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String userName=textFieldUserName.getText();
char[] a=passwordFieldPass.getPassword();
char[] a1=passwordFieldPassAgain.getPassword();
String passWord=new String(a);
String passAgain=new String(a1);
if (passWord.equals(passAgain)) {
SQLLogOut.newInstance().sqlLogOut(userName, passWord);
}else{
System.out.println("两次输入的密码不一致请重新输入");
}
passWord=null;
userName=null;
}
});
contentPane.add(button_2);
/***
* 点击事件,用来重新设置数据库中的对应用户名和密码的密码
*/
JButton button_3 = new JButton("改密");
button_3.setBounds(167, 268, 93, 23);
button_3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String userName=textFieldUserName.getText();
char[] a=passwordFieldPass.getPassword();
char[] a1=passwordFieldPassAgain.getPassword();
char[] a2=passwordFieldChange.getPassword();
String passWord=new String(a);
String passAgain=new String(a1);
String changePass=new String(a2);
if (passWord.equals(passAgain)) {
SQLChange.newInstance().changePassWord(userName, passWord,changePass);
}else{
System.out.println("两次输入的密码不一致请重新输入");
}
passWord=null;
userName=null;
}
});
contentPane.add(button_3);
passwordFieldPass = new JPasswordField();
passwordFieldPass.setBounds(99, 65, 138, 27);
contentPane.add(passwordFieldPass);
passwordFieldPassAgain = new JPasswordField();
passwordFieldPassAgain.setBounds(99, 116, 138, 27);
contentPane.add(passwordFieldPassAgain);
JLabel label_2 = new JLabel("确认密码");
label_2.setBounds(25, 122, 54, 15);
contentPane.add(label_2);
/***
* 点击事件,用来退出当前程序
*/
JButton button_4 = new JButton("退出");
button_4.setBounds(35, 313, 225, 23);
button_4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
contentPane.add(button_4);
passwordFieldChange = new JPasswordField();
passwordFieldChange.setBounds(99, 168, 138, 27);
contentPane.add(passwordFieldChange);
JLabel label_3 = new JLabel("修改密码");
label_3.setBounds(25, 174, 54, 15);
contentPane.add(label_3);
JLabel label_4 = new JLabel(" 登录只需要填写用户名和密码");
label_4.setBounds(74, 47, 186, 15);
label_4.setForeground(Color.RED);
label_4.setBackground(Color.RED);
contentPane.add(label_4);
JLabel label_5 = new JLabel(" 注册和注销需要填写确认密码");
label_5.setForeground(Color.RED);
label_5.setBounds(74, 96, 186, 15);
contentPane.add(label_5);
JLabel label_6 = new JLabel(" 改密需要填写修改密码");
label_6.setForeground(Color.RED);
label_6.setBounds(74, 147, 186, 15);
contentPane.add(label_6);
}
}
package com.baidu.sqlfinal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Judge {
/**
* 改方法用来判断输入的用户名和密码的格式是否正确
*
* @param userName
* 传入用户名
* @param passWord
* 传入密码
* @return 如果用户名和密码输入格式正确返回true 输入格式错误则返回false
*/
public boolean judge(String userName, String passWord) {
Pattern pUser = Pattern.compile("^\\w{2,16}");
Matcher mUser = pUser.matcher(userName);
boolean isUserName = mUser.matches();
System.out.println("账户格式正确与否:"+isUserName);
Pattern pPass = Pattern.compile("^\\w{2,16}");
Matcher mPass = pPass.matcher(userName);
boolean isPassWord = mPass.matches();
System.out.println("密码格式正确与否:"+isPassWord);
return isPassWord && isUserName;
}
}
package com.baidu.sqlfinal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SQLChange {
/***
* 单例设计模式
*/
private static SQLChange change;
private SQLChange() {
}
public static synchronized SQLChange newInstance() {
if (change == null) {
change = new SQLChange();
}
return change;
}
/***
* 连接数据库,首先判断是否存在用户名和密码对,如果存在则更改密码
* @param userName 传入用户名
* @param passWord 传入密码
* @param changePass 传入需要修改的密码
*/
public void changePassWord(String userName, String passWord,String changePass) {
Connection conn = SQLManger.newInstance().getConnection();
try {
if (!conn.isClosed()) {
PreparedStatement state = conn.prepareStatement("select * from user where user_name=? and password=?");
/** setString中的1表示state中的第一个问号,2表示state中的第二个问号 */
state.setString(1, userName);
state.setString(2, passWord);
ResultSet set = state.executeQuery();
set.last();
int num = set.getRow();
if (num == 1) {
String update = "update user set password='" + changePass + "' where user_name='" + userName + "'";
state.execute(update);
System.out.println("修改成功");
num = 0;
}
} else {
System.out.println("更改失败,用户名或密码输入错误");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package com.baidu.sqlfinal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SQLLogOut {
/**
* 单例设计模式
*/
private static SQLLogOut logOut;
private SQLLogOut() {
}
public static synchronized SQLLogOut newInstance() {
if (logOut == null) {
logOut = new SQLLogOut();
}
return logOut;
}
/***
* 该方法首先判断数据库中有没有该用户名和密码对,如果有则删除这条记录
* @param userName 传入用户名
* @param passWord 传入密码
*/
public void sqlLogOut(String userName, String passWord) {
Connection conn = SQLManger.newInstance().getConnection();
try {
if (!conn.isClosed()) {
PreparedStatement state = conn.prepareStatement("select * from user where user_name=? and password=?");
/** setString中的1表示state中的第一个问号,2表示state中的第二个问号 */
state.setString(1, userName);
state.setString(2, passWord);
ResultSet set = state.executeQuery();
set.last();
int num = set.getRow();
if (num==1){
String delete="delete from user where user_name='"+userName+"'";
state.execute(delete);
System.out.println("注销成功");
num=0;
}else{
System.out.println("注销失败,用户名或密码输入错误");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package com.baidu.sqlfinal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQLManger {
/***
* 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例,即无论多个线程还是多个新建的对象,都只有同一个对象
*
*/
private Statement statement;
private Connection connection;
public Connection getConnection() {
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public Statement getStatement() {
return statement;
}
public void setStatement(Statement statement) {
this.statement = statement;
}
private static SQLManger manger; //创建一个私有的属性
public static synchronized SQLManger newInstance(){ //创建一个私有的带有线程锁的静态方法,来保证只能创建一个实例
if (manger==null) { //如果manger为空,那么就创建一个对象
manger=new SQLManger();
}
return manger;
}
// 建立一个私有的构造器
/***
* 包含的方法是用来连接数据库的
*/
private SQLManger(){
String driver="com.mysql.jdbc.Driver"; //连接数据库驱动
String url="jdbc:mysql://localhost:3306/clazz"; //URL指向要访问的数据库名
String user="root"; //MySQL配置时的用户名
String password="123456"; //java连接mySQL配置时的密码
try {
Class.forName(driver); //加载驱动
connection=DriverManager.getConnection(url,user,password); //与数据库建立连接
if (!connection.isClosed()) { //判断数据库是否关闭
statement=connection.createStatement(); //数据库操作类
String creatTable="create table if not exists user(id int(11) not null primary key auto_increment ,user_name varchar(30) BINARY not null,password varchar(30) BINARY not null)";
// binary的作用是区分大小写 if not exists是判断名字为user的表是否存在
statement.execute(creatTable);
System.out.println("执行创建Table成功");
}else{
System.out.println("请打开数据库");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.baidu.sqlfinal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SQLOperate {
private static SQLOperate opreate;
private SQLOperate(){
}
/**
* 该方法用来创建一个SQLOperate类型的单例
* @return 返回一个SQLOperate类型的单例
*/
public static synchronized SQLOperate newInstance(){
if (opreate==null) {
opreate=new SQLOperate();
}
return opreate;
}
/**
* 该方法用于判断是否登录成功
* @param userName 传入用户名
* @param passWrod 传入密码
* @return 如果返回为True则登录成功如果返回为False则登录失败
*/
public boolean signIn(String userName,String passWrod){
Connection conn=SQLManger.newInstance().getConnection();
try {
if (!conn.isClosed()) {
PreparedStatement state=conn.prepareStatement("select * from user where user_name=? and password=?");
/**setString中的1表示state中的第一个问号,2表示state中的第二个问号*/
state.setString(1, userName);
state.setString(2, passWrod);
ResultSet set=state.executeQuery();
set.last();
int num=set.getRow();
System.out.println("行数值为:"+num);
return num == 1;
}
} catch (SQLException e) {
e.printStackTrace();
}return false;
}
}
package com.baidu.sqlfinal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.baidu.sql.SQLManger;
public class SQLRegistered {
/***
* 单例设计模式
*/
private Statement state;
private static SQLRegistered registered;
private SQLRegistered(){
}
public static synchronized SQLRegistered newInstance(){
if (registered==null) {
registered=new SQLRegistered();
}
return registered;
}
/***
* 该方法首先判断数据库中有没有相同的数据,如果没有则添加这一条数据
* @param userName 传入用户名
* @param passWord 传入密码
*/
public void registered(String userName,String passWord){
state=SQLManger.newInstance().getStatement();
String sql="select * from user where user_name='"+userName+"'"; //判断
try {
ResultSet set=state.executeQuery(sql); //executeQuery()方法会把数据库响应的查询结果存放在ResultSet类对象中供我们使用
set.last(); //将游标放到最后
int num=set.getRow(); //获取当前行的标号
if (num>0) {
System.out.println("该用户已创建");
}else{
String register="insert into user(user_name,password) values('"+userName+"','"+passWord+"')";
state.execute(register); //执行方法找到一个与 methodName 属性同名的方法,并在目标上调用该方法
System.out.println("创建成功");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
MVC设计模式
MVC是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。
具体的我也不是太懂,
事务
事务(一组不可拆分的操作)
//银行ATM提款 输入密码 输入金额-服务器-播放录音-打开取钱口-吐钱-钱拿走
银行取款就是一整套不可分割的操作,如果中间有任何一个步骤出错,程序就会全部退回
package com.baidu.sql;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.awt.event.ActionEvent;
public class Testshiwu extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Testshiwu frame = new Testshiwu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Testshiwu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 211, 247);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
/***
* 点击事件,用于测试“事务处理”如果代码中有一句语句错误那么所有语句都不会执行,并报错
*/
JButton button = new JButton("测试");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String sql1="insert into user(user_name,password)values('sisi','123456')";
String sql2="insert into user(user_name,passwords)values('eiei','123456')";
String sql3="insert into user(user_name,password)values('yiyi','123456')";
String sql4="insert into user(user_name,password)values('soso','123456')";
Connection coon=SQLManger.newInstance().getConnection();
try {
Statement state=coon.createStatement();
//数据库连接默认每一条语句都是一个事务,会单独执行
//首先设置connection不自动提交
// coon.setAutoCommit(false);
// state.execute(sql1);
// state.execute(sql2); //执行给定的 SQL 语句,该语句可能返回多个结果
// state.execute(sql3);
// state.execute(sql4);
// //最后在提交
// coon.commit();
coon.setAutoCommit(false); //将此连接的自动提交模式设置为给定状态
state.addBatch(sql1); //将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中
state.addBatch(sql2);
state.addBatch(sql3);
state.addBatch(sql4);
state.executeBatch(); //将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组
coon.commit(); //使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
button.setBounds(49, 83, 93, 23);
contentPane.add(button);
}
}
建立Web Servlet
1.首先需要构建环境
安装tomcat插件 将com.sysdeo.eclipse.tomcat_3.3.1.jar包放入eclipse的安装路径下的plugins文件夹中
将apache_tomcat-7.0.63解压到与安装eclipse相同的磁盘(本地磁盘D)上
创建Web project,首先要选择java EE,打开project EE explorer 然后新建一个Dynamic Web Project 工程,选择 Apache Tomcat v7.0 到最后选择 Generate web.xml deployment descriptor,然后finish
2.然后在WebContent目录下的WEB-INF中创建一个html文件,如果命名为index则会默认启动执行,如果命名为其他如,SenLin.html,则需要在网址的后面加上该名称才可以运行该html文档
3.html
主要是创建serberlet用来给前段传送数据
doGet在网址后边跟上要提交的数据
http://localhost:8080/ElevenAugMyServer/MyServerLet?username=sisi&password=123456
问号后面跟的是客户端向服务端提供的数据
4.使用浏览器提交数据默认的编码格式为ISO-8859-1
1.得到String username他的编码格式为8859-1
2.使用ISO-8859-1编码格式转化成字节数组
3.在使用UTF-8编码格式将字节数组转化成字符串
其程序为
package com.baidu.test;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServerLet
*/
@WebServlet("/MyServerLet")
public class MyServerLet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServerLet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getParameter("username");
String passwrod=request.getParameter("password");
username=EnCoding.doEncoding(username);
System.out.println("用户名为"+username+"密码为"+passwrod);
String s="得到的用户名:"+username+"密码为:"+passwrod;
response.setHeader("Content-type", "text/html;charset=UTF-8");
// 让浏览器以UTF-8编码格式解析
response.getWriter().append(s);
// response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
package com.baidu.test;
import java.io.UnsupportedEncodingException;
public class EnCoding {
/***
* 这个方法是用来将ISO-8859-1类型的字符转变为UTF-8类型的字符
* @param str 传入ISO-8859-1类型的字符串
* @return 返回UTF-8类型的字符
*/
public static String doEncoding(String str){
try {
byte[] array=str.getBytes("ISO-8859-1"); //将传入的字符串转变为字节类型
str=new String(array, "UTF-8"); //将字节类型的数据转换为字符串类型
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return str;
}
}