*利用简单的JAVA与数据库写一个属于你自己的账本*
- 效果图
*
- 目标实现
把用户输入的信息录入到数据库中,并且从数据库中取出值来,是不是很简单? - 所需工具
相信大家都有的,eclipse、myeclipse都可以,数据库我用的MySQL - 下面就一步一步的贴代码给大家诺:
首先看看我的项目结构:
这里我新建的是一个java项目,大家可能建的时候没有那个lib文件夹,需要大家手动新建这么一个文件夹用来放置连接数据库的驱动jar包,并且配置好环境即可,相信大家做过web项目应该知道如何操作。
DbUtil类为数据库连接类,比较简单:
package com.VastWu.util;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* 连接数据库工具类
* @author VastWu
*
*/
public class DbUtil {
//私有化conn对象
private static Connection conn=null;
//私有化构造方法
private DbUtil() {}
public static Connection getConn() {
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://127.0.0.1:3306/你的数据库名称?useUnicode=true&characterEncoding=utf-8";
String user="你的数据库用户名";
String password="你的用户密码";
conn=DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
这里使用的是MySQL数据库,其他数据库大同小异
在dao层一共有三个类,分别用来存库、取库、查询总金额
InDao类:
package com.VastWu.Dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.VastWu.util.DbUtil;
/**
* 存入数据库的方法类
* @author VastWu
*
*/
public class InDao {
String sql="insert into init_2018(price,thing,other) values(?,?,?)";
PreparedStatement pstm=null;
public boolean inDatabase(Double price,String thing,String other) {
Connection conn=DbUtil.getConn();
try {
pstm=conn.prepareStatement(sql);
pstm.setDouble(1, price);
pstm.setString(2, thing);
pstm.setString(3, other);
int row=pstm.executeUpdate();
conn.close();
pstm.close();
if(row>0){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
ReadDao类:
package com.VastWu.Dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import javax.swing.JTextArea;
import com.VastWu.util.DbUtil;
/**
* 从数据库读取数据类
* @author VastWu
*
*/
public class ReadDao {
String sql="select * from init_2018";
Statement st=null;
ResultSet rs=null;
public boolean readData(JTextArea jta){
Connection conn=DbUtil.getConn();
try {
st=conn.createStatement();
rs=st.executeQuery(sql);
jta.append("事件"+" "+"金额"+" "+"时间"+" "+"备注"+"\n");
while(rs.next()){
double p=rs.getDouble(3);
String tg=rs.getString(4);
String or=rs.getString(5);
Date d=rs.getDate(2);
jta.append(tg+" "+p+" "+d+" "+or+"\n");
}
rs.close();
st.close();
conn.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
这个类用来把查到的数据放到我们写好的UI界面上
SumQuery类:
package com.VastWu.Dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.VastWu.util.DbUtil;
/**
* 查询数据库金额总量
* @author VastWu
*
*/
public class SumQuery {
public Double queryPriceAll() {
String sql="select sum(price) from init_2018";
Connection conn=DbUtil.getConn();
double p = 0;
try {
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery(sql);
while(rs.next()){
p=rs.getDouble(1);
}
conn.close();
return p;
} catch (Exception e) {
e.printStackTrace();
}
return p;
}
}
用于查询总金额,一定记得写conn.close();不然太多数据库的连接后面开多了连接会报错。
最后是我们的UI界面,也是我们的给用户操作、互动的界面
MainPage类: 主界面,程序入口,有查询总金额,计入数据库的功能!
package com.VastWu.ui;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import com.VastWu.Dao.InDao;
import com.VastWu.Dao.SumQuery;
import com.VastWu.thread.QueryThread;
/**
* 主界面
* @author VastWu
*
*/
public class MainPage {
public static void main(String[] args) {
MainPage mainPage=new MainPage();
mainPage.initUi();
}
public void initUi() {
//实例化indao
final InDao inDao=new InDao();
JFrame jf = new JFrame("book");
jf.setSize(900, 800);
jf.setDefaultCloseOperation(3);
jf.setLayout(null);
jf.setLocationRelativeTo(null);
//标题
JLabel tit=new JLabel();
tit.setBounds(0, 0, 600, 50);
jf.add(tit);
//事件标签
JLabel thingLable=new JLabel("事件");
thingLable.setBounds(100, 100, 30, 50);
jf.add(thingLable);
//事件框
final JTextField thing=new JTextField();
thing.setBounds(130, 100, 200, 50);
jf.add(thing);
//金额标签
JLabel priceLable=new JLabel("金额");
priceLable.setBounds(100, 200, 30, 30);
jf.add(priceLable);
//金额框
final JTextField price=new JTextField();
price.setBounds(130, 200, 200, 30);
jf.add(price);
//备注标签
JLabel otherLable=new JLabel("备注");
otherLable.setBounds(100, 270, 30, 50);
jf.add(otherLable);
//备注框
final JTextField other=new JTextField();
other.setBounds(130, 270, 500, 50);
jf.add(other);
//存储按钮
JButton save=new JButton("记录");
save.setBounds(130, 400, 250, 50);
jf.add(save);
//查看按钮
JButton query=new JButton("查看历史记录");
query.setBounds(400, 400, 250, 50);
jf.add(query);
jf.setVisible(true);
ActionListener al=new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String command=e.getActionCommand();
switch (command) {
case "记录":
if(thing.getText()==null){
JOptionPane.showMessageDialog(null, "事件不能为空!");
break;
}
int n = JOptionPane.showConfirmDialog(null, "您确定储存吗?点击确定将存入", "记录",JOptionPane.YES_NO_OPTION);
if(n==0){
String tg=thing.getText();
String or=other.getText();
Double p = null;
try {
p=Double.parseDouble(price.getText());
} catch (Exception e2) {
JOptionPane.showMessageDialog(null, "金额不能为空或是字符串类型,请输入一个数字并重试");
break;
}
boolean flag=inDao.inDatabase(p, tg, or);
if(flag){
JOptionPane.showMessageDialog(null, "记录成功!");
thing.setText("");
price.setText("");
other.setText("");
}else{
JOptionPane.showMessageDialog(null, "记录失败,请重试");
}
break;
}
break;
case "查看历史记录":
ShowUI showUI=new ShowUI();
showUI.show();
break;
default:
break;
}
}
};
save.addActionListener(al);
query.addActionListener(al);
QueryThread queryThread=new QueryThread(tit);
queryThread.start();
}
}
因为swing代码有点多,所以代码看上去多一点,其实很简单
ShowUI类: 用于展示数据库中的所有消息,这里我直接显示在一个文本域组件中
package com.VastWu.ui;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import com.VastWu.Dao.ReadDao;
/**
* 展示数据类
* @author VastWu
*
*/
public class ShowUI {
/**
* 窗口初始化方法
*/
public void show() {
JFrame jf=new JFrame("数据页");
jf.setSize(900, 800);
jf.setLayout(null);
jf.setLocationRelativeTo(null);
//用于显示数据的文本域
JTextArea jta=new JTextArea();
jta.setBounds(0, 0, 900, 800);
jta.setEditable(false);
jf.add(jta);
jf.setVisible(true);
ReadDao readDao=new ReadDao();
boolean b=readDao.readData(jta);
if(b){
JOptionPane.showMessageDialog(null, "读库成功");
}
}
}
写到这里,账本的基本功能就实现了哦,你可以尝试进行记账了
最后还有一个线程类QueryThread 这个线程类是用来刷新主界面的金额总值实时更新的,如果不写的话,在你存储一个信息的时候,上面的金额不会马上刷新,只有当你再次运行主界面时才会刷新!
package com.VastWu.thread;
import java.awt.Font;
import javax.swing.JLabel;
import com.VastWu.Dao.SumQuery;
/**
* 刷新金额的线程类
* @author VastWu
*
*/
public class QueryThread extends Thread{
JLabel tit;
public QueryThread(JLabel tit){
this.tit=tit;
}
@Override
public void run() {
while(true){
SumQuery sumQuery=new SumQuery();
double pp=sumQuery.queryPriceAll();
tit.setText("自2018-12-18开始已经使用"+pp);
tit.setFont(new Font("楷体",Font.PLAIN,30));
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
当然,还有数据库设计,可以参考一下子:
DROP TABLE IF EXISTS `init_2018`;
CREATE TABLE `init_2018` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`writetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`price` decimal(10,2) DEFAULT NULL,
`thing` varchar(500) DEFAULT NULL,
`other` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of init_2018
-- ----------------------------
INSERT INTO `init_2018` VALUES ('6', '2018-12-22 23:24:05', '3.55', '早餐', '两个包子');
INSERT INTO `init_2018` VALUES ('7', '2018-12-22 23:23:44', '7.40', '中餐', '啵啵鱼(外卖)');
这里需要提一下的是,我的金额用到的数据类型是decimal类型,是为了数值更加精准,如果你使用double的话可能会导致数值不精确,相加出现无限循环的数值!记得小数后面写保留几位小数哦!!!
好了,我们的超简易账本写完了,是不是很简单呢?在我看来还有许多的功能是我们需要去完善的,希望有兴趣的可以改造一番,写成自己有个性的账本!归根结底此项目就是简单的存库取库而已!希望简单的项目对大家有所帮助!!! -------------VastWu
效果图