基于JDK10的Java基础教学项目
掌握Oracle数据库的安装、基本的运行等操作。
要求可以进行简单的查询操作,会使用Connection、DriverManger、PreparedStatement、ResultSet等类。
创建该类,并将该类升级成拥有软编码的技术的工具类。
学会在Oracle中创建基本表,并插入数据。
使用JDBC和DBConnection工具类,完成对user表的CRUD操作。
了解domain和手动的ORM操作的基本原理和使用方式。
在第4个任务过程中,抽象出更多的JDBC操作模板。生成专门的数据库访问工具类:JdbcTemplate.java
1,实现专门的增、删、改方法,其方法原型如下:
public int update(String sql,Object...params);
2,实现专门的查询方法,其方法原型如下:
public <T> T query(String sql,ResultSetHandler rsh,Object...params);
ResultSetHandler接口
public interface ResultSetHandler<T>{
public T handler(ResultSet rs);
}
在Users表中查询姓名中包含某个字的同学或者是姓某个姓的同学。这里需要用到like运算符和%运算符。在PreparedStatement中如何操作?
批量操作API。
新增数据时获取主键。
JDBC时间操作API:JDK8之前;JDK8之后
创建一个表:
--日期时间操作
create table dateTable(
id number(10) primary key,
dateColumn date, --日期
timeColumn date, --时间
timestampColumn timestamp --时间戳
);
create sequence dateTable_id start with 0 minvalue 0 increment by 1;
分别用JDK8之前的代码和JDK8之后的代码实现以上表的插入和获取操作。
利用任务5创建的JDBC操作模板,使用命令行界完成,完成如下任务。
查询功能
分为对车次信息的查询和客户对已订车票信息的查询。要求:
1)对车次的查询,可以按照发车车次进行查询;
2)车次信息包括:车次(可选)、出发地、目的地、发车日期(可选);
3)车次信息只允许用户查询,不允许修改。
售票功能
通过查询系统,客户找到自己满意的车次,再输入个人信息后直接通过系统进行车票的预定。要求:售票记录包括:姓名、车号、发车日期、订票日期、订票数量、总价。
退票
可退票,通过查询系统,客户可以根据自己的名字找到自己的订票信息,通过退票模块退掉已购的车票。
CUI层,与用户进行命令行的交互。 Service层,业务数据处理。 DBOperation层,访问数据库。
查询车次功能的基本流程:进入车次查询,依次输入相应的查询关键字(注意:出发地、目的地、发车日期必须输入;车号、票价可选)。
经典多线程任务
基于synchronized关键字的生产者与消费者问题的任务细分
1,确定参与操作的对象有哪些? 仓库,Storage类,从生产者接收产品,并存放入仓库;同时随时准备给消费者产品。 产品,Product类,操作的对象,本身没有专门的特性。能简单区分就行了。 生产者,Producer类,生产产品,放入仓库,数量可以指定。 消费者,Customer类,从仓库销费产品,数量可以指定。
2,将仓库抽象成list集合,用于存放数据;将生产和消费抽象成两个方法。
public class Storage {
public final int MAX_NUM=100;
LinkedList<Product> list=new LinkedList<>();
public void produce(int number) {}
public void buy(int number) {}
}
3,生产行为详细描述
public void produce(int number) {
synchronized(list) { //给共享数据加锁
while(list.size()+number>=MAX_NUM) { //此处的逻辑是if,但必须使用while。
System.out.println("仓库已满,无法生产产品!");
try {
list.wait(); //条件不被满足,等待。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<number;i++) {
list.add(new Product(i,Thread.currentThread().getName()+"_"+i));
}
System.out.println("已经生产了"+number+"件产品,仓库中共有"+list.size()+"件产品");
list.notifyAll(); //生产结果,唤醒可能的因为仓库存货不足而挂起的线程。
}
}
解析:
使用while代替if语句,是判断wait()方法可否执行的关键。这是因为,当某个线程被唤醒的时候,使其被挂起的条件不一定被满足。需要重复判定。所以要用while循环代替if语句。
4,生产者、消费者为两个继承了Thread类的类,需要实现核心方法public void run()
5,创建Test类,构造多个生产者和消费者从而测试多个生产者和消费者之间的消息通讯机制。
任务细分
1,重构,提取原来仓库类中的核心数据结构和方法原型,抽象到更高层次的接口中。如下:
public interface Storage {
public final int MAX_NUM=100;
LinkedList<Product> list=new LinkedList<>();
public void produce(int number);
public void buy(int number);
}
原来的仓库类,改名为StorageForSynchronized类,实现Storage接口。
加入新的Storage接口的实现类:StorageForReentrantLock类。
2,实现基于重入锁的生产者和消费者问题。这里只关注消费行为的实现。如下:
public void buy(int number) {
lock.lock(); //加锁
try {
while(list.size()-number<=0) {
System.out.println("仓库存货不足,无法销费!");
try {
empty.await(); //挂起
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<number;i++) {
list.remove();
}
System.out.println("已经销费了"+number+"件产品,仓库中还有"+list.size()+"件产品");
full.signal(); //唤醒
}finally {
lock.unlock(); //解锁
}
}
解析:注意特殊的语句结构,在lock.lock()方法之后的代码,必须放在try语句中,而对应的lock.unlock()方法必须放置在finally语句。这并不是为了获取某个异常,只是为了在异常可能发生时,保证一定要解锁。
Java Core、CUI
火车票售票系统,简称TTS。
tts_userInfo表、tts_trainInfo表、tts_orderform表
edu.yuhf.tts.cui 实施CUI界面编码。
edu.yuhf.tts.dao 数据访问模型
edu.yuhf.tts.service 业务模型
创建Dao,利用之前的JdbcTemplate类进行相应的操作。
必查内容:发车地点、到达地点
可选内容:发车时间、车次
操作步骤:
1,从CUI处收集相应的关键字,并且将关键字封装到相关的类中。这里是封装到Train类中。
System.out.println("车次查询,请按照要求输入查询关键字:");
Scanner input=new Scanner(System.in);
System.out.print("出发地:");
String fromAddress=input.nextLine();
System.out.print("目的地:");
String toAddress=input.nextLine();
System.out.print("发车日期:(2018-08-23)");
String date=input.nextLine();
System.out.print("车次");
String trainId=input.nextLine();
//jdk1.8之后的日期处理方式
Train train=null;
if(!Objects.equals(date, "")) {
DateTimeFormatter dft=DateTimeFormatter.ofPattern("yyyy-MM-dd");
train=new Train(0,trainId,fromAddress,toAddress,LocalDate.parse(date,dft),null,null);
}else {
train=new Train(0,trainId,fromAddress,toAddress,null,null,null);
}
List<Train> list=queryService.queryTrain(train);
2,传递给Service组件,进行必要的业务处理。这里没有进行任何业务处理。
return queryDao.queryTrain(train);
3,再传递到Dao组件中,在该组件中根据参数对SQL语句和装入到JdbcTemplate中的入参进行拼装,并执行、返回结果。
public List<Train> queryTrain(Train train){
//拼装SQL
String sql="select * from tts_trainInfo " +
"where fromAddress=? and toaddress=?";
if(train.getTrainId().length()!=0) {
sql+=" and trainId=?";
}
if(null!=train.getDate()) {
sql+=" and startdate=to_date(?,'yyyy-mm-dd')";
}
//组装参数
List<Object> params=new ArrayList<>();
params.add(train.getFromAddress());
params.add(train.getToAddress());
if(train.getTrainId().length()!=0) {
params.add(train.getTrainId());
}
if(null!=train.getDate()) {
DateTimeFormatter dft=DateTimeFormatter.ofPattern("yyyy/MM/dd");
params.add(dft.format(train.getDate()));
}
List<Train> list=JdbcTemplate.query(sql, (rs)->{
List<Train> list0=new ArrayList<>();
try {
while(rs.next()) {
Train train0=new Train(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4),rs.getDate(5).toLocalDate(),rs.getTime(6).toLocalTime(),rs.getBigDecimal(7));
list0.add(train0);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list0;
}, params.toArray());
return list;
}
依然使用车次查询功能,查到具体某个车次,可以录入该车次,从而选择购买该车次的车票。
编程逻辑分析:
购票任务本质上是对订单表进行一个插入操作。而一次订单表插入操作需要同时获得车次表中的信息和用户信息。
车次信息在查询已经获得,需要得到只是用户信息。
用户信息的获取途径:1,当用户没有登录的时候,在购票之前让用户登录;2,用户已经登录了,直接使用相关信息就可以。
略
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。