您的位置:首页 > 编程语言 > Java开发

JDBC项目——汽车租赁项目业务流程总结

2017-09-22 16:48 274 查看
-一、需求分析

-二、概要设计
-三、详细设计
1.添加车辆

2.实现租车业务

3.实现还车业务

数据层代码

-一、需求分析与数据表设计
需求图:





发现类:
01.moto类(汽车父类):

01.1:bus类(客车类)

01.2:car类(轿车类)

01.3:truck类(卡车类)

02.mototype类(汽车类型类)

03.用户类:软件系统的使用者,登录该系统 管理的 人,比如:管理员、业务经理等。

04.客户类:租车的人。

05.公司类:用于处理租车换车业务流程的人。

-二、概要设计
数据库设计:




-三、详细设计
实现各车的信息录入





一个问题:卡车跟大巴和轿车录入是不一样的,所以在业务层需要判断是什么车型,但这样代码比较臃肿,不利于扩展,不是面向对象编程。

解决:采用面向对象的特点(继承和多态),在moto类建立录入车信息的方法,这样轿车客车大巴继承moto类就可以有自己的录入车信息的方法。

代码演示:
moto类:
public abstract class Moto {
private String mno;              //车牌号
private int seatCount;
private MotoType mtype;

//这里省略get\set方法

public Moto(MotoType mtype,String mno,int seatCount){
this.mno = mno;
this.seatCount = seatCount;
this.mtype = mtype;
}

/**
* 把当前对象存储到数据库中
* @throws Exception
*/
public void saveDB() throws Exception{
CompanyDao dao = new CompanyDao();
try {
dao.addMoto(this);
} catch (Exception e) {
e.printStackTrace();
}finally{
dao.closeConnection();
}
}
}
car类:可以直接使用moto类中的方法
public class Car extends Moto{
public Car(MotoType mtype,String mno) {
super(mtype,mno, 5);
}
}
truck类:重写了moto类的saveDB()方法
public class Truck extends Moto{
private int dun;
private double priceEachDun;            //每吨每天的单价

public int getDun() {
return dun;
}
public double getPriceEachDun() {
return priceEachDun;
}
public void setPriceEachDun(double priceEachDun) {
this.priceEachDun = priceEachDun;
}
public Truck(MotoType mtype, String mno, int seatCount,int dun) {
super(mtype, mno, seatCount);
this.dun = dun;
}
public double getDayMoney() {
return priceEachDun*dun;
}

/**
* 把当前对象存储到数据库中  ----------重写
* @throws Exception
*/
@Override
public void saveDB() throws Exception{
CompanyDao dao = new CompanyDao();
try {
dao.beginTransaction();
dao.addMoto(this);
TruckEntity truckEntity = new TruckEntity();
truckEntity.setMno(this.getMno());
truckEntity.setDun(dun);
truckEntity.setPriceEachDun(priceEachDun);
dao.addTruck(truckEntity);
dao.commit();
} catch (Exception e) {
e.printStackTrace();
dao.rollback();
throw e;
}finally{
dao.closeConnection();
}
}
}
在业务逻辑层方法就很简单了:
private List<Moto> motos;
/**
* 添加汽车
* @param moto
* @throws Exception
*/
public void addMoto(Moto moto) throws Exception{
if(moto != null ){
moto.saveDB();                      //OO多态
motos.add(moto);
}else{
throw new Exception("入参moto错误");
}
}


2.实现租车业务

图解:



注意:由于整个租车过程包含多个表的修改,比如加入两个订单在差不多时间操作同一辆车,肯定会有一个订单有问题,这是就需要保证事务的一致性和完整性。

在业务逻辑层的代码就可以:
public class RentCompany {

private String name;
private List<Moto> motos;               //待租赁的汽车

public String getName() {
return name;
}

public List<Moto> getMotos() {
return motos;
}

public RentCompany(String name){

this.name = name;
motos = new ArrayList<Moto>(50);

}

/**
* 汽车租赁
* @param motos
* @param client
* @param rentinfo
* @return            租赁成功,返回订单号
* @throws Exception
*/
public String rent(List<Moto> motos,TClient client,TRentInfo rentinfo) throws Exception{
String rentno = null;

if(motos != null && client != null && rentinfo!= null){
CompanyDao dao = new CompanyDao();
try {
dao.beginTransaction();                                 //开启事务
//添加客户数据
dao.addTClient(client);
//添加汽车租赁信息
rentno = dao.addRentInfo(rentinfo);
//添加租赁明细
for(Moto moto : motos){
TRentDetail rentDetail = getTRentDetail(rentno,moto);
dao.addRentDetail(rentDetail);
}
dao.commit();                                         //提交事务
} catch (Exception e) {
dao.rollback();                                       //回滚事务
rentno = null;
throw e;
}finally{
dao.closeConnection();
}
}else{
throw new Exception("入参错误,请检查");
}

return rentno;
}

private TRentDetail getTRentDetail(String rentno,Moto moto){
TRentDetail detail = new TRentDetail();

detail.setMno(moto.getMno());
detail.setRentno(rentno);
detail.setDaymoney(moto.getDayMoney());

return detail;
}
}
3.实现还车业务

业务流程:计算租金总额、添加还车信息、给订单写入租金总额、设置车辆信息
/**
* 还车,计算租赁的总价
* @param moto
* @return
*/
public double rentBack(String rentno) throws Exception{
double allMoney = 0;

if(rentno != null){
CompanyDao dao = new CompanyDao();
try {
dao.beginTransaction();
//计算租金总额
allMoney = dao.countAllPayMoney(rentno);
//添加还车信息
dao.addRentBackInfo(rentno);
//给订单写入租金总额
dao.writeAllPayMoney(rentno, allMoney);
//设置车辆的状态
dao.setRentBackMotoState(rentno);
dao.commit();
} catch (Exception e) {
dao.rollback();
throw e;
}finally{
dao.closeConnection();
}
}else{
throw new Exception("入参错误");
}

return allMoney;
}


对应dao层代码:
basedao

public class BaseDao {
protected Connection conn;
public Connection getConn() {
return conn;
}

public void setConn(Connection conn) {
this.conn = conn;
}

public void openConnection() throws ClassNotFoundException,SQLException{

//通过反射技术,对oracel的驱动对象进行类的加载 (其实是在做类型检查)
//在类的加载时,会调用OracleDriver中的静态代码块和静态变量初始化
if(this.conn == null || this.conn.isClosed()){
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@10.0.19.252:1521:orcl","testdb","1111");
}

}

public void beginTransaction() throws Exception{
this.openConnection();
if(this.conn != null){
this.conn.setAutoCommit(false);			             //手动提交模式
}
}

public void commit() throws Exception{
if(this.conn != null){
this.conn.commit();
}
}

public void rollback() throws Exception{
if(this.conn != null){
this.conn.rollback();
}
}

public void closeConnection() {
if(this.conn != null){
try {
this.conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class CompanyDao extends BaseDao{
/**
* 根据订单号,计算需要的租金总额
* @param rentno
* @return
* @throws Exception
*/
public double countAllPayMoney(String rentno) throws Exception{

double allMoney = 0;
double dayMoneys = 0;

String sql = " select  sum(daymoney) dayMoneys from trentinfo r,trentdetail d where r.rentno = d.rentno"
+ " and r.rentno=?";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1,rentno);
ResultSet rs = ps.executeQuery();
while(rs.next()){
dayMoneys = rs.getDouble("dayMoneys");
}
RentinfoDto rentinfo = getRentInfo(rentno);
int days = (int)((new Date()).getTime() - rentinfo.getRentBeginDate().getTime())/(24*3600*1000) + 1;

allMoney = dayMoneys*days;

return allMoney;

}

/**
* 根据订单编号,返回订单信息
* @param rentno
* @return
*/
public RentinfoDto getRentInfo(String rentno) throws Exception{
RentinfoDto rentinfo = null;

String sql = " select r.rentno,r.clno,r.eno,r.operator,r.rentbengindate,r.diyamoney,r.payallmoney, b.backdate  " +
" from trentinfo r left join  trentback b on  r.rentno = b.rentno and r.rentno=?";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1,rentno);
ResultSet rs = ps.executeQuery();
while(rs.next()){
rentinfo = new RentinfoDto();
rentinfo.setBackDate(rs.getDate("backdate"));
rentinfo.setClno(rs.getString("clno"));
rentinfo.setDiyaMoney(rs.getDouble("diyamoney"));
rentinfo.setEno(rs.getString("eno"));
rentinfo.setOperator(rs.getString("operator"));
rentinfo.setPayAllMoney(rs.getDouble("payallmoney"));
rentinfo.setRentBeginDate(rs.getDate("rentbengindate"));
rentinfo.setRentno(rs.getString("rentno"));
}

return rentinfo;

}

/**
* 还车时,给订单写入租金总额
* @param rentno
* @param allMoney
* @throws Exception
*/
public void writeAllPayMoney(String rentno,double allMoney) throws Exception{
String sql = "update trentinfo set payallmoney=? where rentno=?";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setDouble(1, allMoney);
ps.setString(2, rentno);
ps.executeUpdate();
ps.close();
}

/**
* 添加还车信息
* @param rentno
* @throws Exception
*/
public void addRentBackInfo(String rentno) throws Exception{
String sql = "insert into trentback values(?,?)";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, rentno);
ps.setTimestamp(2,new java.sql.Timestamp(new Date().getTime()));
ps.executeUpdate();
ps.close();
}

/**
* 还车时,设置所有订单中的车辆状态为'01'
* @param rentno
* @throws Exception
*/
public void setRentBackMotoState(String rentno) throws Exception{

String sql = "select d.mno  from trentinfo r,trentdetail d where r.rentno = d.rentno and r.rentno=?";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1,rentno);
ResultSet rs = ps.executeQuery();
while(rs.next()){
String mno = rs.getString("mno");
updateRentBackMotoState(mno);
}
rs.close();
ps.close();
}

public void updateRentBackMotoState(String mno) throws Exception{
String sql = "update tmoto set state='01' where mno=?";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, mno);
ps.executeUpdate();
ps.close();
}

/**
* 添加客户数据
* @param client
* @throws Exception
*/
public void addTClient(TClient client) throws Exception{
//查询客户是否存在
boolean bRet = isHaveClient(client.getTel());
if(!bRet){
//添加客户数据
String sql = "insert into tclient values(?,?,?,?,?)";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, client.getTel());
ps.setString(2, client.getCname());
ps.setString(3, client.getCid());
ps.setString(4, client.getTel());
ps.setString(5, client.getAddress());
ps.executeUpdate();
ps.close();
}
}

/**
* 通过手机号,查询指定用户是否存在
* @param tel
* @return
*/
private boolean isHaveClient(String tel) throws Exception{
boolean bRet = false;

String sql = "select * from tclient where tel=?";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, tel);
ResultSet rs = ps.executeQuery();
while(rs.next()){
bRet = true;
}
rs.close();
ps.close();

return bRet;
}

/**
* 汽车租赁
* @param rentinfo
* @return     返回订单号
* @throws Exception
*/
public String addRentInfo(TRentInfo rentinfo) throws Exception{
String sql = "insert into trentinfo values(?,?,?,?,?,?,?)";

this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");
String rentno = "rno-" + sd.format(new Date()) + "-" + (new Date()).getTime();
ps.setString(1, rentno);
ps.setString(2, rentinfo.getClno());
ps.setString(3, rentinfo.getEno());
ps.setString(4, rentinfo.getOperator());
ps.setDate(5, new java.sql.Date(rentinfo.getRentBeginDate().getTime()));
ps.setDouble(6, rentinfo.getDiyaMoney());
ps.setDouble(7, rentinfo.getPayAllMoney());
ps.executeUpdate();
ps.close();

return rentno;
}

/**
* 添加租赁明细
* @param rentDetail
* @throws Exception
*/
public void addRentDetail(TRentDetail rentDetail) throws Exception{
//添加明细
String sql = "insert into TRentDetail values(seq_rentdetail_id.nextval,?,?,?)";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, rentDetail.getRentno());
ps.setString(2, rentDetail.getMno());
ps.setDouble(3,rentDetail.getDaymoney());
ps.executeUpdate();
ps.close();
//修改汽车状态值
updateMotoStateByRent(rentDetail.getMno());
}

/**
* 修改汽车状态值,从未出租改为出租中
* @param moto
* @throws Exception
*/
private void updateMotoStateByRent(String mno) throws Exception{
String sql = "update tmoto set state='02' where mno=? and state='01'";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, mno);
int iRet = ps.executeUpdate();
if(iRet==0){
throw new MotoRentFailException( mno+ ",该车已被别人租用,请重新选择");
}
ps.close();
}

/**
* 添加汽车单表数据
* @param moto
* @throws Exception
*/
public void addMoto(Moto moto) throws Exception{
String sql = "insert into tmoto values(?,?,?,?)";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1,moto.getMno());
ps.setString(2,moto.getMtype().getTno());
ps.setInt(3, moto.getSeatCount());
ps.setString(4, MotoState.PREPARED_RENT);
ps.executeUpdate();
ps.close();
}

/**
* 添加卡车单表数据
* @param truck
* @throws Exception
*/
public void addTruck(TruckEntity truck) throws Exception{
String sql = "insert into truck values(?,?,?)";
this.openConnection();
PreparedStatement ps = this.conn.prepareStatement(sql);
ps.setString(1, truck.getMno());
ps.setInt(2, truck.getDun());
ps.setDouble(3, truck.getPriceEachDun());
ps.executeUpdate();
ps.close();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java