我在国企当实习程序员的日子

没来之前,心目中的国企程序员:

1、分一个单间寝室,或者两个人一间也行。

2、饭卡吃饭只要几元就能吃到外面十几二十的东西。

3、工资没外面IT的高,但是一个月也得个6,7K 吧?

4、生活安逸,每天就插插网线,重启机子。

5、不用怕失业。

6、既然工资不高,那么福利待遇应该妥妥的吧,逢年过节送个几千的应该没问题吧。

来了之后,对应上面的想象:

1、我和一个哥们住在一个超级小的房间,里面只有(也只能有)一张床,大概2m x 3m,自己想想吧,上下铺,我在上铺,床质量很差,一动就咯吱响,第一天晚上我和这哥们都没睡着,3点的时候,我说哥们对不起啊,这床不给力啊。。

2、每个月300饭补,呵呵,在动不动十几二十一餐的一线城市哦,300。

3、工资比想象中低个3,4K而已(大概两千五),啊!拜托,期望工资已经只想要6,7K了,你还能这么刷下限。

4、一组算上我8个人,连领导都在干活,都在加班,你说安逸?不是这阵子才这样,我抱怨压力是不是有点大了,一哥们无语了,对我呵呵,说我还没见识过连续上班19天的时候。还没见识半夜被打电话叫来DEBUG的时候。

5、这个铁饭碗,还是妥妥的。

6、福利听说在去年都取消了,可能和政策有关吧,过年1000,元旦300。没了,没错,没了!这让在腾讯某部门,36个月工资的他们无语了吧。

好吧,谈谈工作吧:

让我熟悉java,eclipse和oracle!

好无语。。大二的东西,又要捡回来吗?

然后说是想看看我水平,让我写个有JTable操作的应用。

好吧,oracle还是第一次接触哦,我愧对软件学院。

==========================================吐槽到此结束====================================

========================================踏实干活才是王道===================================

功能:

1、书本录入,包括:

编号 BOOK_ID

书名 BOOK_NAME

作者 BOOK_AUTHOR

出版社 BOOK_PUBLISH

入库时间 Create_time

SQL> desc aa_book
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------

 BOOK_ID                                   NOT NULL NVARCHAR2(50)
 BOOK_NAME                                 NOT NULL VARCHAR2(100)
 BOOK_AUTHOR                               NOT NULL VARCHAR2(100)
 BOOK_PUBLISH                              NOT NULL VARCHAR2(100)
 CREATE_TIME                               NOT NULL VARCHAR2(50)

入库的时候要看看是不是主键冲突。

2、书本查询

能够按编号,作者,出版社排序。

3、书本删除

无脑删除。

4、书本修改

修改的时候要看看是不是主键冲突。

界面:

大概长这个样子:

项目免积分打包下载:http://download.csdn.net/download/xihuanqiqi/7321283

jar包都在里面了,导入即可。

数据库配置:

为了怕有的孩子不大懂Oracle,我就免为其难得把自己的配置文档共享下吧:

Ps:

首先请你安装下Oracle,然后再安装下PLSQL,然后进入PLSQL,菜单栏 -> 文件 -> 新建 -> SQL窗口,输入下面5.1到5.9的SQL命令即可。

我的Oracle版本是9i,安装图解教程:http://hi.baidu.com/yuyuliangliang/item/11ffa027ba87220842634a8a

如果实在装不懂,可以留言回复,我基本每天都会上CSDN。

1. 确认PC已装有Oracle10g,但是没有密码,无法进入。
2. 卸载Oracle10g:
 	2.1 运行services.msc,停止4个和oracle有关的服务
 	2.2 开始->程序-> Oracle - OraDb_home1 ->  Oracle Installation Products ->Universal Installer
    2.3 重启后删除原来oracle所在文件夹

3. 安装oracle9i
    D盘 默认-> 企业版 -> 通用
    全局数据库名:gt.sxtest
    SID:gt	 (操作系统环境变量)
    数据库文件目录:D:\oracle10G\oradata
	字符集:缺省的 ZHS16GBK(方便跨平台)
	服务器参数文件名:D:\oracle 10G\database\spfilegt.ora

	SYS口令:qq123qwe
	SYSTEM口令:qq123qwe 

	一开始123qwe,结果报错:ORA-00988:缺少或无效口令
	这里密码长度有限制:口令长度不能小于7个字符第一个字符不能为数字且全部字符中应该为字母和数字混合

4. 用户名 和 密码
 oracle安装会自动的生存sys用户、scott用户和system用户。
(1)sys用户是 超级用户,具有最高权限,具有sysdba角色,有create database的权限,该用户默认的密码是 change_on_install;
(2)system用户是 管理操作员,权限也很大。具有sysoper角色,没有create database的权限,默认的密码是 manager
(3)一般来讲,对数据库维护,使用system用户登录就可以了。
(4)scott普通用户,密码是tiger。

5.数据库正式开始创建:表空间+表

5.1
 创建临时表空间:
 CREATE TEMPORARY TABLESPACE AA_TEMP
	TEMPFILE ‘D:\oracle10G\oradata\gt2\AA_TEMP.dbf‘
	SIZE 32M
	AUTOEXTEND ON
	NEXT 32M MAXSIZE 2048M
	EXTENT MANAGEMENT LOCAL;

 解释:
	SIZE 是文件大小
	AUTOEXTEND ON  表示是否自动拓展
	NEXT 表示文件满了之后拓展的大小
	MAXSIZE 表示 最大文件能拓展多大
	EXTENT MANAGEMENT LOCAL表示本地表空间管理。

5.2
 创建表空间:
 CREATE TABLESPACE AA

	LOGGING
	DATAFILE ‘D:\oracle10G\oradata\gt2\aa.dbf‘

	SIZE 32M
	AUTOEXTEND ON
	NEXT 32M MAXSIZE 2048M
	EXTENT MANAGEMENT LOCAL;

5.3
 创建用户并把表空间指定给用户
	CREATE USER AA_USER IDENTIFIED BY AA_PASS

	DEFAULT TABLESPACE AA

	TEMPORARY TABLESPACE AA_TEMP;

5.4
 给用户赋权
 GRANT
 CREATE SESSION, CREATE ANY TABLE ,CREATE ANY VIEW, CREATE ANY INDEX,CREATE ANY PROCEDURE,
 ALTER ANY TABLE, ALTER ANY PROCEDURE,
 DROP ANY TABLE, DROP ANY VIEW , DROP ANY INDEX, DROP ANY PROCEDURE,
 SELECT ANY TABLE, INSERT ANY TABLE, UPDATE ANY TABLE ,DELETE ANY TABLE
 TO AA_USER;

5.5
 给用户赋予角色
 GRANT
 CONNECT ,RESOURCE, DBA TO AA_USER;

 取消授予角色;revoke dba from AA_USER;

5.6
 建表
 CREATE TABLE AA_BOOK(
	book_id varchar2(50) not null,
	book_name varchar2(100) not null,
	book_author varchar2(100) not null,
	book_publish varchar2(100) not null,
	create_time varchar2(50) default to_char(sysdate,‘yyyy-MM-d HH:mm:ss‘) not null,
	constraint pk_book primary key (book_id)
	)
	tablespace AA

5.7
 插入数据
insert into aa_book(book_id,book_name,book_author,book_publish,create_time) values(‘1ABBC1‘,‘一本书‘,‘一个作者‘,‘一家出版社‘,‘2014-05-06‘)

说两点:
1.不能带‘;‘,否则会提示无效字符
2.字符串用单引号,而不能用双引号

这就是配置文档了,如果有人想实现ID自增,类似MySQL和MSSQL那样,可以这么操作(注意下BOOK_ID已经变成了number类型):

5.1
 创建临时表空间:
 CREATE TEMPORARY TABLESPACE AA_TEMP
	TEMPFILE ‘D:\oracle10G\oradata\gt2\AA_TEMP.dbf‘
	SIZE 32M
	AUTOEXTEND ON
	NEXT 32M MAXSIZE 2048M
	EXTENT MANAGEMENT LOCAL;

 解释:
	SIZE 是文件大小
	AUTOEXTEND ON  表示是否自动拓展
	NEXT 表示文件满了之后拓展的大小
	MAXSIZE 表示 最大文件能拓展多大
	EXTENT MANAGEMENT LOCAL表示本地表空间管理。

5.2
 创建表空间:
 CREATE TABLESPACE AA

	LOGGING
	DATAFILE ‘D:\oracle10G\oradata\gt2\aa.dbf‘

	SIZE 32M
	AUTOEXTEND ON
	NEXT 32M MAXSIZE 2048M
	EXTENT MANAGEMENT LOCAL;

5.3
 创建用户并把表空间指定给用户
	CREATE USER AA_USER IDENTIFIED BY AA_PASS

	DEFAULT TABLESPACE AA

	TEMPORARY TABLESPACE AA_TEMP;

5.4
 给用户赋权
 GRANT
 CREATE SESSION, CREATE ANY TABLE ,CREATE ANY VIEW, CREATE ANY INDEX,CREATE ANY PROCEDURE,
 ALTER ANY TABLE, ALTER ANY PROCEDURE,
 DROP ANY TABLE, DROP ANY VIEW , DROP ANY INDEX, DROP ANY PROCEDURE,
 SELECT ANY TABLE, INSERT ANY TABLE, UPDATE ANY TABLE ,DELETE ANY TABLE
 TO AA_USER;

5.5
 给用户赋予角色
 GRANT
 CONNECT ,RESOURCE, DBA TO AA_USER;

 取消授予角色;revoke dba from AA_USER;

5.6
 建表
 CREATE TABLE AA_BOOK(
	book_id number(10,0) not null,
	book_name varchar2(100) not null,
	book_author varchar2(100) not null,
	book_publish varchar2(100) not null,
	create_time varchar2(50) default to_char(sysdate,‘yyyy-MM-d HH:mm:ss‘) not null,
	constraint pk_book primary key (book_id)
	)
	tablespace AA

5.7
 建立序列
 CREATE SEQUENCE emp_sequence
	 INCREMENT BY 1
	 START WITH 1
	 NOMAXVALUE
	 NOCYCLE
	 NOCACHE

	以上代码完成了一个序列(sequence)的建立过程,名称为emp_sequence
	范围是从1开始到无限大(无限大的程度是由你机器决定的),nocycle 是决定不循环
	如果你设置了最大值那么你可以用cycle 会使seq到最大之后循环.
	对于nocache顺便说一下如果你给出了cache值那么系统将自动读取你的cache值大小个seq

5.8
 建立触发器 - 实现自增ID

 CREATE OR REPLACE TRIGGER AA_INSERT_TRIGGER
 BEFORE INSERT ON AA_BOOK
 FOR EACH ROW

 BEGIN
        SELECT emp_sequence.nextval into :new.book_id from dual;
 END;

5.9
 插入数据
insert into aa_book(book_name,book_author,book_publish,create_time) values(‘一本书‘,‘一个作者‘,‘一家出版社‘,‘2014-05-06‘)

对我来说的项目亮点:

1、JTable 中实现 “删除”按钮和“编辑”按钮,这个很屌,不是吗。

2、Oracle连接代码(以前没接触过哦,所以比较新鲜)。

3、JTable 配合 DefaultTableModel,清空数据啊,添加数据啊,都是以前没搞过的。

4、父窗口和模态窗口的研究:

	这个长知识了,原来JFrame不具备模态窗口的条件:

		//Window类的构造:
		Window(GraphicsConfiguration gc){} //Frame和JFrame采用了这个构造方法

		//下面这三个构造方法才能拓展出模态窗口,因为它们指定了一个Frame或Window作为其所有者
		Window(Frame owner){}
		Window(Window owner){}
		Window(Window owner, GraphicsConfiguration gc){}

	所以要改用JDialog!

	Dialog继承的是Window类,它的构造如下:
	public Dialog(Frame owner, String title, boolean modal, GraphicsConfiguration gc) {
		super(owner, gc); //重点在这里,所以它可以设置模态
		this.title = title;
		this.modal = modal;
		setFocusTraversalPolicy(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalPolicy());
	}

	JFrame和它的父类Frame的构造:
	public Frame(String title, GraphicsConfiguration gc) {
		super(gc); //采用了Window的第一种构造
		init(title, gc);
	}

5、对精简代码的一些小感悟:

5.1 同一个功能尽可能多封装在一个函数:

我把JRadioButton部分代码,放到刷新JTable的函数中:
	用一个判断作为一个分支:
			if(sql.equals(SELECT_ALL_SQL)){
				String postfix = null;
				if(idRB.isSelected()){
					postfix = " order by book_id";
				}else if(authorRB.isSelected()){
					postfix = " order by book_author";
				}else if(publishRB.isSelected()){
					postfix = " order by book_publish";
				}
				sql += postfix;
			}

这样子很烦,因为出现不少次呢,所以封装成getPostfix(),每次:SQL+=getPostfix()即可:

	/*
	 * 获取排序后缀字符串:order by xx 返回值为String
	 */
	private String getPostfix() {
		String postfix = null;
		if (idRB.isSelected()) {
			postfix = " order by book_id";
		} else if (authorRB.isSelected()) {
			postfix = " order by book_author";
		} else if (publishRB.isSelected()) {
			postfix = " order by book_publish";
		}
		return postfix;
	}

5.2 用try - catch来帮助做一些判断:

	在录入的时候,如果数据库中已有主键,try会报错。
	此时,我们把报错信息省略。
	catch (SQLException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
	}
	因为报错看起来不美丽。

	然后因为update失败,返回的影响行数就 不是 > 0所以就能判断出update失败。
	类似;
	if(DBHelper.update(sql, pras) > 0 ){
		JOptionPane.showMessageDialog(null, "录入成功!");
		reflashTableData(SELECT_ALL_SQL,null);
	}else{
		JOptionPane.showMessageDialog(null, "书本编号已存在!", "错误哦~", JOptionPane.ERROR_MESSAGE);
	}

5.3 去掉一些傻逼逻辑:

比如说,table更新获得焦点:
	这是之前的代码:
	 //默认情况焦点放到最后一行,除非指定focusOnRowIndex
	int allRowsCount = table.getRowCount();
	if(focusOnRowIndex == -1){
		table.requestFocus();
		table.setRowSelectionInterval(allRowsCount-1, allRowsCount-1);//最后一行获得焦点
	}else{
		table.requestFocus();
		if(allRowsCount-1 + 1  == focusOnRowIndex){//如果是最后一行
			table.setRowSelectionInterval(allRowsCount-1, allRowsCount-1);//最后一行获得焦点
		}else
			table.setRowSelectionInterval(focusOnRowIndex, focusOnRowIndex);//选中那一行获得焦点
	}

	这是之后的代码!:
	int allRowsCount = table.getRowCount();
	table.requestFocus();
	if(focusOnRowIndex == -1  || (allRowsCount-1 + 1)  == focusOnRowIndex)
		table.setRowSelectionInterval(allRowsCount-1, allRowsCount-1);
	else
		table.setRowSelectionInterval(focusOnRowIndex, focusOnRowIndex);

5.4 一个函数控制不要超过40行:

一个函数如果太多行,就分几个写。
比如说我的initUI(),要实现两个panel的界面:searchPanel和inputPanel,
写在一起就太长了,于是我就: initSearchPanel() 和 initInputPanel()
然后再initUI()中调用这两个函数就好了。

5.5 try catch 的东西可以写在一起:

比如:
		try{
			//语句块A
		}catch{

		}

		try{
			//语句块B
		}catch{

		}   

		写成:
		try{
			//语句块A
			//语句块B
		}catch{

		}

5.6 加注释:

		这个要考虑清楚什么叫精简代码,首先注释不算代码量;
		其次,注释能帮人更好的阅读代码,也和我们精简代码的期望是一致的。

		基本做到每个函数前面有基本的注释,如:
		/*
		 * 这个函数是干嘛用的!
		 */
		 private void test(){
		 }

代码:

其实不建议直接看代码,虽然我每个函数都有注释,但是依旧很长很烦。

建议把项目下载(免积分下载哦),然后导入,然后再稍微看看。

如果我有什么讲得不清楚,或者某段代码不明白,可以留言,我都会回复的。

DBHelper.java:

这个数据库操作全集成在这里了。。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DBHelper {
	//数据库驱动对象
	public static final String DRIVER="oracle.jdbc.driver.OracleDriver";

	//连接字符串
	public static final String URL="jdbc:oracle:thin:@localhost:1521:gt2";

	//Username
	public static final String USER="system";

	//Password
	public static final String PWD="qq123qwe";

	private static Connection con=null; //数据库连接对象
	private static PreparedStatement ps=null;  //预编译对象
	private static ResultSet rs=null;          //结果集
	private static DataSource source=null; //数据源对象

	//获取连接对象
	public static Connection getConnection(){
		try {
			Class.forName(DRIVER);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			con=DriverManager.getConnection(URL,USER,PWD);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return con;
	}

	//更新,插入,删除
	public static int update(String sql,String... pras){
		int resu=0;
		if(con == null){
			con=getConnection();
		}
		try {
			ps=con.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
			if(pras != null){
				for(int i=0;i<pras.length;i++){
					ps.setString(i+1,pras[i]);
				}
			}
			resu=ps.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
		finally{
			//closeAllObject();
		}
		return resu;
	}

	//查询
	public static ResultSet query(String sql,String... pras){
		if(con == null){
			con=getConnection();
		}
		try {
			ps=con.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

			if(pras!=null)
				for(int i=0;i<pras.length;i++){
					ps.setString(i+1, pras[i]);
				}

			rs=ps.executeQuery();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return rs;
	}

	//关闭所有对象
	public static void closeAllObject(){
		if(rs!=null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if(ps!=null){
			try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if(con!=null){
			try {
				con.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

GTSX_Text1.java:

实现一个书本入库管理系统,能够:增删改查!

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import java.sql.*;
import java.text.SimpleDateFormat;

//第三方控件
import hysun.util.DateChooser;
import java.util.Calendar;

public class GTSX_Text1 {
	public static void main(String args[]) {
		new MainFrame();
	}
}

class MainFrame extends JFrame implements ActionListener {

	public MainFrame() {
		super("书本入库管理系统");

		// 初始化 - UI
		contentPane = this.getContentPane();
		contentPane.setLayout(new FlowLayout());

		initSearchPanel();// 搜索显示面板
		initInputPanel(); // 书本入库信息录入面板

		// 初始化菜单栏
		initMenuBar();

		// 初始化表格数据
		reflashTableData(SELECT_ALL_SQL);

		// 设置 大小 & 显示位置
		initHeightAndWidthAndPos();
		this.setSize(width, height);
		this.setLocation(xPos, yPos);
		this.setVisible(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);

	}

	/*
	 * 初始化UI - SearchPanel
	 */
	private void initSearchPanel() {
		// 初始化UI - searchPanel
		searchPanel = new JPanel();
		contentPane.add(searchPanel, BorderLayout.CENTER);

		searchPanel.setLayout(bag);

		JLabel label1 = new JLabel("请输入书名:");
		goBtn = new JButton("查询");
		goBtn.addActionListener(this);
		text = new JTextField(25);

		BG = new ButtonGroup();
		idRB = new JRadioButton("按书本编号排序");
		authorRB = new JRadioButton("按作者排序");
		publishRB = new JRadioButton("按出版社排序");
		BG.add(idRB);
		BG.add(authorRB);
		BG.add(publishRB);
		idRB.addActionListener(this);
		authorRB.addActionListener(this);
		publishRB.addActionListener(this);

		idRB.setSelected(true);// 默认选中按书本编号查询

		// 初始化UI - searchPanel - table
		table = new JTable();

		scrollPane = new JScrollPane();
		scrollPane.setViewportView(table);
		scrollPane.setPreferredSize(new Dimension(500, 400));

		setCons(0, 3, 4, 3);
		searchPanel.add(scrollPane, c);

		setCons(0, 0, 1, 1);
		searchPanel.add(label1, c);

		setCons(1, 0, 2, 1);
		searchPanel.add(text, c);

		setCons(0, 1, 1, 1);
		searchPanel.add(idRB, c);

		setCons(1, 1, 1, 1);
		searchPanel.add(authorRB, c);

		setCons(2, 1, 1, 1);
		searchPanel.add(publishRB, c);

		setCons(4, 0, 1, 1);
		searchPanel.add(goBtn, c);
	}

	/*
	 * 初始化UI - inputPanel
	 */
	private void initInputPanel() {
		inputPanel = new JPanel();
		contentPane.add(inputPanel, BorderLayout.EAST);
		inputPanel.setLayout(bag);

		JLabel lb0 = new JLabel("书本编码:");
		setCons(0, 0, 1, 1);
		inputPanel.add(lb0, c);

		book_idTF = new JTextField(10);
		setCons(1, 0, 1, 1);
		inputPanel.add(book_idTF, c);

		JLabel lb2 = new JLabel("书名:");
		setCons(0, 1, 1, 1);
		inputPanel.add(lb2, c);

		book_nameTF = new JTextField(10);
		setCons(1, 1, 1, 1);
		inputPanel.add(book_nameTF, c);

		JLabel lb3 = new JLabel("作者:");
		setCons(0, 2, 1, 1);
		inputPanel.add(lb3, c);

		book_authorTF = new JTextField(10);
		setCons(1, 2, 1, 1);
		inputPanel.add(book_authorTF, c);

		JLabel lb5 = new JLabel("入库时间:");
		setCons(0, 3, 1, 1);
		inputPanel.add(lb5, c);

		book_dateTF = new JTextField(10);
		setCons(1, 3, 1, 1);
		inputPanel.add(book_dateTF, c);

		JButton select_date_btn = new JButton("选择日期");
		setCons(2, 3, 1, 1);
		inputPanel.add(select_date_btn, c);

		select_date_btn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				dc.setLocationRelativeTo(book_dateTF);
				dc.setVisible(true);
				Calendar cal = dc.getSelectedDate();
				if (cal != null) {
					book_dateTF.setText(FORMATTER.format(cal.getTime()));
				}
			}

		});

		JLabel lb4 = new JLabel("出版社:");
		setCons(0, 4, 1, 1);
		inputPanel.add(lb4, c);

		String nations[] = { "广东出版社", "工业出版社", "湖南出版社", "卖萌出版社" };
		book_publishCB = new JComboBox(nations);
		book_publishCB.setMaximumSize(new Dimension(115, 20));
		book_publishCB.setMinimumSize(new Dimension(115, 20));
		book_publishCB.setPreferredSize(new Dimension(115, 20));

		setCons(1, 4, 1, 1);
		inputPanel.add(book_publishCB, c);

		inputBtn = new JButton("录入");
		inputBtn.addActionListener(this);
		setCons(1, 5, 1, 1);
		inputPanel.add(inputBtn, c);
	}

	/*
	 * GridBird 网格布局辅助函数
	 */
	public void setCons(int x, int y, int width, int height) {
		c.weightx = 1;
		c.weighty = 1;
		c.gridheight = height;
		c.gridwidth = width;
		c.gridx = x;
		c.gridy = y;
	}

	/*
	 * 初始化菜单栏
	 */
	private void initMenuBar() {
		// TODO Auto-generated method stub
		menuBar = new JMenuBar();
		menu = new JMenu("书本管理");
		addBookItem = new JMenuItem("加一本书");
		exitItem = new JMenuItem("退出");
		addBookItem.addActionListener(this);
		exitItem.addActionListener(this);
		menu.add(addBookItem);
		menu.add(exitItem);
		menuBar.add(menu);
		this.setJMenuBar(menuBar);
	}

	/*
	 * 刷新表格数据 - 重载 1
	 */
	private void reflashTableData(String sql, String... pras) {
		reflashTableData(sql, -1, pras);
	}

	/*
	 * 刷新表格数据 - 重载2 int focusOnRowIndex; 是说明下要哪一行获得焦点。 -1表示默认情况,最后一行
	 */
	private void reflashTableData(String sql, int focusOnRowIndex,
			String... pras) {

		// 清空JTable
		if (dtm != null) {
			dtm.setRowCount(0);
		}

		// 没有搜索条件就全排,默认加上order by xx
		if (sql.equals(SELECT_ALL_SQL)) {
			sql += getPostfix();
		}

		ResultSet rs = DBHelper.query(sql, pras);
		fillCellData(rs);// 填充cellData数据
		String[] columnNames = { "编号", "书名", "作者", "出版社", "入库时间", "DEL", "Edit" };
		dtm = new myTablemodel(cellData, columnNames);
		table.setModel(dtm);

		// 删除按钮
		this.table.getColumnModel().getColumn(delColumnIndex).setCellEditor(
				new MyDelButtonEditor(this.table));
		this.table.getColumnModel().getColumn(delColumnIndex).setCellRenderer(
				new MyButtonRender("Del"));

		// 编辑按钮
		this.table.getColumnModel().getColumn(editColumnIndex).setCellEditor(
				new MyEditButtonEditor(this.table, this));
		this.table.getColumnModel().getColumn(editColumnIndex).setCellRenderer(
				new MyButtonRender("Edit"));

		this.table.setRowHeight(25);

		// 设置行焦点,默认最后一行,如果UI有操作就当前行
		int allRowsCount = table.getRowCount();
		table.requestFocus();
		if (focusOnRowIndex == -1 || (allRowsCount - 1 + 1) == focusOnRowIndex)
			table.setRowSelectionInterval(allRowsCount - 1, allRowsCount - 1);
		else
			table.setRowSelectionInterval(focusOnRowIndex, focusOnRowIndex);
	}

	/*
	 * 获取排序后缀字符串:order by xx 返回值为String
	 */
	private String getPostfix() {
		String postfix = null;
		if (idRB.isSelected()) {
			postfix = " order by book_id";
		} else if (authorRB.isSelected()) {
			postfix = " order by book_author";
		} else if (publishRB.isSelected()) {
			postfix = " order by book_publish";
		}
		return postfix;
	}

	/*
	 * 获取JTable 的 CellData 填充CellData的数据
	 */
	private void fillCellData(ResultSet rs) {
		int rowCount = 0;
		try {
			columnNumber = rs.getMetaData().getColumnCount() + 2;// 加一个编辑一个删除

			rs.last();
			rowCount = rs.getRow();
			if (rowCount > 0) {
				cellData = new Object[rowCount][columnNumber];
			} else {
				cellData = new Object[1][columnNumber];
				cellData[0][0] = "查无数据";
			}
			rs.beforeFirst();

			// 给cellData赋值
			if (rs != null) {
				int i = 0;
				while (rs.next()) {
					for (int j = 0; j < columnNumber - 2; j++) {
						cellData[i][j] = rs.getObject(j + 1);
					}
					i++;
				}
			}

		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	/*
	 * 初始化UI的长宽和初始显示位置
	 */
	private void initHeightAndWidthAndPos() {
		// TODO Auto-generated method stub
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension screenSize = tk.getScreenSize();
		height = screenSize.height * 2 / 3;
		width = screenSize.width * 3 / 4;
		xPos = (screenSize.width - width) / 2;
		yPos = (screenSize.height - height) / 2;
	}

	/*
	 * 响应按钮监听函数 (non-Javadoc)
	 *
	 * @see
	 * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getSource() == goBtn) {
			String searchText = this.text.getText();
			if (searchText == "" || searchText.equals("")) {
				reflashTableData(SELECT_ALL_SQL, null);
			} else {
				String postfix = null;
				if (idRB.isSelected()) {
					postfix = " order by book_id";
				} else if (authorRB.isSelected()) {
					postfix = " order by book_author";
				} else if (publishRB.isSelected()) {
					postfix = " order by book_publish";
				}

				String sql = "select * from aa_book where book_id = ‘"
						+ searchText + "‘" + postfix;
				// System.out.println(sql);
				reflashTableData(sql, null);
			}

		}
		if (e.getSource() == inputBtn) {
			String book_id_text = this.book_idTF.getText();
			String book_name_text = this.book_nameTF.getText();
			String book_author_text = this.book_authorTF.getText();
			String book_publish_text = this.book_publishCB.getSelectedItem()
					.toString();
			String book_date_text = this.book_dateTF.getText();
			if (book_name_text.equals("") || book_author_text.equals("")
					|| book_publish_text.equals("")
					|| book_date_text.equals("")) {
				JOptionPane.showMessageDialog(null, "请您填写完整的数据!", "错误哦~",
						JOptionPane.ERROR_MESSAGE);
			} else {
				String sql = "insert into aa_book(book_id,book_name,book_author,book_publish,create_time) values(?,?,?,?,?)";
				String pras[] = { book_id_text, book_name_text,
						book_author_text, book_publish_text, book_date_text };

				if (DBHelper.update(sql, pras) > 0) {
					JOptionPane.showMessageDialog(null, "录入成功!");
					reflashTableData(SELECT_ALL_SQL, null);
				} else {
					JOptionPane.showMessageDialog(null, "书本编号已存在!", "错误哦~",
							JOptionPane.ERROR_MESSAGE);
				}

			}
		}

		if(e.getSource() == idRB || e.getSource() == authorRB || e.getSource() == publishRB){
			reflashTableData(SELECT_ALL_SQL, null);
		}
	}

	/*
	 * 自定义类myTablemodel 自定义的DefaultTableModel 方便控制是否可编辑等属性
	 */
	class myTablemodel extends DefaultTableModel {
		myTablemodel(Object[][] cells, String[] colnames) {
			super(cells, colnames);
		}

		public boolean isCellEditable(int row, int column) {
			if (column == delColumnIndex || column == editColumnIndex) {
				return true;
			} else {
				return false;
			}
		}

	}

	/*
	 * 自定义类MyDelButtonEditor 用来放在JTable中
	 */
	public class MyDelButtonEditor extends DefaultCellEditor {
		private static final long serialVersionUID = -6546334664166791132L;

		private JPanel panel;

		private JButton button;

		public MyDelButtonEditor(JTable table) {
			// TODO Auto-generated constructor stub
			// DefautlCellEditor有此构造器,需要传入一个,但这个不会使用到,直接new一个即可。
			super(new JTextField());

			// 设置点击几次激活编辑。
			this.setClickCountToStart(1);

			this.initButton(table);

			this.initPanel();

			// 添加按钮。
			this.panel.add(this.button);
		}

		private void initButton(final JTable table) {
			this.button = new JButton();

			// 设置按钮的大小及位置。
			this.button.setBounds(0, 0, 50, 15);

			// 为按钮添加事件。这里只能添加ActionListner事件,Mouse事件无效。
			this.button.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					int res = JOptionPane.showConfirmDialog(null, "确认删除?",
							"请确定是否删除该行数据", JOptionPane.YES_NO_OPTION);
					if (res == JOptionPane.YES_OPTION) {
						int rowIndex = table.getSelectedRow();
						Object book_id = table.getModel().getValueAt(rowIndex,
								0);
						// System.out.println(book_id.toString());

						String sql = "delete from aa_book where book_id = ‘"
								+ book_id.toString() + "‘";
						if (DBHelper.update(sql, null) > 0) {
							JOptionPane.showMessageDialog(null, "删除成功");
							reflashTableData(SELECT_ALL_SQL, rowIndex);
						}

					}
					// 触发取消编辑的事件,不会调用tableModel的setValue方法。
					MyDelButtonEditor.this.fireEditingCanceled();

					// 这里可以做其它操作。
					// 可以将table传入,通过getSelectedRow,getSelectColumn方法获取到当前选择的行和列及其它操作等。
				}
			});

		}

		private void initPanel() {
			this.panel = new JPanel();

			// panel使用绝对定位,这样button就不会充满整个单元格。
			this.panel.setLayout(null);
		}

		/**
		 * 这里重写父类的编辑方法,返回一个JPanel对象即可(也可以直接返回一个Button对象,但是那样会填充满整个单元格)
		 */
		@Override
		public Component getTableCellEditorComponent(JTable table,
				Object value, boolean isSelected, int row, int column) {
			// 只为按钮赋值即可。也可以作其它操作。
			this.button.setText(value == null ? "DEL" : String.valueOf(value));

			return this.panel;
		}

		/**
		 * 重写编辑单元格时获取的值。如果不重写,这里可能会为按钮设置错误的值。
		 */
		@Override
		public Object getCellEditorValue() {
			return this.button.getText();
		}
	}

	/*
	 * 自定义类MyEditButtonEditor 用来放在JTable中
	 */
	public class MyEditButtonEditor extends DefaultCellEditor {
		private static final long serialVersionUID = -6546334664166791132L;

		private JPanel panel;

		private JButton button;

		public MyEditButtonEditor(JTable table, MainFrame mf) {
			// TODO Auto-generated constructor stub
			// DefautlCellEditor有此构造器,需要传入一个,但这个不会使用到,直接new一个即可。
			super(new JTextField());

			// 设置点击几次激活编辑。
			this.setClickCountToStart(1);

			this.initButton(table, mf);

			this.initPanel();

			// 添加按钮。
			this.panel.add(this.button);
		}

		private void initButton(final JTable table, final MainFrame mf) {
			this.button = new JButton();

			// 设置按钮的大小及位置。
			this.button.setBounds(0, 0, 50, 15);

			// 为按钮添加事件。这里只能添加ActionListner事件,Mouse事件无效。
			this.button.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					EditDialog ed = new EditDialog(mf);
					// 触发取消编辑的事件,不会调用tableModel的setValue方法。
					MyEditButtonEditor.this.fireEditingCanceled();

					// 这里可以做其它操作。
					// 可以将table传入,通过getSelectedRow,getSelectColumn方法获取到当前选择的行和列及其它操作等。
				}
			});

		}

		private void initPanel() {
			this.panel = new JPanel();

			// panel使用绝对定位,这样button就不会充满整个单元格。
			this.panel.setLayout(null);
		}

		/**
		 * 这里重写父类的编辑方法,返回一个JPanel对象即可(也可以直接返回一个Button对象,但是那样会填充满整个单元格)
		 */
		@Override
		public Component getTableCellEditorComponent(JTable table,
				Object value, boolean isSelected, int row, int column) {
			// 只为按钮赋值即可。也可以作其它操作。
			this.button.setText(value == null ? "DEL" : String.valueOf(value));

			return this.panel;
		}

		/**
		 * 重写编辑单元格时获取的值。如果不重写,这里可能会为按钮设置错误的值。
		 */
		@Override
		public Object getCellEditorValue() {
			return this.button.getText();
		}
	}

	/*
	 * 自定义类EditDialog 用来放在修改书本信息
	 */
	class EditDialog {
		private JTextField book_id_TF;
		private JTextField book_name_TF;
		private JTextField book_author_TF;
		private JTextField book_publish_TF;
		private JTextField book_date_TF;
		private JPanel panel;
		private JButton saveBtn;
		private String orgBookID;

		public EditDialog(JFrame father) {
			final JDialog jd = new JDialog(father, "编辑书本信息", true);

			panel = new JPanel();
			Container jd_contentPane = jd.getContentPane();

			jd_contentPane.setLayout(bag);

			TableModel tm = table.getModel();
			int row = table.getSelectedRow();

			orgBookID = tm.getValueAt(row, 0).toString();

			JLabel lb0 = new JLabel("书本编码:");
			book_id_TF = new JTextField(20);
			book_id_TF.setText(tm.getValueAt(row, 0).toString());

			JLabel lb1 = new JLabel("书名:");
			book_name_TF = new JTextField(20);
			book_name_TF.setText(tm.getValueAt(row, 1).toString());

			JLabel lb2 = new JLabel("作者:");
			book_author_TF = new JTextField(20);
			book_author_TF.setText(tm.getValueAt(row, 2).toString());

			JLabel lb3 = new JLabel("出版社:");
			book_publish_TF = new JTextField(20);
			book_publish_TF.setText(tm.getValueAt(row, 3).toString());

			JLabel lb4 = new JLabel("入库日期:");
			book_date_TF = new JTextField(20);
			book_date_TF.setText(tm.getValueAt(row, 4).toString());

			// panel.setLayout(bag);

			setCons(0, 0, 1, 1);
			jd_contentPane.add(lb0, c);
			setCons(1, 0, 1, 1);
			jd_contentPane.add(book_id_TF, c);

			setCons(0, 1, 1, 1);
			jd_contentPane.add(lb1, c);
			setCons(1, 1, 1, 1);
			jd_contentPane.add(book_name_TF, c);

			setCons(0, 2, 1, 1);
			jd_contentPane.add(lb2, c);
			setCons(1, 2, 1, 1);
			jd_contentPane.add(book_author_TF, c);

			setCons(0, 3, 1, 1);
			jd_contentPane.add(lb3, c);
			setCons(1, 3, 1, 1);
			jd_contentPane.add(book_publish_TF, c);

			setCons(0, 4, 1, 1);
			jd_contentPane.add(lb4, c);
			setCons(1, 4, 1, 1);
			jd_contentPane.add(book_date_TF, c);

			saveBtn = new JButton("修改");
			setCons(1, 5, 1, 1);
			jd_contentPane.add(saveBtn, c);
			saveBtn.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent arg0) {
					// TODO Auto-generated method stub
					String book_id = book_id_TF.getText();
					String book_name = book_name_TF.getText();
					String book_author = book_author_TF.getText();
					String book_publish = book_publish_TF.getText();
					String book_date = book_date_TF.getText();

					// 请注意!!!!!!!!!!!!!
					// 这边逻辑太多了,就偷懒,默认四个都不为空都会修改吧
					String sql = "update aa_book set book_id = ?, book_name = ? , book_author = ? , book_publish = ? , create_time = ? where book_id = ?";
					String[] pras = { book_id, book_name, book_author,
							book_publish, book_date, orgBookID };

					if (DBHelper.update(sql, pras) > 0) {
						JOptionPane.showMessageDialog(null, "修改成功!");
						reflashTableData(SELECT_ALL_SQL, null);
						jd.dispose();

					} else {
						JOptionPane.showMessageDialog(null, "书本编号冲突!",
								"ERROR! 修改不成功!", JOptionPane.ERROR_MESSAGE);
					}
				}

			});

			jd.setSize(400, 300);
			Toolkit tk = Toolkit.getDefaultToolkit();
			Dimension screenSize = tk.getScreenSize();
			height = screenSize.height * 1 / 3;
			width = screenSize.width * 1 / 4;

			int xPos = (screenSize.width - width) / 2;
			int yPos = (screenSize.height - height) / 2;
			jd.setLocation(xPos, yPos);
			jd.setVisible(true);
		}
	}

	private JPanel panel;
	private Container contentPane;
	private JPanel searchPanel;
	private JPanel inputPanel;
	private int height, width, xPos, yPos;
	private JMenuBar menuBar;
	private JMenu menu;
	private JMenuItem addBookItem;
	private JMenuItem exitItem;
	private JTable table;
	private Object[][] cellData;
	private JScrollPane scrollPane;
	private int columnNumber;
	private int defaultRowsNum;
	GridBagLayout bag = new GridBagLayout();
	GridBagConstraints c = new GridBagConstraints();
	private JButton goBtn;
	private JTextField text;
	private myTablemodel dtm = null;
	private JTextField book_idTF;
	private JTextField book_nameTF;
	private JTextField book_authorTF;
	private JComboBox book_publishCB;
	private JTextField book_dateTF;
	private JButton inputBtn;
	final DateChooser dc = new DateChooser(this, true);
	private static final SimpleDateFormat FORMATTER = new SimpleDateFormat(
			"yyyy-MM-dd");
	private int delColumnIndex = 5;
	private int editColumnIndex = 6;
	private String SELECT_ALL_SQL = "select * from aa_book";
	private ButtonGroup BG;
	private JRadioButton idRB;
	private JRadioButton authorRB;
	private JRadioButton publishRB;
}

MyButtonRender.java:

辅助类,用来调整JTable中的JButton属性。

import java.awt.Component;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class MyButtonRender implements TableCellRenderer
{
    private JPanel panel;  

    private JButton button;  

    private String nameOfBtn;

    public MyButtonRender(String btnName)
    {
    	nameOfBtn = btnName;

        this.initButton();  

        this.initPanel();  

        // 添加按钮。
        this.panel.add(this.button);
    }  

    private void initButton()
    {
        this.button = new JButton();  

        // 设置按钮的大小及位置。
        this.button.setBounds(5, 2, 60, 20);  

        // 在渲染器里边添加按钮的事件是不会触发的
        // this.button.addActionListener(new ActionListener()
        // {
        //
        // public void actionPerformed(ActionEvent e)
        // {
        // // TODO Auto-generated method stub
        // }
        // });  

    }  

    private void initPanel()
    {
        this.panel = new JPanel();  

        // panel使用绝对定位,这样button就不会充满整个单元格。
        this.panel.setLayout(null);
    }  

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
            int column)
    {
        // 只为按钮赋值即可。也可以作其它操作,如绘背景等。
        //this.button.setText(value == null ? "DEL" : String.valueOf(value));
        this.button.setText(nameOfBtn);

        return this.panel;
    }  

}

emaster  关注信息安全的胖子

欢迎转载,但转载请注明地址:http://blog.csdn.net/emaste_r/article/details/25384691

我在国企当实习程序员的日子,布布扣,bubuko.com

时间: 2024-10-12 16:02:29

我在国企当实习程序员的日子的相关文章

我在国企当实习程序猿的日子

没来之前,心目中的国企程序猿: 1.分一个单间寝室,或者两个人一间也行. 2.饭卡吃饭仅仅要几元就能吃到外面十几二十的东西. 3.工资没外面IT的高,可是一个月也得个6,7K 吧? 4.生活安逸.每天就插插网线.重新启动机子. 5.不用怕失业. 6.既然工资不高,那么福利待遇应该妥妥的吧.逢年过节送个几千的应该没问题吧. 来了之后,相应上面的想象: 1.我和一个哥们住在一个超级小的房间,里面仅仅有(也仅仅能有)一张床,大概2m x 3m.自己想想吧,上下铺,我在上铺.床质量非常差,一动就咯吱响,

为什么程序员话少钱多死得早?-一位人生悲惨的程序员与你讲述其中原因

引子: 有一个段子:女人爱找程序员当男朋友,因为程序员话少钱多死得早. 哇咔咔,哈哈哈. 其实最开始听到这个词的时候我是拒绝的.因为我觉得我话挺多的,无论和谁,只要唠开了,就能滔滔不绝的唠下去: "哎呀老铁,你说的太对了,还有个事跟你说说--&%--¥--%--()&--%&%¥%--&". 所以我在想,程序员都是话少吗?不一定吧,像我和我的同学,都是话很多啊.但是经历过很多事的现在,再想想,发现事实的确如此,程序员确实话少. 为什么有人说我们话少: 首

Github上安卓榜排名第2的程序员教你如何学习【转载,侵删】

来自:峰瑞资本(微信号:freesvc)文章作者:代码家(微信 ID:daimajia_share) 软件早已吞噬整个世界,程序员是关键角色.过去 40 年中,许多伟大的公司都由程序员缔造,比如比尔·盖茨.拉里·埃里森.马克·扎克伯格.伊隆·马斯克. 一本哥哥不太关心的 Visual Basic 课外书,代码家如获至宝,他接触了简单的代码,这让他进入到一个全新的世界.从那之后,代码家一直享受着用代码解决问题过程中产生的精神愉悦,并成长为一名专家级程序员.用行话说,黑客.现在,代码家是 Githu

程序员的出路(要非常专一门技术才行,超过80%的同行,或者积累自己的类库和产品)

今天看到这样一篇文章,感觉太好了,拿出来当做自勉吧. http://www.cnblogs.com/zhuweisky/archive/2013/04/27/3046585.html 就现在经济大环境而言,很不乐观,程序员的日子也很不好过,无论是还在找工作的.还是已经入职多年.哪怕做到项目经理技术经理的,压力都异常巨大,似乎处处充满危机.但是,仔细分析一下,出路还是有的,甚至解决温饱.过上有房有车没贷款的生活也是很可能的.首先,在如今这个浮躁的社会,大多数人的心态也是浮躁的,只要你能潜下心来,深

京城码帮——不做单纯的程序员,第二次聚会总结

互联网喧嚣无比,移动互联网更加喧嚣得无处不在.短平快地接受信息是一种病:今天是飞天猪,明天被黑出翔:昨日复盘,今日豹变:上穷碧落,追求体位. 在互联网的浮躁年代,切勿相信互联网思维. 京城码帮--不做单纯的程序员 前段日子,我们终于举办了第二次京城码帮的聚会.本次聚会在帝都的亚杰商会举办,来了差不多50多个小伙伴.当然,很多小伙伴应为时间繁忙的关系都没有空过来,这里我把聚会上的分享内容,在这里想大家简单的介绍一下.希望,大家都能够找到自己的方向,不做单纯的程序员. 为什么创立这么一个组织? 正和

程序员薪资 如何分配,如何增长

自从2011年初,CSDN在网上发起的"2011年软件行业技术人员薪资大调查"以来,获得了广大网友的热烈反响,短短两个月时间内,上万名技术开发者提交了调查数据.尽管这还只是中国百万开发者大军的一小部分,但他们所在的行业几乎涵盖了整个中国软件的产业链,他们的职位几乎代表了一个软件团队体系的每一个层面,而且"一叶知秋",同时,透过这些调查数据和变化,我们或许可以一瞰中国软件开发者的普遍生存状态,甚至可帮助开发者,更准确地定位自己在产业内的坐标. 2011:程序员的日子不

月薪5K左右的程序员该不该去接私活?醍醐灌顶的答案!

提问: "本人是一名二线城市的普通程员,工作五六年了,换过四五次工作,因为各种原因,现在只能算公司的一名主力程序员,没有步入管理层收入,5k多的样子,穷diao丝一个,现在的收入,已经严重不足以应付花钱越来越多的生活.晋升?感觉阻力重重,跳槽?收入差不了多少,做兼职?这个没有做过.不过现在想来,做点私活是增加收入最实际的出路.近尔立之年,我有点迷茫!" 回答1: 程序员做"私活"是最要不得的,因为这对提升自己的价值毫无帮助.仅从技术角度来说,程序的小模块的私活没什么

答读者问(5):有关数学对程序员的作用、研发工作岗位要求和实习对找工作的影响等问题

最近,有很多读者通过微博.微信与本人交流.感觉大家对于学习.对于技术都非常的有热情,让我也学到了很多东西. 我提取了几个大家比较关心的问题予以答复,请有相同疑问的朋友参考一下. 问题1:数学对程序员重要吗? 答复:要回答这个问题,我举一个身边的例子. 我们项目组有两个同时入职的员工(比我晚一年入职),一个是研究生毕业,一个是本科毕业.前者在校成绩很好,几乎每门数学课都考了90分以上:后者在校成绩马马虎虎,但据说写程序很厉害.他们同时进行入职培训,同样有指导老师教,同时转正.大半年之后,我无意间打

程序员实习过程中应该掌握的问问题技巧

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/44344879 http://www.llwjy.com/blogdetail/c28aae9f6e5a8fbf5b37320e255ee462.html 个人博客站已经上线了,网址www.llwjy.com,欢迎大家来吐槽 ------------------------------------------------------------------------------