Day36 JDBC 2 PrepareStatement和JDBC的封装以及MVC分层模式+员工管理系统的实现

PreparedStatement和Statement的区别:

1.PrepareStatement接口是Statement接口的子接口,他继承了Statement接口的所有功能。它主要是拿来解决我们使用Statement对象多次执行同一个SQL语句的效率问题的。
2.ParperStatement接口的机制是在数据库支持预编译的情况下预先将SQL语句编译,当多次执行这条SQL语句时,可以直接执行编译好的SQL语句,这样就大大提高了程序的灵活性和执行效率。
3.代码书写方式不同。
stmt = conn.createStatement();
pstmt = conn.prepareStatement(sql);
4.PreparedStatement比Statement安全,避免了SQL注入的风险。

PreparedStatement对象完成查询

特点:
        防止sql注入
        提升sql语句的执行效率(当批量执行同一类型的sql语句时)
    使用:
        创建集合或者实体类对象(可选-查询)  
        加载驱动
        获取连接对象
        设置手动数据提交(可选--增删改)
        创建sql命令
        获取sql命令对象
        给占位符赋值
        执行sql语句
        遍历执行结果(可选--查询)
        提交数据(可选--增删改)
        回滚数据(可选-增删改)
        关闭资源
        返回结果

代码示例实现:

public class UserDaoImpl {  
    //查询用户信息
    public User getUserInfo(String uname,String upwd) throws ClassNotFoundException, SQLException{
        //声明User对象
        User u=null;
        //加载驱动
        Class.forName("oracle.jdbc.driver.OracleDriver");
        //创建连接对象
        Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "oracle");
        //创建sql命令
        String sql="select * from t_user where uname=? and upwd=?";
        //创建sql命令对象
        PreparedStatement ps=conn.prepareStatement(sql);
        //给占位符赋值(占位符从左到右角标从1开始)
        ps.setString(1, uname);
        ps.setString(2, upwd);

        //执行sql命令
        ResultSet rs=ps.executeQuery();
        //遍历查询结果
        while(rs.next()){
            u=new User();
            u.setUnum(rs.getInt("unum"));
            u.setUname(rs.getString("uname"));
            u.setUpwd(rs.getString("upwd"));
            return u;
        }
        //关闭资源
        rs.close();
        ps.close();
        conn.close();
        //返回执行结果
        return u;
    }
    //新增--preparedStatement
        public int insUser2() throws ClassNotFoundException, SQLException{
            //加载驱动
            Class.forName("oracle.jdbc.driver.OracleDriver");
            //创建连接对象
            Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "oracle");
            //创建sql命令
            String sql="insert into t_user values(?,?,?)";
            //创建sql命令对象
            PreparedStatement ps=conn.prepareStatement(sql);
            //给占位符赋值
                ps.setInt(1, 7);
                ps.setString(2,"赵六");
                ps.setString(3,"666");
                //执行sql命令
                int i=ps.executeUpdate();
            //关闭资源
                ps.close();
                conn.close();
            //返回结果
                return i;
        }   
    //更新
        public int upUser(String uname,int unum) throws ClassNotFoundException, SQLException{
            //加载驱动
            Class.forName("oracle.jdbc.driver.OracleDriver");
            //获取连接对象
            Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "oracle");
            //创建sql命令
            String sql="update t_user set uname=? where unum=?";
            //获取sql命令对象
            PreparedStatement ps=conn.prepareStatement(sql);
            //给占位符赋值
            ps.setString(1, uname);
            ps.setInt(2, unum);
            //执行sql命令
            int i=ps.executeUpdate();
            //关闭资源
            ps.close();
            conn.close();
            //返回结果  
            return i;
        }   
    //删除
        public int delUser(int unum) throws ClassNotFoundException, SQLException{

            //加载驱动
            Class.forName("oracle.jdbc.driver.OracleDriver");
            //获取连接对象
            Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "oracle");
            //创建sql命令
            String sql="delete from t_user where unum=?";
            //获取sql命令对象
            PreparedStatement ps=conn.prepareStatement(sql);
            //给占位符赋值
            ps.setObject(1, unum);
            //执行sql命令
            int i=ps.executeUpdate();
            //关闭资源
            ps.close();
            conn.close();
            //返回结果  
            return i;

        }       
}

JDBC的封装

JDBC的封装:
    问题:
        在数据库操作方法中关于驱动加载和数据库连接对象的代码是重复的.
        会造成修改数据源特别麻烦.
    解决1:

            将jdbc参数在功能类中提取为全局变量
    问题2:
        如果使用解决方式1解决后,修改了数据源则必须重启程序.而开发过程中尽量要求,在不重启程序的情况下完成对
        代码的参数的修改.
    解决2:
        将jdbc参数存储到properties属性配置文件中,封装工具类进行获取.
    知识点:
        properties文件是专门用来存储属性配置的文件,格式要求必须是键值对,以=号隔开.一行一组键值对,并且不能使用分号结尾.
        可以使用Properties对象来进行读取该文件的内容.        
    使用:
        创建java工具类
        创建jdbc参数静态变量
        创建静态代码块
            创建properties对象
            获取properties文件流对象
            加载属性配置文件
            获取jdbc参数并赋值给静态变量
            加载驱动
        创建获取Connection对象的静态方法
        创建获取PreparedStatement对象的静态方法
        创建获取Statement对象的静态方法
        创建关闭资源静态方法
        创建增删改的封装方法--executeDML
注意:需要在src下声明存储了jdbc参数的properties文件(db.properties):
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
username=scott
password=oracle

JDBCUtil封装源码:

public class JdbcUtil {
    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    static{
        //创建properties对象获取属性文件的内容
        Properties p=new Properties();
        //获取属性文件的读取流对象
        InputStream is=JdbcUtil.class.getResourceAsStream("/db.properties");
        try {
            //加载属性配置文件
            p.load(is);
            //获取jdbc参数
            driver=p.getProperty("driver");
            url=p.getProperty("url");
            username=p.getProperty("username");
            password=p.getProperty("password");
            //加载驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //获取Connection对象
    public static Connection getConnection(){
        Connection conn=null;
        try {
             conn=DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;

    }

    //封装获取PreparedStatement对象
    public static PreparedStatement getPreparedStatement(String sql,Connection conn){

        PreparedStatement ps=null;
        try {
            ps =conn.prepareStatement(sql);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ps;

    }

    //封装获取Statement对象
    public static Statement getStatement(Connection conn){
        Statement stmt=null;
        try {
            stmt = conn.createStatement();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return stmt;

    }

    //关闭资源
    public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
        try {
            rs.close();
        } catch (Exception e) {

        }
        try {
            stmt.close();
        } catch (SQLException e) {

        }
        try {
            conn.close();
        } catch (SQLException e) {

        }
    }

    //封装DML
    public static int executeDML(String sql,Object...objs){
        //创建连接对象
        Connection conn=getConnection();
        //创建sql命令对象
        PreparedStatement ps=JdbcUtil.getPreparedStatement(sql, conn);
        //给占位符赋值
            try {
                conn.setAutoCommit(false);
                for(int i=0;i<objs.length;i++){
                    ps.setObject(i+1, objs[i]);
                }
                int i=ps.executeUpdate();
                conn.commit();
                return i;
            } catch (Exception e) {
                    try {
                        conn.rollback();
                    } catch (SQLException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
            }finally{
                //关闭资源
                JdbcUtil.closeAll(null, ps, conn);
            }
            //返回结果
            return -1;
    }
}

JDBC分层MVC

使用分层思想完成功能开发:
    问题:
        1 不同的数据使用相同的数据库操作
        2 不同的数据使用相同的业务逻辑
        3 代码的开发是团队协作进行开发的,需要降低代码与代码之间的耦合性.
    MVC分层:
        Model:数据库层和业务层
        Controller:控制器层(程序的入口)
        View:视图层(jsp以及其他页面资源)
    使用:
        com.bjsxt.dao
        com.bjsxt.daoImpl
        com.bjsxt.service
        com.bjsxt.serviceImpl
        com.bjsxt.pojo
        com.bjsxt.test
        com.bjsxt.util  
---------------------------------------------------------------------------
总结:
    使用MVC分层后使用preparedStatement或者Statement对象完成对数据库的增删改查.

小结:

PrepareStatement用法
封装工具类
属性文件的编写
静态代码块加载属性文件,静态代码块只要类加载 它就会进内存
MVC分层思想
员工管理系统

小知识点

Statement 和  preparedStatement  的区别
写法方面:   preparedStatement 先写SQL命令,再写SQL命令对象,然后把SQL命令传进去。  然后给占位符赋值,可以使用占位符 避免 SQL注入。  
                         优点                                                            缺点
Statement         可以字符串拼接SQL语句                                  有SQL注入的风险,让没有的用户登陆成功   select * from stundet  where1=1
preparedStatement  可以使用占位符避免SQL注入,可以预编译,效率高               不能进行字符串拼接SQL语句。
但是在实际开发中, 密码都要经过加密处理,所以  Statement 和 preparedStatement  都有适合用的场合。


字符串拼接


String sname="张三三";
        String sql="update student set sname='"+sname+"' where snum=2";



可变参数:底层就是一个长度可变的数组。

占位符的使用:  例子:  占位符从1开始
//创建sql命令
            String sql="insert into t_user values(?,?,?)";
            //创建sql命令对象
            PreparedStatement ps=conn.prepareStatement(sql);
            //给占位符赋值
                ps.setInt(1, 7);
                ps.setString(2,"赵六");
                ps.setString(3,"666");
                //执行sql命令
                int i=ps.executeUpdate();

关于日期格式的转换  情况一: 向数据库添加数据的时候 需要把 util的date转成sql的date   java.sql.Date d=new java.sql.Date(hiredate.getTime());
  情况二:  在接收用户输入的时候,需要把String 类型的转换成util的date   Date  hiredate=new SimpleDateFormat("yyyy-MM-dd").parse(date);

员工管理系统的实现

需求文档:

1.项目功能
    名称:员工管理系统
    功能:查询所有  按照编号查询  添加员工  更新员工  删除员工
2.项目技能
    1.使用JDBC访问数据库
    2.分层开发:
    前台:调用后台并输出结果
    后台:使用JDBC访问数据库并返回结果
    3.提前工具类DBUtil,复用代码
    4.使用Properties类读取属性文件
    5.使用log4j记录日志
    6.扩展:提取查询方法(使用反射)
3.搭建项目框架
    1.创建项目 empmgr
    2.添加jar包
    3.创建包
        com.bjsxt.empmgr.dao   后台:存放访问数据库的接口  EmployeeDao
        com.bjsxt.empmgr.dao.impl 后台: 存放访问数据库的实现类 EmployeeDaoImpl
        com.bjsxt.empmgr.entity 后台:存放实体类 Employee
        com.bjsxt.empmgr.test   前台
        com.bjsxt.empmgr.util   工具类,提取数据库常用操作便于重复调用,避免代码重复
    4.创建实体类Employee
    5.创建后台的接口EmployeeDao和实现类EmployeeDaoImpl
        public List<Employee> findAll();
        public Employee findById(int empno);
        public int save(Employee emp);  
        public int update(Employee emp);    
        public void delete(int empno); 

4.实现具体功能
    1.查询所有员工
        1.后台
        2.前台
    2.查询指定编号的员工
        1.后台
        2.前台
    3.提供工具类DBUtil
        好处:复用代码  便于修改维护
        1.获取数据库连接:getConnection()
        2.关闭数据库资源 closeAll(rs,stmt,conn)
    4.添加员工
        1.后台
            日期的处理
            pstmt.setDate(5, new java.sql.Date(emp.getHireDate().getTime()));
            pstmt.setTimestamp(5, new java.sql.Timestamp(emp.getHireDate().getTime()));
        2.前台
    5.更新员工
        1.后台
        2.前台
    6.删除员工
        1.后台
        2.前台
    7.提供工具类DBUtil   
        1.提前DML操作的方法
        2.后台DAO中调用工具类的方法
    8.通过主菜单将各个功能整合到一起
    9.提取业务层
        之前前台负责主菜单和各个具体的交互功能
        现在:前台只负责主菜单
        提取业务层服务各个具体的交互功能
        前台调用业务层,业务层调用DAO层
        两层变成三层
        之前:前台---后台
        现在:前台---业务层----后台(DAO层)

    10.将四个连接参数放入属性文件,便于修改和维护
        Properties是一种特殊的Map,key和value都是String类型,一般用来读写属性文件
        Properties prop = new Properties();
        InputStream is = DBUtil.class.getResourceAsStream("/conn.properties");
        prop.load(is);
        driver = prop.getProperty("driver");


    11.使用log4j记录日志
        1.日志log
            异常信息  登录成功失败的信息  其他重要操作的信息
            方式1:System.out.println(.....)    e.printStackTrace();
            缺点:不是保存到文件,不能长久存储

            方式2:IO流 将System.out.println(.....)    e.printStackTrace();写入文件
            缺点:日志没有等级,日志的格式不能很好的定制

            方式3:使用现成的日志框架,比如log4j
            优点:长久保存   有等级   格式可以很好的定制  代码编写简单

        2.log4j作用
            1.记录日志(长久保存   有等级   格式可以很好的定制)
            2.为后续对日志进行分析统计,查找问题准备好内容

        3.log4j日志的级别
            FATAL:指出现了非常严重的错误事件,这些错误可能会导致应用程序异常中止
            ERROR:指虽有错误,但仍允许应用程序继续运行
            WARN:指运行环境潜藏着危害
            INFO:指报告信息,这些信息在粗粒度级别上突出显示应用程序的进程
            DEBUG:指细粒度信息事件,细粒度信息事件对于应用程序的调试是最有用的


        4.使用log4j记录日志
            1.加入jar包   log4j-1.2.8.jar
            2.加入属性文件 src 下 log4j.properties
            3.通过属性文件理解log4j的主要API
                Appender 日志目的地 :ConsoleAppender   FileAppender 
                Layout 日志格式化器 :SimpleLayout  PatternLayout
            4.代码中记录日志
                private static Logger logger = Logger.getLogger(DBUtil.class.getName());
                logger.info("已经正确的读取了conn.properties:");
                logger.error("dml操作异常:"+e);

        5.理解日志格式化字符的含义 %d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n    


    12.如果把数据库换成MySQL,需要多大的修改
        1.jar包
        2.修改四个属性值
        3.需要有数据库表(借助PowerDesigner的逆向工程将Oracle sql转换成MySQL SQL)
        4.delete 需要使用from
        5.insert 可能会使用序列,但是MySQL不需要

    13.使用反射提取select方法(模拟Hiberante)

SQL语句设计:

需求分析:
    员工管理系统
功能分析:
    查询所有的员工信息
    根据编号查询员工信息
    修改员工信息(修改员工姓名)
    新增员工信息
    删除员工信息
数据库设计:
    员工信息表(emp)
Sql语句设计:
    查询所有的员工信息:
        select *from emp
    根据编号查询员工信息:
        select * from emp where empno=?
    修改员工信息(修改员工姓名):
        update emp set ename=? where empno =?
    新增员工信息:
        insert into emp values(?,?,?,?,?,?,?,?)
    删除员工信息:
        delete from emp where empno=?
功能开发:
    创建数据库操作功能类(不用的数据使用相同的数据库操作)
    创建程序入口类




类实现:
EmpDao.java

import java.util.ArrayList;
import java.util.Date;

import com.zp.pojo.Emp;

public interface EmpDao {
   //查询所有员工信息
    public ArrayList<Emp> selAllEmpInfo();
   //根据编号查询员工信息
    public Emp selEmpInfoByEmpno(int empno);
   //添加员工信息
    public int insEmp(int empno,String ename,String job,int mgr,Date hiredate,double sal,double comm,int deptno);
    //删除员工信息
    public int delEmp(int empno);
    //修改员工信息
    public int upEmp(int empno,String newName);
}

EmpDaoImpl.java:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.temporal.JulianFields;
import java.util.ArrayList;
import java.util.Date;

import com.zp.dao.EmpDao;
import com.zp.pojo.Emp;
import com.zp.util.JdbcUtil;

public class EmpDaoImpl  implements EmpDao{
    //查询所有员工的信息
    @Override
    public ArrayList<Emp> selAllEmpInfo() {
        //声明数据库变量
        ResultSet rs=null;
        //创建集合储存数据
        ArrayList<Emp> list=new ArrayList<>();
        //创建数据库连接对象
        Connection conn=JdbcUtil.getConnection();
        //创建SQL命令
        String sql="select * from emp";
        //创建SQL命令对象
        PreparedStatement ps=JdbcUtil.getPreparedStatement(sql, conn);
        //执行SQL命令
        try {
             rs= ps.executeQuery();
            //遍历查询结果
            while(rs.next()){
             Emp p=new Emp();
             p.setEmpno(rs.getInt("empno"));
             p.setEname(rs.getString("ename"));
             p.setJob(rs.getString("job"));
             p.setMgr(rs.getInt("mgr"));
             p.setHiredate(rs.getDate("hiredate"));
             p.setSal(rs.getDouble("sal"));
             p.setComm(rs.getDouble("comm"));
             p.setDeptno(rs.getInt("deptno"));
             list.add(p);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            JdbcUtil.closeAll(rs, ps, conn);
        }
    //返回结果
        return list;
    }
   //根据编号查询员工的信息
    @Override
    public Emp selEmpInfoByEmpno(int empno) {
        //声明JDBC变量
        ResultSet rs=null;
        //声明Emp对象
        Emp p=null;
        //创建数据库连接对象
        Connection conn=JdbcUtil.getConnection();
        //创建SQL命令
        String sql="select * from emp where empno=?";
        //创建SQL命令对象
        PreparedStatement ps=JdbcUtil.getPreparedStatement(sql, conn);
        try {
            //给占位符赋值
            ps.setInt(1, empno);
            //执行SQL命令
             rs=ps.executeQuery();
             if(rs.next()){
                 p=new Emp();
                p.setEmpno(rs.getInt("empno"));
                p.setEname(rs.getString("ename"));
                p.setJob(rs.getString("job"));
                p.setMgr(rs.getInt("mgr"));
                p.setHiredate(rs.getDate("hiredate"));
                p.setSal(rs.getDouble("sal"));
                p.setComm(rs.getDouble("comm"));
                p.setDeptno(rs.getInt("deptno"));
             }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            JdbcUtil.closeAll(rs, ps, conn);
        }
        //返回结果
        return p;
    }
   //添加员工信息
    @Override
    public int insEmp(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm,
            int deptno) {
        //创建SQL语句
        String sql="insert into emp values(?,?,?,?,?,?,?,?)";
        //将日记格式转换
         java.sql.Date d=new java.sql.Date(hiredate.getTime());
        //执行SQL命令
        int i=JdbcUtil.executeDML(sql,empno,ename,job,mgr,d,sal,comm,deptno);
        return i;
    }
    //删除员工信息
    @Override
    public int delEmp(int empno) {
        return JdbcUtil.executeDML("delete emp where empno=?", empno);
    }
     //修改员工信息
    @Override
    public int upEmp(int empno, String newName) {

        return JdbcUtil.executeDML("update emp set ename=? where empno=?", newName,empno);
    }

}

Emp.java:

import java.util.Date;

public class Emp {
   private  int empno;
   private String ename;
   private String job;
   private int mgr;
   private Date hiredate;
   private double sal;
   private double comm;
   private int deptno;
public Emp() {

}
public Emp(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm, int deptno) {
    super();
    this.empno = empno;
    this.ename = ename;
    this.job = job;
    this.mgr = mgr;
    this.hiredate = hiredate;
    this.sal = sal;
    this.comm = comm;
    this.deptno = deptno;
}
public int getEmpno() {
    return empno;
}
public void setEmpno(int empno) {
    this.empno = empno;
}
public String getEname() {
    return ename;
}
public void setEname(String ename) {
    this.ename = ename;
}
public String getJob() {
    return job;
}
public void setJob(String job) {
    this.job = job;
}
public int getMgr() {
    return mgr;
}
public void setMgr(int mgr) {
    this.mgr = mgr;
}
public Date getHiredate() {
    return hiredate;
}
public void setHiredate(Date hiredate) {
    this.hiredate = hiredate;
}
public double getSal() {
    return sal;
}
public void setSal(double sal) {
    this.sal = sal;
}
public double getComm() {
    return comm;
}
public void setComm(double comm) {
    this.comm = comm;
}
public int getDeptno() {
    return deptno;
}
public void setDeptno(int deptno) {
    this.deptno = deptno;
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(comm);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    result = prime * result + deptno;
    result = prime * result + empno;
    result = prime * result + ((ename == null) ? 0 : ename.hashCode());
    result = prime * result + ((hiredate == null) ? 0 : hiredate.hashCode());
    result = prime * result + ((job == null) ? 0 : job.hashCode());
    result = prime * result + mgr;
    temp = Double.doubleToLongBits(sal);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Emp other = (Emp) obj;
    if (Double.doubleToLongBits(comm) != Double.doubleToLongBits(other.comm))
        return false;
    if (deptno != other.deptno)
        return false;
    if (empno != other.empno)
        return false;
    if (ename == null) {
        if (other.ename != null)
            return false;
    } else if (!ename.equals(other.ename))
        return false;
    if (hiredate == null) {
        if (other.hiredate != null)
            return false;
    } else if (!hiredate.equals(other.hiredate))
        return false;
    if (job == null) {
        if (other.job != null)
            return false;
    } else if (!job.equals(other.job))
        return false;
    if (mgr != other.mgr)
        return false;
    if (Double.doubleToLongBits(sal) != Double.doubleToLongBits(other.sal))
        return false;
    return true;
}
@Override
public String toString() {
    return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate
            + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + "]";
}


}

EmpService.java:

public interface EmpService {
    //查询所有员工的信息
    public void selAllEmpInfo();
    //根据编号查询员工的信息
    public void selEmpInfoByEmpno();
    //删除员工信息
    public void delEmpInfo();
    //添加员工信息
    public void insEmpInfo();
    //修改员工信息
    public void upEmpInfo();

}

EmpServiceImpl.java:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

import com.zp.dao.EmpDao;
import com.zp.daoImpl.EmpDaoImpl;
import com.zp.pojo.Emp;
import com.zp.service.EmpService;

public class EmpServiceImpl  implements EmpService {
    //声明全局数据库库层对象
    EmpDao ed=new EmpDaoImpl();
     //查询所有员工的信息
    @Override
    public void selAllEmpInfo() {
        ArrayList<Emp> list=ed.selAllEmpInfo();
        System.out.println("员工编号\t\t姓名\t\t职位\t\t上级编号\t\t入职时间\t\t薪水\t\t奖金\t\t部门编号");
        for(int i=0 ;i<list.size();i++){
            Emp p=list.get(i);
            System.out.print(p.getEmpno()+"\t\t");
            System.out.print(p.getEname()+"\t\t");
            System.out.print(p.getJob()+"\t\t");
            System.out.print(p.getMgr()+"\t\t");
            System.out.print(p.getHiredate()+"\t\t");
            System.out.print(p.getSal()+"\t\t");
            System.out.print(p.getComm()+"\t\t");
            System.out.print(p.getDeptno()+"\t\t");
            System.out.println();
        }
    }
     //根据编号查询员工信息
    @Override
    public void selEmpInfoByEmpno() {
        //获取用户数据
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入要查询的用户编号");
        int empno=sc.nextInt();
        //操作数据库
        Emp p=ed.selEmpInfoByEmpno(empno);
        //如果返回的用户信息不为空,那么就输出,否则就查询无此人
        if(p!=null){
            System.out.println("员工编号\t\t姓名\t\t职位\t\t上级编号\t\t入职时间\t\t薪水\t\t奖金\t\t部门编号");
                System.out.print(p.getEmpno()+"\t\t");
                System.out.print(p.getEname()+"\t\t");
                System.out.print(p.getJob()+"\t\t");
                System.out.print(p.getMgr()+"\t\t");
                System.out.print(p.getHiredate()+"\t\t");
                System.out.print(p.getSal()+"\t\t");
                System.out.print(p.getComm()+"\t\t");
                System.out.print(p.getDeptno()+"\t\t");
                System.out.println();
        }else{
            System.out.println("查无此人");
        }

    }
    //删除员工信息
    @Override
    public void delEmpInfo() {
        //获取用户输入
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入要删除的员工编号");
        int empno=sc.nextInt();
        //操作数据库
        int i=ed.delEmp(empno);
        //判断结果
        if(i>0){
            System.out.println("删除成功");
        }else{
            System.out.println("删除失败");
        }
    }
    //添加员工信息
    @Override
    public void insEmpInfo() {
        //获取用户输入
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入新增员工编号");
        int empno=sc.nextInt();
        System.out.println("请输入新增员工姓名");
        String ename=sc.next();
        System.out.println("请输入新增员工职位");
        String job=sc.next();
        System.out.println("请输入新增员工上级编号");
        int mgr=sc.nextInt();
        System.out.println("请输入新增员工入职时间(YYYY-MM-DD)");
        String  date=sc.next();
        System.out.println("请输入新增员工工资");
        double sal=sc.nextDouble();
        System.out.println("请输入新增员工奖金");
        double comm=sc.nextDouble();
        System.out.println("请输入新增员工部门编号");
        int deptno=sc.nextInt();
        //将字符串类型的日期转换成Date类型
        //创建日期变量
        Date hiredate=null;
        try {
             hiredate=new SimpleDateFormat("yyyy-MM-dd").parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //执行SQL命令
        int i= ed.insEmp(empno, ename, job, mgr, hiredate, sal, comm, deptno);
        //判断结果
        if(i>0){
            System.out.println("添加成功");
        }else{
            System.out.println("添加失败");
        }

    }
    //修改员工信息
    @Override
    public void upEmpInfo() {
        //获取用户数据
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入要修改的员工编号");
        int empno=sc.nextInt();
        System.out.println("请输入要改成的新名字");
        String newName=sc.next();
        //执行SQL命令
        int i=ed.upEmp(empno, newName);
        //判断结果
        if(i>0){
            System.out.println("修改成功");
        }else{
            System.out.println("修改失败");
        }
    }

}

JdbcUtil.java:

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
 * 对数据库操作相关的工具类
 * @author zhangpeng
 *
 */
public class JdbcUtil {
   private static String driver;
   private static String url;
   private static String username;
   private static String password;
   static{
       //创建properties对象获取属性文件的内容
       Properties  p=new Properties();
       //获取属性文件的读取流对象
       InputStream is=JdbcUtil.class.getResourceAsStream("/db.properties");
       //加载属性配置文件
       try {
        p.load(is);
        //获取jdbc参数
           driver=p.getProperty("driver");
           url=p.getProperty("url");
           username=p.getProperty("username");
           password=p.getProperty("password");
           //加载驱动
           Class.forName(driver);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } 
   }
   //封装获取Connection对象
   public static Connection getConnection(){
       Connection conn=null;
    try {
        conn = DriverManager.getConnection(url,username,password);
    } catch (SQLException e) {
        e.printStackTrace();
    }
       return conn;
   }
   //封装获取PreparedStatement对象
   public static PreparedStatement getPreparedStatement(String sql ,Connection conn){
       PreparedStatement ps=null;
    try {
        ps = conn.prepareStatement(sql);
    } catch (SQLException e) {
        e.printStackTrace();
    }
       return ps;

   }
   //封装获取Statement 对象
   public static Statement getStatement(Connection conn){
       Statement stmt=null;
    try {
        stmt = conn.createStatement();
    } catch (SQLException e) {
        e.printStackTrace();
    }
       return stmt;
   }
   //封装 关闭资源
   public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
       try {
           if(rs!=null){
                rs.close();
           }

    } catch (SQLException e) {
        e.printStackTrace();
    }
       try {
           if(stmt!=null){
               stmt.close();
           }

    } catch (SQLException e) {
        e.printStackTrace();
    }
       try {
           if(conn!=null){
               conn.close(); 
           }

    } catch (SQLException e) {
        e.printStackTrace();
    }
   }
   //封装DML执行操作  增 删 改 操作
   public static int executeDML(String sql,Object...objs){
       //创建连接对象
       Connection conn=getConnection();
       //创建SQL命令对象
       PreparedStatement ps=JdbcUtil.getPreparedStatement(sql, conn);
       //创建SQL命令,已经传进来了
       //设置手动提交

       try {
        conn.setAutoCommit(false);
        //给占位符赋值
           for(int i=0;i<objs.length;i++){
               ps.setObject(i+1, objs[i]);
           }
           //执行SQL命令
           int i=ps.executeUpdate();
           conn.commit();
           return i;
    } catch (Exception e) {
       try {
        conn.rollback();
    } catch (SQLException e1) {
        e1.printStackTrace();
    }
    }finally {
        //关闭资源
           JdbcUtil.closeAll(null, ps, conn);
    }   
       //返回结果   
       return -1;   
   }
}

Test.java:

import java.util.Scanner;

import com.zp.service.EmpService;
import com.zp.serviceImpl.EmpServiceImpl;

public class Test {
    public static void main(String[] args) {
        //创建业务层对象
        EmpService es=new EmpServiceImpl();
        //主界面
        do {
            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("6、退出系统");
            System.out.println("***************************************************");
            //接收用户输入
            Scanner sc=new Scanner(System.in);
            int i=sc.nextInt();
            switch (i) {
            case 1:
                es.selAllEmpInfo();
                break;
            case 2:
                es.selEmpInfoByEmpno();
                break;
            case 3:
                es.insEmpInfo();
                break;
            case 4:
                es.upEmpInfo();
                break;
            case 5:
                es.delEmpInfo();
                break;
            case 6:
                System.out.println("谢谢使用,再见");
                return ;

            default:
                System.out.println("输入有误,请重新输入");
                break;
            }

        } while (true);
    }
}

db.properties:

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=scott
password=tiger

lib:ojdbc6.jar包

遇到的错误:

创建对象不能调方法---->没写main方法
员工信息管理系统:
1、无法输出所有人信息,-->没有把信息存到list中,->list.add();
2、无法添加信息, util类中executeDML 没有写返回值    daoImpl实现类调executeDML传参不正确
3、util 类资源关闭 空指针异常 --> 健壮性不够  加 if(资源!=null){ 资源.close()}
4、实体类编写错误,单词没写对,导致查询不到数据库中的内容
已标记关键词 清除标记
相关推荐
<p> <b><span style="background-color:#FFE500;">【超实用课程内容】</span></b> </p> <p> <br /> </p> <p> <br /> </p> <p> 本课程内容包含讲解<span>解读Nginx的基础知识,</span><span>解读Nginx的核心知识、带领学员进行</span>高并发环境下的Nginx性能优化实战,让学生能够快速将所学融合到企业应用中。 </p> <p> <br /> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><br /> </b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><span style="background-color:#FFE500;">【课程如何观看?】</span></b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端:<a href="https://edu.csdn.net/course/detail/26277"><span id="__kindeditor_bookmark_start_21__"></span></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端:CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课,课程永久有效观看时长,大家可以抓紧时间学习后一起讨论哦~ </p> <p style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <strong><span style="background-color:#FFE500;">【学员专享增值服务】</span></strong> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b>源码开放</b> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化 </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 下载方式:电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a>,播放页面右侧点击课件进行资料打包下载 </p> <p> <br /> </p> <p> <br /> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页