javase知识点复习:
final关键字:http://t.csdn.cn/bvFgu
接口的定义,特性,实现,继承:http://t.csdn.cn/tbXl3
异常:http://t.csdn.cn/VlS0Z
DAO的概念和角色(设计理念): DAO-称之为数据访问对象,其中的方法都是单精度方法。
单精度指的是这个方法的粒度不能再分了,已经非常细了(因此也称之为细粒度)
fruit --- controller --- Menu.class
fruit --- dao --- FruitDAO.interface
/ impl --- FruitDAOImpl.class
/base --- BaseDAO.class
fruit --- pojo --- Fruit.class
fruit --- view --- Client.class
Menu.class
package com.atguigu.fruit.controller;
import com.atguigu.fruit.dao.FruitDAO;
import com.atguigu.fruit.dao.impl.FruitDAOImpl;
import com.atguigu.fruit.pojo.Fruit;
import java.util.List;
import java.util.Scanner;
//菜单类
public class Menu {
Scanner input = new Scanner(System.in);
FruitDAO fruitDAO = new FruitDAOImpl();
//显示主菜单
public int showMainMenu(){
System.out.println("=================欢迎使用水果库存系统=====================");
System.out.println("1.查看水果库存列表");
System.out.println("2.添加水果库存信息");
System.out.println("3.查看特定水果库存信息");
System.out.println("4.水果下架");
System.out.println("5.退出");
System.out.println("======================================================");
System.out.print("请选择:");
int slt = input.nextInt();
return slt ;
}
//查看水果库存列表
public void showFruitList(){
List<Fruit> fruitList = fruitDAO.getFruitList();
System.out.println("------------------------------------------------------");
System.out.println("编号\t\t名称\t\t单价\t\t库存\t\t备注");
if(fruitList==null || fruitList.size()<=0){
System.out.println("对不起,库存为空!");
}else{
for (int i = 0; i < fruitList.size(); i++) {
Fruit fruit = fruitList.get(i);
System.out.println(fruit);
}
}
System.out.println("------------------------------------------------------");
}
//添加水果库存信息 -- 业务方法:添加库存记录
public void addFruit(){
System.out.print("请输入水果名称:");
String fname = input.next() ;
Fruit fruit = fruitDAO.getFruitByFname(fname);
if(fruit==null){ //说明库存中没有这个名称的水果 - 添加
System.out.print("请输入水果单价:");
int price = input.nextInt() ;
System.out.print("请输入水果库存量:");
int fcount = input.nextInt() ;
System.out.print("请输入水果备注:");
String remark = input.next() ;
//封装成一个新的fruit对象
fruit = new Fruit(0,fname , price , fcount , remark ) ;
//调用DAO的添加方法
fruitDAO.addFruit(fruit);
}else{ // 说明库存中有这个名称的水果 - 修改
System.out.print("请输入追加的库存量:");
int fcount = input.nextInt() ;
fruit.setFcount(fruit.getFcount()+fcount);
//调用DAO的修改方法
fruitDAO.updateFruit(fruit);
}
System.out.println("添加成功!");
}
//查看指定水果库存信息
public void showFruitInfo(){
System.out.print("请输入水果名称:");
String fname = input.next() ;
Fruit fruit = fruitDAO.getFruitByFname(fname);
if(fruit==null){
System.out.println("对不起,没有找到指定的水果库存记录!");
}else{
System.out.println("------------------------------------------------------");
System.out.println("编号\t\t名称\t\t单价\t\t库存\t\t备注");
System.out.println(fruit);
System.out.println("------------------------------------------------------");
}
}
//水果下架
public void delFruit(){
System.out.print("请输入水果名称:");
String fname = input.next() ;
Fruit fruit = fruitDAO.getFruitByFname(fname);
if(fruit==null){
System.out.println("对不起,没有找到需要下架的水果信息!");
}else{
System.out.print("是否确认下架?(Y/N)");
String slt = input.next() ;
if("y".equalsIgnoreCase(slt)){
fruitDAO.delFruit(fname);
System.out.println("下架成功!");
}
}
}
//退出
public boolean exit(){
System.out.print("是否确认退出?(Y/N)");
String slt = input.next();
return !"Y".equalsIgnoreCase(slt);//equalsIgnoreCase('Y') ---> true !取反
}
}
BaseDAO.class
package com.atguigu.fruit.dao.base;
import com.atguigu.fruit.pojo.Fruit;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
//抽象方法不能直接new 必须只能继承 允许有构造方法
public abstract class BaseDAO<T> {
//向上提取通用常量,多个DAO可用
public final String DRIVER = "com.mysql.jdbc.Driver";
public final String URL = "jdbc:mysql://localhost:3306/fruitdb?useUnicode=true&characterEncoding=utf-8&useSSL=false";
public final String USER = "root";
public final String PWD = "123456";
protected Connection conn;//连接对象
protected PreparedStatement psmt;//预处理命令对象
protected ResultSet rs;//返回结果集
//T的class对象
private Class entityClass;
public BaseDAO(){
//getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
//那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
//因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
//所以getGenericSuperclass()获取到的是BaseDAO的Class
Type genericType = getClass().getGenericSuperclass();
//ParameterizedType 参数化类型
Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
//获取到的<T>中的T的真实的类型
Type actualType = actualTypeArguments[0];
try {
entityClass = Class.forName(actualType.getTypeName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
protected Connection getConn() {
try {
//1.加载驱动
Class.forName(DRIVER);
//2.通过驱动管理器获取连接对象
return DriverManager.getConnection(URL, USER, PWD);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return null;
}
//关闭资源
protected void close(ResultSet rs, PreparedStatement psmt, Connection conn) {
try {
if (rs != null) {
rs.close();
}
if (psmt != null) {
psmt.close();
}
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
//给预处理命令对象设置参数
private void setParams(PreparedStatement psmt,Object... params) throws SQLException {
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
psmt.setObject(i + 1, params[i]);
}
}
}
//执行更新,返回影响行数
protected int executeUpdate(String sql , Object... params){
boolean insertFlag = false ;
insertFlag = sql.trim().toUpperCase().startsWith("INSERT");
try {
conn = getConn();
if(insertFlag){
psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
}else {
psmt = conn.prepareStatement(sql);
}
setParams(psmt,params);
int count = psmt.executeUpdate() ;
rs = psmt.getGeneratedKeys();
if(rs.next()){
return ((Long)rs.getLong(1)).intValue();
}
return count ;
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(rs,psmt,conn);
}
return 0;
}
//通过反射技术给obj对象的property属性赋propertyValue值
private void setValue(Object obj , String property , Object propertyValue){
Class clazz = obj.getClass();
try {
//获取property这个字符串对应的属性名 , 比如 "fid" 去找 obj对象中的 fid 属性
Field field = clazz.getDeclaredField(property);
if(field!=null){
field.setAccessible(true);
field.set(obj,propertyValue);
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
//执行复杂查询,返回例如统计结果
protected Object[] executeComplexQuery(String sql , Object... params){
try {
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//通过rs可以获取结果集的元数据
//元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
ResultSetMetaData rsmd = rs.getMetaData();
//获取结果集的列数
int columnCount = rsmd.getColumnCount();
Object[] columnValueArr = new Object[columnCount];
//6.解析rs
if(rs.next()){
for(int i = 0 ; i<columnCount;i++){
Object columnValue = rs.getObject(i+1); //33 苹果 5
columnValueArr[i]=columnValue;
}
return columnValueArr ;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
//执行查询,返回单个实体对象
protected T load(String sql , Object... params){
try {
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//通过rs可以获取结果集的元数据
//元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
ResultSetMetaData rsmd = rs.getMetaData();
//获取结果集的列数
int columnCount = rsmd.getColumnCount();
//6.解析rs
if(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1); //fid fname price
Object columnValue = rs.getObject(i+1); //33 苹果 5
setValue(entity,columnName,columnValue);
}
return entity ;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return null ;
}
//执行查询,返回List
protected List<T> executeQuery(String sql , Object... params){
List<T> list = new ArrayList<>();
try {
conn = getConn() ;
psmt = conn.prepareStatement(sql);
setParams(psmt,params);
rs = psmt.executeQuery();
//通过rs可以获取结果集的元数据
//元数据:描述结果集数据的数据 , 简单讲,就是这个结果集有哪些列,什么类型等等
ResultSetMetaData rsmd = rs.getMetaData();
//获取结果集的列数
int columnCount = rsmd.getColumnCount();
//6.解析rs
while(rs.next()){
T entity = (T)entityClass.newInstance();
for(int i = 0 ; i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1); //fid fname price
Object columnValue = rs.getObject(i+1); //33 苹果 5
setValue(entity,columnName,columnValue);
}
list.add(entity);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} finally {
close(rs,psmt,conn);
}
return list ;
}
}
FruitDAOImpl.class
package com.atguigu.fruit.dao.impl;
import com.atguigu.fruit.dao.FruitDAO;
import com.atguigu.fruit.dao.base.BaseDAO;
import com.atguigu.fruit.pojo.Fruit;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
//接口实现类
public class FruitDAOImpl extends BaseDAO<Fruit> implements FruitDAO {
//查询库存列表
@Override
public List<Fruit> getFruitList() {
return super.executeQuery("select * from t_fruit");
}
//新增库存
@Override
public boolean addFruit(Fruit fruit) {
String sql = "insert into t_fruit values(0,?,?,?,?)";
return super.executeUpdate(sql,fruit.getFname(),fruit.getPrice(),fruit.getFcount(),fruit.getRemark())>0;
}
//修改库存
@Override
public boolean updateFruit(Fruit fruit) {
String sql = "update t_fruit set fcount = ? where fid = ? " ;
return super.executeUpdate(sql,fruit.getFcount(),fruit.getFid())>0;
}
//根据名称查询特定库存
@Override
public Fruit getFruitByFname(String fname) {
return super.load("select * from t_fruit where fname like ? ",fname);
}
//删除特定库存记录
@Override
public boolean delFruit(String fname) {
String sql = "delete from t_fruit where fname like ? " ;
return super.executeUpdate(sql,fname) > 0;
}
}
FruitDAO.interface
package com.atguigu.fruit.dao;
import com.atguigu.fruit.pojo.Fruit;
import java.util.List;
public interface FruitDAO {
//查询库存列表
List<Fruit> getFruitList();
//新增库存
boolean addFruit(Fruit fruit);
//修改库存
boolean updateFruit(Fruit fruit);
//根据名称查询特定库存
Fruit getFruitByFname(String fname);
//删除特定库存记录
boolean delFruit(String fname);
}
Fruit.class
package com.atguigu.fruit.pojo;
public class Fruit {
private Integer fid ;
private String fname ;
private Integer price ;
private Integer fcount ;
private String remark ;
public Fruit(){}
public Fruit(Integer fid, String fname, Integer price, Integer fcount, String remark) {
this.fid = fid;
this.fname = fname;
this.price = price;
this.fcount = fcount;
this.remark = remark;
}
public Integer getFid() {
return fid;
}
public void setFid(Integer fid) {
this.fid = fid;
}
public String getFname() {
return fname;
}
public void setFname(String fname) {
this.fname = fname;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public Integer getFcount() {
return fcount;
}
public void setFcount(Integer fcount) {
this.fcount = fcount;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return fid + "\t\t" + fname + "\t\t" + price +"\t\t" + fcount +"\t\t" + remark ;
}
}
Client.class
package com.atguigu.fruit.view;
import com.atguigu.fruit.controller.Menu;
public class Client {
public static void main(String[] args) {
Menu m = new Menu() ;
boolean flag = true ;
while(flag){
//调用显示主菜单的方法
int slt = m.showMainMenu();
switch(slt){
case 1:
//显示库存列表
m.showFruitList();
break;
case 2:
m.addFruit();
break;
case 3:
m.showFruitInfo();
break;
case 4:
m.delFruit();
break;
case 5:
flag=m.exit();
break;
default:
System.out.println("你不按套路出牌!");
break;
}
}
System.out.println("谢谢使用!再见!");
}
}
导成jar包
Build Artifacts…