两小时一个Java小项目—TelBook
今天和大家分享一下最近两天的学习成果。
涉及到Java 通讯录源码 JDBC DAO 配置文件 工具类这些知识。
直接上代码,本人CSDN新人若有疑问可以私聊。lfw615@foxmail.com
1.工程建包范例
公司.公司名.项目简称.*(全小写) | 包名翻译 | 存放的类 |
---|---|---|
com.nyist.telbook.config | 配置 | 存放配置文件 *.properties |
com.nyist.telbook.entity | 实体 | 存放实体类 也就是对象类和接口 |
com.nyist.telbook.servicr | 业务 | 存放业务(实务操作) |
com.nyist.telbook.sql | SQL | 存放.sql 文件 |
com.nyist.telbook.test | 测试 | 存放测试类(一般都是视图界面) |
com.nyist.telbook.util | 使用 | 存放工具类 例如:JDBCUtil.java |
com.nyist.telbook.dao | DAO | 存到直接操控sql语句的DAO方法的类和接口 |
配置文件的创建与书写
为了方便像我一样的小白共同学习,插入下图:
123步骤完成后输入“db.properties”点击“Finish”
在新建的文件左下角选择“source”
在文件的空白处键入连接数据库所需要的必要的文本信息。
2.创建一个工程
2.1 配置文件的书写
db.properties 文件:
//加载数据库所需驱动
jdbc.driver=oracle.jdbc.OracleDriver
//书写URLL
jdbc.url=jdbc:oracle:thin:@localhost:1521:xe
//登陆数据库的用户名
jdbc.user=hr
//登陆用户的密码
jdbc.p=sys
2.2数据库中的表 sql
为了更直接的说明问题,在这里我把本项目中用到的数据库的建表代码也附带上。
//序列
create sequence person_seq;
//建表
create table person(
id number(7) primary key,
name varchar2(15) not null,
mobile varchar2(11) not null unique check( length(mobile)=11 ),
telphone varchar2(13) check( telphone like '___%-_______%'),
email varchar2(30) unique check( email like '_%@%_' ),
city varchar2(20),
birthday date
);
2.3实体类 Entity
首先根据数据库中的表来创建实体类。
我们可以看出有七个变量: 对其进行封装等操作。
package com.baizhi.lfw.entity;
import java.util.Date;
/**
*
* @author LiuFw
* @类的描述:对象类 person对象模板
*/
public class Person {
private int id;
private String name;
private String mobile;
private String telphone;
private String email;
private String city;
private java.util.Date brithday;
//无参有参
public Person(){}
public Person(String name, String mobile, String telphone,
String email, String city, Date brithday) {
super();
this.name = name;
this.mobile = mobile;
this.telphone = telphone;
this.email = email;
this.city = city;
this.brithday = brithday;
}
/*
省略get set方法 注意日期类型的get set方法
*/
public java.util.Date getBrithday() {
return brithday;
}
public void setBrithday(java.util.Date brithday) {
this.brithday = brithday;
}
//toString
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", mobile=" + mobile
+ ", telphone=" + telphone + ", email=" + email + ", city="
+ city + ", brithday=" + brithday + "]";
}
}
2.4工具类书写 Util
2.4.1作用
加载配置文件,创建Connection对象,优化代码,提高复用性。
2.4.2 工具类的书写
//导入要用到的包
import java.io.*;
import java.sql.*;
import java.util.*;
//创建工具类
public class JDBCUtil {
//创建一个Properties对象来向DB(date base)发送sql语句
private static Properties p = new Properties();
//创建线程的存放 为了保障多个类完成一个事务走的是一个线程链
private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
//静态代码块·· 加载配置文件
static{
//创建一个写入流
InputStream is =null;
try {
//加载配置文件(“配置文件路径”)
is = JDBCUtil.class.getResourceAsStream("/com/baizhi/lfw/config/db.properties");
//处理配置文件(可以让配置文件跟随工具类一同进行类加载)
p.load(is);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
//关闭流释放资源
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//获取 线程绑定的 conn
public static Connection getConn(){
//首先Conn对象访问线程的存放 若无则创建conn对象
Connection conn = tl.get();
if(conn == null){
try {
//类加载 (加载链接数据库的驱动)
Class.forName(p.getProperty("jdbc.driver"));
//填充相关数据信息
conn = DriverManager.getConnection(p.getProperty("jdbc.url"),p.getProperty("jdbc.user"),p.getProperty("jdbc.pass"));
//把创建好的Connection对象存在threadlocal中
tl.set(conn);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return conn;
}
//释放资源
public static void close(Connection conn,Statement stmt,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
//这里要注意:关闭conn时 同时移除线程
tl.remove();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
工具类稍微难理解一些,初步阶段做到会用,懂原理就好。
2.5DAO java执行sql语句
DAO :Data Access Object
2.5.1 作用
书写完工具类后我们就可以通过conn对象链接数据库。
接下来我们开始创建DAO
为了防止以后系统升级带来的不便,在这里建议大家使用DAO操作的时候先创建接口类,定义相应的DB中的数据表需要实现的操作,然后用实现类去实现各个方法。
2.5.2 IPersonDAO.java
package com.baizhi.lfw.dao;
import java.util.List;
public interface IPersonDAO {
//增
public void addPerson(Person p);
//删
public void deletePerson(int id);
//改
public void updatePerson(Person p);
//查一个
public Person selectPerson(int id);
//查所有
public List<Person> selectAll();
//手机号模糊查
public List<Person> selectCell(String cell);
//名字模糊查
public List<Person> selectName(String name);
}
2.5.3 PersonDAO.java
package com.baizhi.lfw.dao;
import java.sql.*;
import java.util.*;
import com.baizhi.lfw.entity.Person;
import com.baizhi.lfw.util.JDBCUtil;
public class PersonDAO implements IPersonDAO{
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
@Override
// 添加联系人信息
public void addPerson(Person p) {
// TODO Auto-generated method stub
//书写sql
String sql = "insert into person values(person_seq.nextval,?,?,?,?,?,?)";
try {
//获取连接
conn = JDBCUtil.getConn();
//把sql发送给DB
pstmt = conn.prepareStatement(sql);
//给sql中的6个问号赋值
pstmt.setString(1, p.getName());
pstmt.setString(2, p.getMobile());
pstmt.setString(3, p.getTelphone());
pstmt.setString(4, p.getEmail());
pstmt.setString(5, p.getCity());
pstmt.setDate(6, new Date(p.getBrithday().getTime()));
//执行sql语句 并获得返回值
int i = pstmt.executeUpdate();
if(i != 0 ){
System.out.println("添加成功!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//释放资源
JDBCUtil.close(null, pstmt, rs);
}
}
@Override
// 删除联系人
public void deletePerson(int id) {
// TODO Auto-generated method stub
String sql = "delete from person where id = ?";
try {
conn = JDBCUtil.getConn();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
int i = pstmt.executeUpdate();
if(i != 0){
System.out.println("删除id:"+id+"成功!!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(null, pstmt, rs);
}
}
@Override
// 修改联系人
public void updatePerson(Person p) {
// TODO Auto-generated method stub
String sql = "update person set name = ?,mobile = ?, telphone = ?, email = ?, city = ?, birthday = ? where id = ?";
try {
conn = JDBCUtil.getConn();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, p.getName());
pstmt.setString(2, p.getMobile());
pstmt.setString(3, p.getTelphone());
pstmt.setString(4, p.getEmail());
pstmt.setString(5, p.getCity());
pstmt.setDate(6, new Date(p.getBrithday().getTime()));
pstmt.setInt(7, p.getId());
System.out.println(p);
int i = pstmt.executeUpdate();
if(i != 0){
System.out.println("修改成功!!");
}else{
System.out.println("修改失败!!");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(null, pstmt, rs);
}
}
@Override
//通过id查询一个联系人
public Person selectPerson(int id) {
// TODO Auto-generated method stub
String sql = "select * from person where id = ?";
try {
conn = JDBCUtil.getConn();
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
rs = pstmt.executeQuery();
Person per = null;
if(rs.next()){
per = new Person();
per.setId(rs.getInt(1));
per.setName(rs.getString(2));
per.setMobile(rs.getString(3));
per.setTelphone(rs.getString(4));
per.setEmail(rs.getString(5));
per.setCity(rs.getString(6));
per.setBrithday(rs.getDate(7));
}
return per;
} catch (Exception e) {
System.out.println("查询出错!!");
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(null, pstmt, rs);
}
return null;
}
@Override
//显示所有联系人
@Test
public List<Person> selectAll() {
// TODO Auto-generated method stub
id,name,mobile,telphone,email,city,birthday from person";
String sql = "select * from person";
List<Person> list = new ArrayList<Person>();
try {
conn = JDBCUtil.getConn();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()){
Person per = new Person();
per.setId(rs.getInt(1));
per.setName(rs.getString(2));
per.setMobile(rs.getString(3));
per.setTelphone(rs.getString(4));
per.setEmail(rs.getString(5));
per.setCity(rs.getString(6));
per.setBrithday(rs.getDate(7));
System.out.println("读取:"+per);
list.add(per);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(null, pstmt, rs);
}
return null;
}
@Override
//电话号码模糊查询联系人
public List<Person> selectCell(String cell) {
// TODO Auto-generated method stub
String sql = "select * from person where mobile like ?";
try {
conn = JDBCUtil.getConn();
pstmt = conn.prepareStatement(sql);
String cells = "%"+cell+"%";
pstmt.setString(1, cells);
rs = pstmt.executeQuery();
List<Person> list = new ArrayList<Person>();
while(rs.next()){
Person per = new Person();
per.setId(rs.getInt(1));
per.setName(rs.getString(2));
per.setMobile(rs.getString(3));
per.setTelphone(rs.getString(4));
per.setEmail(rs.getString(5));
per.setCity(rs.getString(6));
per.setBrithday(rs.getDate(7));
System.out.println("读取:"+per);
list.add(per);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(null, pstmt, rs);
}
return null;
}
@Override
//名字模糊查找联系人
public List<Person> selectName(String name) {
// TODO Auto-generated method stub
String sql = "select * from person where name like ?";
try {
conn = JDBCUtil.getConn();
pstmt = conn.prepareStatement(sql);
String cells = "%"+name+"%";
pstmt.setString(1, cells);
rs = pstmt.executeQuery();
List<Person> list = new ArrayList<Person>();
while(rs.next()){
Person per = new Person();
per.setId(rs.getInt(1));
per.setName(rs.getString(2));
per.setMobile(rs.getString(3));
per.setTelphone(rs.getString(4));
per.setEmail(rs.getString(5));
per.setCity(rs.getString(6));
per.setBrithday(rs.getDate(7));
System.out.println("读取:"+per);
list.add(per);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
JDBCUtil.close(null, pstmt, rs);
}
return null;
}
}
程序写到这里,我们可以运用”@Test”方法对基本的功能进行测试。
如果不会使用”@Test”方法的战友们请翻阅我的其他文章,会有相关的介绍。
2.6 业务层 Service
写到这里我们的项目即将大功告成。
业务类是为了实现不同业务,可以同时操作多个DAO方法,完成相关的操作
2.6.1TelBookService.java
该层的类中方法实际上已经是面向用户的需求而定制的。
同DAO 我们先创建一个接口。
package com.baizhi.lfw.service;
import java.util.List;
import com.baizhi.lfw.entity.*;;
/**
*
* @author LiuFw
* @类的描述: 业务类 实现不同业务 可以同时操作 多个DAO方法
*/
public interface TelbookService {
//添加联系人需要使用的业务方法
public void regist(Person person) ;
//修改联系人时需要调用的业务方法
public void changePersonMessage(Person person);
//通过Id查找联系人
public Person getOnePerson(Integer id) ;
//获得所有的联系人的业务方法
public List<Person> getAllPersons() ;
//根据联系人姓名查找联系人的业务方法
public List<Person> getPersonByName(String name);
//根据手机号码查询相关的联系人的业务方法
public List<Person> getPersonByMobile(String mobile);
//删除联系人时需要调用的业务方法
public void dropPerson(Integer id);
}
2.6.2 TelBookServiceImpl.java
实现类中实现各个方法的步骤是:
1.获取conn 链接到数据库,同时也是为了保证在同一线程中
2.关闭自动提交,手动提交事务,在操作多个DAO时候若有异常可数据回滚
3.执行相应的DAO操作,即调用操作sql语句的类方法
4.提交事务
5.若有返回值,return *;
package com.baizhi.lfw.service;
import java.sql.*;
import java.util.*;
import java.security.Provider.Service;
import com.baizhi.lfw.dao.*;
import com.baizhi.lfw.entity.Person;
import com.baizhi.lfw.util.JDBCUtil;
public class TelbookServiceImpl implements TelbookService{
private static Connection conn = null;
private static IPersonDAO dao = new PersonDAO();
private static List<Person> list = new ArrayList<Person>();
@Override
//添加联系人
public void regist(Person person) {
try {
//获取同一线程的conn
conn = JDBCUtil.getConn();
//关闭自动提交
conn.setAutoCommit(false);
//DAO操作
dao.addPerson(person);
//提交
conn.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
try {conn.rollback();
} catch (Exception e1) {e1.printStackTrace();}
e.printStackTrace();
//结果回滚
}finally{
JDBCUtil.close(conn, null, null);
}
}
@Override
//修改联系人
public void changePersonMessage(Person person) {
// TODO Auto-generated method stub
try {
conn = JDBCUtil.getConn();
conn.setAutoCommit(false);
dao.updatePerson(person);
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO: handle exception
}finally{
JDBCUtil.close(conn, null, null);
}
}
@Override
//通过id查找
public Person getOnePerson(Integer id) {
// TODO Auto-generated method stub
try {
conn = JDBCUtil.getConn();
conn.setAutoCommit(false);
//操作
Person p = dao.selectPerson(id);
conn.commit();
return p;
} catch (SQLException e) {
// TODO Auto-generated catch block
try {System.out.println("查询失败!!");
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
JDBCUtil.close(conn, null, null);
}
return null;
}
@Override
//获取所有的联系人的业务
public List<Person> getAllPersons() {
// TODO Auto-generated method stub
try {
conn = JDBCUtil.getConn();
conn.setAutoCommit(false);
list = dao.selectAll();
for (Person p : list) {
System.out.println("111111····测试:"+p);
}
conn.commit();
return list;
} catch (Exception e) {
try {conn.rollback();} catch (SQLException e1) {e1.printStackTrace();
}
e.printStackTrace();
}finally{
JDBCUtil.close(conn, null, null);
}
return null;
}
@Override
//通过名字 模糊查询
public List<Person> getPersonByName(String name) {
// TODO Auto-generated method stub
try {
conn = JDBCUtil.getConn();
conn.setAutoCommit(false);
list = dao.selectName(name);
conn.commit();
return list;
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
//通过手机号模糊查询
public List<Person> getPersonByMobile(String mobile) {
// TODO Auto-generated method stub
try {
conn = JDBCUtil.getConn();
conn.setAutoCommit(false);
list = dao.selectCell(mobile);
conn.commit();
return list;
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
//通过id删除联系人
public void dropPerson(Integer id) {
// TODO Auto-generated method stub
try {
conn = JDBCUtil.getConn();
conn.setAutoCommit(false);
dao.deletePerson(id);
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}finally{
JDBCUtil.close(conn, null, null);
}
}
}
2.7 测试类
在这里,为了能够简单有效的限额出整体的操作数据,使用了测试类。
测试类通过业务层来间接操作DAO方法。
package com.baizhi.lfw.test;
import java.text.*;
import java.util.*;
import org.junit.Test;
import com.baizhi.lfw.entity.Person;
import com.baizhi.lfw.service.TelbookService;
import com.baizhi.lfw.service.TelbookServiceImpl;
class Main{
public static void main(String[] args) {
TelBookView t = new TelBookView();
t.showMainView();
}
}
public class TelBookView {
private Scanner sc = new Scanner(System.in);
private TelbookService service = new TelbookServiceImpl();
//菜单
@Test
public void showMainView(){
while(true){
System.out.println("***************欢迎访问通讯录***************");
System.out.println("1.显示所有联系人 2.按姓名查找联系人 3.按号码查找联系人");
System.out.println("4.添加联系人 5.删除联系人 6.修改联系人信息");
System.out.println("7.退出");
System.out.println("请选择操作:");
int selected = sc.nextInt();
//调用选择方法
requestDispatcher(selected);
}
}
//选择方法
public void requestDispatcher(int selected) {
try {
switch(selected){
case 1:{ showAllPerson(); break;}
case 2:{ showPersonsByName(); break;}
case 3:{ showPersonsByMobil();break;}
case 4:{ addPerson(); break;}
case 5:{ dropPerson(); break;}
case 6:{changePersonMessage(); break;}
case 7:{
System.out.println("--------------------谢谢使用,再见------------------");
System.exit(0);
break;
}
default:{
throw new Exception("输入错误,请考虑重新选择!");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//用户选择功能1,显示所有联系人
public void showAllPerson() {
//调用service的查询方法,查询所有的联系人
List<Person> list=service.getAllPersons();
//调用本类的方法显示联系人信息
showPersons(list);
}
//只供本类其他方法是用,用表格形式显示list集合里的联系人信息
private void showPersons(List<Person> list) {
System.out.println("Id\tName\t Mobile \t Telphone \t Email \t City \t Birthday ");
for(Person p:list){
System.out.println(p.getId()+"\t"+p.getName()+"\t"+p.getMobile()+"\t"+p.getTelphone()+"\t"+p.getEmail()+"\t"+p.getCity()+"\t"+p.getBrithday());
}
}
//用户选择功能2,按姓名查询联系人,允许模糊查询
public void showPersonsByName() {
System.out.println("请输入需要查询的联系人姓名(可以模糊查询):");
String name=sc.next();
//调用service方法查询相关数据
List<Person> list=service.getPersonByName(name);
//调用本类的方法显示联系人信息
showPersons(list);
}
//用户选择功能3,按手机查询联系人,允许模糊查询
public void showPersonsByMobil() {
System.out.println("请输入需要查询的联系人手机号码(可以模糊查询):");
String mobile=sc.next();
//调用service方法查询相关数据
List<Person> list=service.getPersonByMobile(mobile);
//调用本类的方法显示联系人信息
showPersons(list);
}
//用户选择功能4,添加联系人,允许用户名重复
@Test
public void addPerson() {
Person p = null;
try {
System.out.println("请输入联系人姓名:");
String name=sc.next();
System.out.println("请输入联系人手机号码:");
String mobile=sc.next();
System.out.println("请输入联系人座机号码:");
String telphone=sc.next();
System.out.println("请输入联系人email:");
String email=sc.next();
System.out.println("请输入联系人地址:");
String city=sc.next();
System.out.println("请输入生日(1980-6-23):");
String date=sc.next();
System.out.println("输入的日期是:"+date);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date utilDate = sdf.parse(date);
p = new Person(name,mobile,telphone,email,city,utilDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//调用service的regist()方法
service.regist(p);
//System.out.println("添加联系人成功!!!!");
}
//用户选择功能5,删除联系人,需要输入联系人的id
public void dropPerson() {
System.out.println("请输入需要删除的联系人的id:");
int id=sc.nextInt();
//调用service的方法删除联系人
service.dropPerson(id);
System.out.println("-----------删除成功----------");
}
//用户选择功能6
//首先需要用户输入被修改用户的id,将该用户信息显示在屏幕上.
//目前修改联系人只能全表修改,必须给定除id以外的所有值
public void changePersonMessage() {
System.out.println("请输入需要修改的联系人的编号(id): ");
int id=sc.nextInt();
//调用service的根据id查询联系人方法,获得联系人具体信息并且显示
Person p=service.getOnePerson(id);
try {
System.out.println("您要修改的联系人具体信息如下:");
System.out.println("Id\tName\t Mobile \t Telphone \t Email \t City \t Birthday ");
System.out.println(p.getId()+"\t"+p.getName()+"\t"+p.getMobile()+"\t"+p.getTelphone()+"\t"+p.getEmail()+"\t"+p.getCity()+"\t"+p.getBrithday());
//用户输入修改信息
System.out.println("请输入联系人姓名:");
String name=sc.next();
System.out.println("请输入联系人手机号码:");
String mobile=sc.next();
System.out.println("请输入联系人座机号码:");
String telphone=sc.next();
System.out.println("请输入联系人email:");
String email=sc.next();
System.out.println("请输入联系人地址:");
String city=sc.next();
System.out.println("请输入生日(1980-6-23):");
String date=sc.next();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date utilDate;
utilDate = sdf.parse(date);
Person per = new Person();
per = new Person(name,mobile,telphone,email,city,utilDate);
per.setId(id);
//调用service里的修改联系人的方法
service.changePersonMessage(per);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在书写完业务类之后我们一定要仔细品味类与类之间的关系。
今天的分享到此为止,如有意见或者建议欢迎大家给我提出。谢谢