一 前情提要
话说当时敌方使者与尚未恢复的灵战斗,灵无可奈何之下传授主角晋升之道,奈何时间有限,排行榜功能尚未做出,只是稍微增强灵的实力,
不至于落败那么快,正当危急时刻,主角忽心有所悟。感悟大道传承,得知唯有再次进化,才有一丝希望打败使者
二 超进化:三层架构之DVD管理系统
2.1 准备
唯有踏入数据库之境,方算起步之境。
古有一气化三清,事不过三之例子,今有三层架构之法。
何为三层架构?其一为DAL,又为数据访问层,主要负责表中数据的CRUD操作。其二为BLL,又为业务逻辑层, 主要负责具体的业务功能实现
其三为UI层,又为用户界面层,接收用户的输入 对用户的输入进行合法校验 调用业务逻辑层的代码进行功能的处理。
开发步骤:实际的操作中每一层就是一个包package
1.依次创建三个包 按照规范分别命名为:ui service dao
2.编写dao层的代码:要求一个类负责数据库中一张表的CRUD 一个表对应一个数据 访问类 类名为:表名+Dao 注意:在dao层的数据访问代码中不要进行异常的处理 直接往上抛
3.编写service层的代码:要求一个类负责项目中一个模块的业务功能 目前来说一张 表对应一个功能模块 类名:表名 + Service
4.编写UI层的代码
注意:为了降低耦合性,最好用接口连接
PreparedStatement的使用
PreparedStatement是Statement的一个子接口,称为预编译的 statement对象
和statement使用上的区别:
- 即将执行的sql语句中的参数不能采用字符串拼接的方式,而是直接使用?进行参 数值的占位
- 在获取PreparedStatement对象时就要求指定执行的具体sql,Statement对象实 在最终调用execute方法的时候才传入执行的sql语句
总结:
PreparedStatement接口相比于Statement来说具有两个优势:
- 可以有效的防止SQL注入攻击
- 对sql参数的处理方式更加的方便(避免了字符串的拼接)
- 因为PreparedStatement是一个预编译的sql,在数据库服务器上只要执行一次 后就会被缓存下来,后期再执行效率非常高 结论:实际开发中一定是使用PreparedStatemen
JDBC事务处理
通俗一点来说:就是没有达到预定的效果而拒绝执行操作,比如转钱,人转了钱,但是别人没收到,那么这个转钱的操作不会执行
步骤:
- //1.关闭事务的自动提交 conn.setAutoCommit(false);
- //提交事务 conn.commit();
- //回滚事务 conn.rollback();//在捕捉异常中写
JDBCUtils工具类的编写
里面都是固定写法,而容易变的都写在一个配置文件中,默认为.properties,后期改变比较容易
将数据库连接相关的四项信息外置到配置文件中,操作步骤:
1.在当前项目的根目录下创建一个文件夹,名称必须为 resources(程序员和IDEA 工具之间做的一个约定 ,约定优先于配置)
2.将resources目录标记为资源目录
3.在资源目录中创建一个db.properties文件(key=value ) 并编写数据库连接相关 的配置信息
数据库
数据库文件跟着一起上传了,我当时从高版本换成低版本出了不少问题,如果出现了问题,最好自己建一个
Date工具类
数据库存储的数据类型为java.sql.Date,java应用层类型为java.util.Date,需要进行转换
java.sql.Date
-
java语言常规应用层面的日期类型,可通过字符串创建时间对象
-
无法直接通过JDBC插入到数据库
java.util.Date
-
不能通过字符串创建对应的时间对象,只能通过毫秒值创建对象
-
可以通过JDBC插入到数据库
SimpleDateFormat:格式化(日期到文本)parse:把一个字符串转为util.Date的类型format:把日期转为字符串
sql.Date不支持字符串转换,只支持毫秒值转换
通过util.Date拿到日期的毫秒值,转换为sql.Date
String str="2021-12-26";
System.out.println("将字符串转为util.Date");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("parse方法转换");
java.util.Date date=sdf.parse(str);
System.out.println(date);
String dates=sdf.format(date);
System.out.println("转换为字符串"+dates);
java.sql.Date sqlDate=new java.sql.Date(date.getTime());
System.out.println("通过util.Date拿到日期的毫秒值,转换为sql.Date"+sqlDate);
java.sql.Date sqlDate=new java.sql.Date(date.getTime())
三 功能模块
3.1 新增
//ui层
System.out.println("输入碟片名");
String name=sc.next();
System.out.println("输入碟片租金");
double price=sc.nextDouble();
Dvd d=new Dvd(null, name, price,null,null,null);
int i = service.insertDvd(d);
if(i==0){
System.out.println("添加失败");
}else{
System.out.println("添加成功");
}
//service层
@Override
public int insertDvd(Dvd d) {
return dao.insertDvd(d);
}
//dao层
@Override
public Integer insertDvd(Dvd d) {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
int i=0;
try {
conn = JDBCutil.getConnection();
String sql = "insert into dvd values (null,?,?,null,0,0)";
pst = conn.prepareStatement(sql);
pst.setString(1, d.getName());
pst.setDouble(2, d.getPrice());
i=pst.executeUpdate();
}catch(Exception e){
System.out.println("DvdDaoImpl error");
e.printStackTrace();
}
finally {
JDBCutil.release(conn,pst,rs);
}
return i;
3.2 显示
//ui
//1 显示所有信息方法
public void showAllDvd() throws Exception{
List<Dvd> list=service.getAllDvd();
showDvds(list);
}
//显示信息
private void showDvds(List<Dvd> list) throws Exception{
for (Dvd d:list
) {
System.out.println(d);
}
}
//service
@Override
public List<Dvd> getAllDvd() {
List<Dvd> list = new ArrayList<>();
PreparedStatement pst = null;
ResultSet rs = null;
Connection conn = null;
try {
DvdDao dao = new DvdDaoImpl();
conn = JDBCutil.getConnection();
conn.setAutoCommit(false);
list = dao.queryAllDvds();
System.out.println(conn);
conn.commit();
return list;
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} finally {
JDBCutil.release(conn, pst, rs);
}
return list;
//dao
@Override
public List<Dvd> queryAllDvds() {
List<Dvd> list=new ArrayList<>();
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
conn = JDBCutil.getConnection();
String sql = "select * from dvd";
pst = conn.prepareStatement(sql);
rs=pst.executeQuery();
while(rs.next()){
Dvd d=new Dvd();
d.setId(rs.getInt("id"));
d.setName(rs.getString("name"));
d.setPrice(rs.getDouble("price"));
d.setJc_date(rs.getDate("jc_date"));
d.setStatus(rs.getInt("status"));
d.setCount(rs.getInt("count"));
list.add(d);
}
}catch (Exception e){
System.out.println("selectall error");
e.printStackTrace();
}
finally {
JDBCutil.release(conn,pst,rs);
}
return list;
}
3.3 删除
//ui
//5 删除信息
private void deleteDvd() {
System.out.println("输入碟片名称");
String name=sc.next();
service.deleteDvdByName(name);
System.out.println("删除成功");
}
//service
@Override
public void deleteDvdByName(String name) {
dao.deleteDvd(name);
}
//dao
@Override
public void deleteDvd(String name) {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
conn = JDBCutil.getConnection();
String sql = "delete from dvd where name=? ";
pst = conn.prepareStatement(sql);
pst.setString(1,name);
pst.executeUpdate();
}catch (Exception e){
System.out.println("delete error");
e.printStackTrace();
}
finally {
JDBCutil.release(conn,pst,rs);
}
}
3.4 修改
//ui
//6 修改信息
private void updateDvd() {
System.out.println("输入修改碟片的名称");
String name=sc.next();
Dvd dvdByName = service.findDvdByName(name);
if(dvdByName ==null){
System.out.println("没有此碟片");
return;
}
System.out.println("输入想修改的租金");
double price=sc.nextDouble();
int row;
row=service.updateDvd(name,price);
if(row !=0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
//service
/**
* 根据名字修改单价
* @param
*/
@Override
public int updateDvd(String name,double price) {
Dvd d=dao.queryDvdByName(name);
d.setPrice(price);
return dao.updateDvd(d);
}
/**
* 根据名字修改出租日期
*/
@Override
public int updateDvdByname(String name, String jc_date){
Dvd d=dao.queryDvdByName(name);
int i;
if(d.getStatus()!=0){
return 0;
}else {
d.setStatus(1);
d.setJc_date(Dateutil.strToUtil(jc_date));
i=dao.updateDvd(d);
return i;
}
}
//dao
@Override
public int updateDvd(Dvd d) {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
try {
conn = JDBCutil.getConnection();
String sql = "update dvd set id=?,price=?,jc_date=?,status=?, count =? where name=?";
pst = conn.prepareStatement(sql);
pst.setInt(1,d.getId());
pst.setDouble(2, d.getPrice());
pst.setDate(3,Dateutil.utildateTosqlDate(d.getJc_date()));
pst.setInt(4, d.getStatus());
pst.setInt(5,d.getCount());
pst.setString(6,d.getName());
int result=pst.executeUpdate();
return result;
}catch (Exception e){
System.out.println("updateDvd error");
e.printStackTrace();
}
finally {
JDBCutil.release(conn,pst,rs);
}
return 0;
}
3.5 出租
//ui
private void updateDvdByname() {
System.out.println("输入出租碟片的名称");
String name=sc.next();
Dvd dvdByName = service.findDvdByName(name);
System.out.println(dvdByName);
if(dvdByName.getName() ==null && dvdByName.getStatus()!=0){
System.out.println("没有此碟片或者碟片已出租");
}else {
System.out.println("输入出租日期(格式为 年-月-日)");
String jc_date=sc.next();
int row;
row=service.updateDvdByname(name,jc_date);
if(row !=0){
System.out.println("出租成功");
}else {
System.out.println("请检查格式是否有问题");
}
}
}
//service
@Override
public int updateDvdByname(String name, String jc_date){
Dvd d=dao.queryDvdByName(name);
int i;
if(d.getStatus()!=0){
return 0;
}else {
d.setStatus(1);
d.setJc_date(Dateutil.strToUtil(jc_date));
i=dao.updateDvd(d);
return i;
}
}
3.6 归还
//ui
//归还碟片
private void updateDvdDateByname() throws InterruptedException {
System.out.println("输入归还碟片的名称");
String name=sc.next();
Dvd dvdByName = service.findDvdByName(name);
System.out.println(dvdByName);
if(dvdByName.getName() ==null && dvdByName.getStatus()!=0){
System.out.println("没有此碟片");
}else {
System.out.println("输入归还日期(格式为 年-月-日)");
String b_date=sc.next();
long l = service.updateDvdDateByname(name, b_date);
int day=(int)(l/1000/60/60/24);
if(l !=0){
System.out.println("归还成功");
System.out.println("共租了"+day+"天,日租金为"+dvdByName.getPrice()+"元");
System.out.println("请付款:");
sleep(3000);
System.out.println("恭喜你中大奖,今天免单");
}else {
System.out.println("请检查格式是否有问题");
}
}
}
//service
@Override
public long updateDvdDateByname(String name, String b_date) {
Dvd d=dao.queryDvdByName(name);
if(d.getStatus()==0){
return 0;
}else {
d.setStatus(0);
d.setCount(d.getCount() + 1);
long l = Dateutil.strToUtil(b_date).getTime() - d.getJc_date().getTime();
d.setJc_date(null);
dao.updateDvd(d);
return l;
}
}
3.7 排行榜
//ui
private void leaderBoard() {
List<Dvd> allDvd = service.getAllDvd();
allDvd.stream().sorted((s1,s2)-> s2.getCount()-s1.getCount()).forEach(System.out::println);
}
四 图片
六 总结
天地传承果然不同凡响,这似乎还蕴藏了一些其他东西,难道是.....优化武器?
那么下一步便是优化了,主角忽而喃喃自语,忽而仰天大笑。“别笑了,你不知道你那个系统有很多bug吗?还不赶紧上传文件,让人帮忙优化”,远处传来灵的独特中又带着空灵的女声。
“他们已经进行到这一步了吗?看来还要多给一点时间啊”,远处一道影子看着地面上的战斗以及旁边的主角低声道