zoukankan      html  css  js  c++  java
  • JDBC

    jdbc:java操纵数据库技术

    在jdk中 : 定义了多个接口,接口中约定了一些规则(抽象方法)

    数据库厂商 : 定义一些类,实现接口,并且按约定实现接口中的方法

    接口简介

    java.sql.Connection : 规定数据库的连接
    java.sql.PreparedStatement:sql发送工具
    java.sql.ResultSet: 处理结果集
    java.sql.Driver: 数据库驱动
    java.sql.DriverManager: 数据库驱动管理

    JDBC主要步骤

    PLSql操纵数据库的步骤

    1.连接数据库 用户名 密码 数据库库名(xe)

    2.创建sql发送窗口

    3.编写sql.发送sql

    4.接收并处理结果集

    5.关闭客户端

    JDBC

    1.加载驱动

    2.获得数据库连接对象(Connection对象)

    3.获取sql发送工具对象(PreparedStatement对象)

    4.编写sql,发送sql

    5.接收并处理结果集对象(ResultSet对象)

    6.关闭资源 ResultSet PreparedStatement Connection

    第一个JDBC代码

    需求:向t_person表中添加一条数据

    create table t_person(
      id number(3) primary key,
      name varchar2(50),
      age  number(3),
      sex  number(1), ---0表示女性  1表示男性
      mobile varchar2(20),
      address varchar2(100)     
    )
    
    insert into t_person values(100,'王xx',18,0,'12312341234','河南郑州')
    导包: ojdbc6.jar
    1.项目---右键----new---folder---lib---将ojdbc6.jar放入lib
    2.jar包---右键---build path-----add to  build  path
    
    
    class JDBC{
    public static void main(String[] args) throws Exception {
            //1.加载驱动  
            Class.forName("oracle.jdbc.OracleDriver");
            //2.获得数据库连接对象(Connection对象)
            /**
             * url:指明数据库的路径
             *     jdbc:oracle:thin:@电脑ip:端口号:数据库库名
             *     jdbc:oracle:thin:@localhost:1521:xe
             */
            Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            System.out.println(conn);
            //3.获取sql发送工具对象(PreparedStatement对象)
            String sql = "insert into t_person values(111,'小杰',16,0,'11122222222','河南郑州')";//sql不加;
            PreparedStatement pstm = conn.prepareStatement(sql);
            //4.发送sql   pstm.executeUpdate()  作用于dml(增删改)语句     返回值这次sql操作影响了表中的几条数据
            int executeUpdate = pstm.executeUpdate();
            System.out.println("影响表中数据:"+executeUpdate);
            //5.接收并处理结果集对象(ResultSet对象)
            //6.关闭资源  ResultSet PreparedStatement Connection  后开的先关
       pstm.close();
       conn.close();
       
        }
    
    
    
    }

    JDBC的查询

    ResultSet

      结果集对象

    需求:查询id=100的信息

    public static void main(String[] args) throws Exception {
            //加载驱动
            Class.forName("oracle.jdbc.OracleDriver");
            //获取数据库连接对象
            Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
            //获取sql发送工具对象
            PreparedStatement pstm = conn.prepareStatement("select * from t_person ");
            //发送sql 
            ResultSet rs = pstm.executeQuery();
            //接收并处理结果集
            //将指针下移一行航
            while(rs.next()) {
                //代表有值
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                int sex = rs.getInt(4);
                String mobile = rs.getString(5);
                String addr = rs.getString(6);
                System.out.println("id="+id+"   name="+name+"   age="+age+"   sex="+sex+"     mobile="+mobile+"   addr="+addr);
            }
            //关闭资源
            rs.close();
            pstm.close();
            conn.close();
        }

    JDBC的动态参数设置

    1.拼接字符串

    问题:不能防止sql注入

    2.设置占位符

      占位符:?

      sql当中需要动态写入值的地方

    public static void main(String[] args) throws Exception {
            Scanner sc = new Scanner(System.in);
            System.out.println("id:");
            int id = sc.nextInt();
            System.out.println("name:");
            String name = sc.next();
            System.out.println("age:");
            int age = sc.nextInt();
            System.out.println("sex:");
            int sex = sc.nextInt();
            System.out.println("mobile:");
            String mobile = sc.next();
            System.out.println("address:");
            String addr = sc.next();
            //1.加载驱动  
            Class.forName("oracle.jdbc.OracleDriver");
            //2.获得数据库连接对象(Connection对象)
            /**
             * url:指明数据库的路径
             *     jdbc:oracle:thin:@电脑ip:端口号:数据库库名
             *     jdbc:oracle:thin:@localhost:1521:xe
             */
            Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            System.out.println(conn);
            //3.获取sql发送工具对象(PreparedStatement对象)
            String sql = "insert into t_person values(?,?,?,?,?,?)";//sql不加;
            PreparedStatement pstm = conn.prepareStatement(sql);
            //给站位符赋值
            pstm.setInt(1, id);
            pstm.setString(2, name);
            pstm.setInt(3, age);
            pstm.setInt(4, sex);
            pstm.setString(5, mobile);
            pstm.setString(6, addr);
            
            
            //4.发送sql   pstm.executeUpdate()  作用于dml(增删改)语句     返回值这次sql操作影响了表中的几条数据
            int executeUpdate = pstm.executeUpdate();
            System.out.println("影响表中数据:"+executeUpdate);
            //5.接收并处理结果集对象(ResultSet对象)
            //6.关闭资源  ResultSet PreparedStatement Connection  后开的先关
       pstm.close();
       conn.close();
       
        }

    pstm预编译

    实体类

    一个实体类对应了数据库中的一张表

    实体类中的一个属性对应了表中的一个字段

    一个书体类对象对应了表中的一行数据

    实体类的存放位置: com.baizhi.entity

    Dao

    date access object:数据库访问对象

    public class BookDao {
        //添加
        public void insert(Book b) {
            //获取数据库连接对象
            Connection conn = null;
            //获取sql发送工具对象
            PreparedStatement pstm = null;
            try {
                //加载驱动
                Class.forName("oracle.jdbc.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
                pstm = conn.prepareStatement("insert into t_book values(seq_book.nextval,?,?,?)");
                //给占位符赋值
                pstm.setString(1, b.getName());
                pstm.setString(2, b.getAuthor());
                pstm.setDouble(3, b.getPrice());
                //发送sql
                pstm.executeUpdate();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("添加失败,原因为:");
                e.printStackTrace();
            } finally {
                //接收并处理结果集
                //关闭资源
                if (pstm != null) {
                    try {
                        pstm.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
            }
            
        }
        //根据id删除
        public void delete(int id) {
            //获取数据库连接对象
            Connection conn = null;
            //获取sql发送工具对象
            PreparedStatement pstm = null;
            try {
                //加载驱动
                Class.forName("oracle.jdbc.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
                pstm = conn.prepareStatement("delete from t_book where book_id = ?");
                //给占位符赋值
                pstm.setInt(1, id);
                //发送sql
                pstm.executeUpdate();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("删除失败,原因为:");
                e.printStackTrace();
            } finally {
                //接收并处理结果集
                //关闭资源
                if (pstm != null) {
                    try {
                        pstm.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        //修改
        public void update(Book b) {
            Connection conn = null;
            PreparedStatement pstm = null;
            try {
                Class.forName("oracle.jdbc.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
                pstm = conn.prepareStatement("update t_book set book_name=?,AUTHOR=?,PRICE=? where book_id=?");
                pstm.setString(1, b.getName());
                pstm.setString(2, b.getAuthor());
                pstm.setDouble(3, b.getPrice());
                pstm.setInt(4, b.getId());
                pstm.executeUpdate();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                if (pstm != null) {
                    try {
                        pstm.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            
        }
        //根据id查询一个
        public Book selectById(int id) {
            Book book =  null;
            Connection conn = null;
            PreparedStatement pstm = null;
            ResultSet rs = null;
            try {
                book = new Book();
                Class.forName("oracle.jdbc.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
                pstm = conn.prepareStatement("select * from t_book where book_id = ?");
                pstm.setInt(1, id);
                rs = pstm.executeQuery();
                if(rs.next()) {
                    book.setId(rs.getInt("book_id"));
                    book.setName(rs.getString("book_name"));
                    book.setAuthor(rs.getString("author"));
                    book.setPrice(rs.getDouble("price"));
                }
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }    
                }
                if (pstm != null) {
                    try {
                        pstm.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
            }
            return book;
        }
        //查询全部
        public List<Book> selectAll(){
            List<Book> list = new ArrayList<Book>();
            Connection conn = null;
            PreparedStatement pstm = null;
            ResultSet rs = null;
            try {
                Class.forName("oracle.jdbc.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
                pstm = conn.prepareStatement("select * from t_book");
                rs = pstm.executeQuery();
                while(rs.next()) {
                    Book book = new Book();
                    book.setId(rs.getInt("book_id"));
                    book.setName(rs.getString("book_name"));
                    book.setAuthor(rs.getString("author"));
                    book.setPrice(rs.getDouble("price"));
                    list.add(book);
                }
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                if (rs != null) {
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }    
                }
                if (pstm != null) {
                    try {
                        pstm.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                
            }
            return list;
        }
    }

    ORM

    Object Realtioonal Mapping:对象关系映射

    主要含义:使数据库中的数据以对象的形式在程序中流转

    dao+实体类=ORM

    接口编程



    项目的包结构

    com.baizhi.entity ----- 实体类

    com.baizhi.dao ------- dao的接口

    com.baizhi.dao.impl ----- dao的实现类

    com.baizhi.test ----- 测试类

     

    JDBCUtil

    编写JDBC的工具类,将创建连接以及关闭连接等每个dao方法当中都要重复编写的代码(获取连接,关闭连接)给封装起来(封装成一个方法),每当dao要使用这段代码时,就调用JDBCUtil当中的方法即可

    位置:com.baizhi.util

    第一版

    public class JDBCUtil {
        //加载驱动.获取连接
        public static Connection getConn() {
            Connection conn = null;
            try {
                Class.forName("oracle.jdbc.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            return conn;
        }
        
        
        //关闭资源    
        public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
            if(rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    第二版

    第一版问题

    第一版解决办法

    public class JDBCUtil {
        //加载驱动.获取连接
        public static Connection getConn() {
            Connection conn = null;
            try {
                //创建properties
                Properties pro = new Properties();
                //获取输入流
                InputStream is = JDBCUtil.class.getResourceAsStream("/JDBCUtil.properties");
                //读取JDBCUtil.properties
                pro.load(is);
                //获取键值对
                String className = pro.getProperty("className");
                String url = pro.getProperty("url");
                String user = pro.getProperty("user");
                String pwd = pro.getProperty("pwd");
                Class.forName(className);
                conn = DriverManager.getConnection(url, user, pwd);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            return conn;
        }
        
        
        //关闭资源    
        public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
            if(rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    第三版

    第二版的问题

    • 每次调用getConnection,都会执行一遍读取配置文件操作,影响程序的运行效率

    解决方案:

      将读取配置文件的操作,放置到静态代码块中,保证读取文件的操作有且必须执行1遍

    public class JDBCUtil {
        private static String  className;
        private static String  url;
        private static String  user;
        private static String  pwd;
        static {
            //创建properties
            Properties pro = new Properties();
            //获取输入流
            InputStream is = JDBCUtil.class.getResourceAsStream("/JDBCUtil.properties");
            //读取JDBCUtil.properties
            try {
                pro.load(is);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //获取键值对
            className = pro.getProperty("className");
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            pwd = pro.getProperty("pwd");
            //关流
            try {
                is.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //加载驱动.获取连接
        public static Connection getConn() {
            Connection conn = null;
            try {
                
                Class.forName(className);
                conn = DriverManager.getConnection(url, user, pwd);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            return conn;
        }
        
        
        //关闭资源    
        public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
            if(rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    项目的三层结构

    视图层(view)

    作用:完成与用户的交互,接收用户输入的信息,向用户展示信息

    技术:HTML CSS JS JQuery....目前使用主函数代替

    业务层(service)

    作用:根据功能需求,调用dao,完成逻辑判断

    编码过程:马上学

    持久层(dao)

    作用:将数据持久化的保存在数据库,从数据库提取数据

    编码过程:已经学了

     

    业务层详解

    存放位置:com.baizhi.service --- service的接口

    com.baizhi.service.impl --- service的实现类

    项目编程步骤

    1.建项目

    2.导入jar包

    3.导入工具类

    a. JDBCUtil.java ------ com.baizhi.util

    b.JDBCUtil.properties ----- src

    4.建表

    5.建实体类 ------ com.baizhi.entity

    6.dao

    a.dao的接口 ------ com.baizhi.dao

    b.dao的实现类 ----- com.baizhi.dao.impl

    7.测试dao

    a. 测试类 ------- com.baizhi.test

    8.service

    a.service的接口 ---- com.baizhi.service

    b.service的实现类 ----- com.baizhi.service.impl

    9.测试service

    a. 测试类 ------- com.baizhi.test

    service事务控制

    什么叫事务

    含义:在一个功能(一系列的sql操作),要么全部成功,要么全部失败

    例:

    范大头老师在5月20号时,要给女朋友转500元,为了过光棍劫

    service{
    转账(){
      try{
          conn.setAutoCommit(false);
    //1.从范大头的账户中-500元
      //2.给女朋友+500元
      conn.commit();
      }catch(Exception e){
          conn.rollback();
          throw new RuntimeException(e);
      }        
    }    
    }

    JDBC控制事务

    jdbc的事务控制
    默认每完成一次sql操作,自动提交一次事务


    手动控制事务
    开启手动控制事务: conn.setAutoCommit(false);

    提交事务:  conn.commit();

    回滚事务: conn.rollback();

    解决service和dao的连接不相同问题

    方法一:将conn作为dao方法中的参数传入

    interface XXDao{
    void insert(User user, Conncetion conn);

    }

    class XXservice{
    insert(User user){
      Conncetion conn = JDBCUtil.getConn()
      XXDao dao = new XXDaoImpl();
      dao.insert(user,conn);    
    }
    }

    缺点:

    1.将连接对象定义在了Dao方法声明中,强耦合

    2.修改的代码太多了

    方法二 : Threadlocal(储存空间)

    1.有效范围

    在同一个线程中有效 ---- 存的时间
    存一个键值对(线程对象,value) ---- 存内容的多少

    2.怎么存(方法)

    tl.set(value)

    3.怎么取(方法)

    tl.get();

    4.怎么移除(方法)

    tl.remove();

    JDBCUtilFinal

    public class JDBCUtil {
        private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); 
        private static String className;
        private static String url;
        private static String user;
        private static String pwd;
        static {
            //创建properties
            Properties pro = new Properties();
            //获取输入流
            InputStream is = JDBCUtil.class.getResourceAsStream("/JDBCUtil.properties");
            //读取JDBCUtil.properties
            try {
                pro.load(is);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //获取键值对
             className = pro.getProperty("className");
             url = pro.getProperty("url");
             user = pro.getProperty("user");
             pwd = pro.getProperty("pwd");
        }
        //加载驱动.获取连接
        public static Connection getConn() {
            if (tl.get() == null) {
                try {
                    Class.forName(className);
                    Connection conn = DriverManager.getConnection(url, user,pwd);
                    tl.set(conn);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            } 
            return tl.get();
        }
        
        
        //关闭资源    
        public static void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs) {
            if(rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);
                }
            }
            if(pstm != null) {
                try {
                    pstm.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                    tl.remove();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    throw new RuntimeException(e);
                }
            }
        }
    }

    注意:

    1.在dao中不能关闭conn

    2.在service中关闭conn

    JUint单元测试

    步骤:

    1.添加@Test注解,方法上添加

    2.引入JUnit jar包

     

    3.定义方法

    要求: 无参无返回值,方法名随意的方法

    4.运行方法时.点击方法名,右键------runs ------ Junit Test

    注意事项

    1.类名 方法名都不要叫Test

    以粮为纲全面发展
  • 相关阅读:
    第6章 函数 习题
    2. VS使用---HelloWorld
    [计蒜客]小 B 的题目
    [计蒜客] n 子棋
    [博弈]Euclid's Game
    [博弈]A Funny Game
    [博弈]Being a Good Boy in Spring Festival
    [组合数学]Magic 12 Months(坑)
    [PTA]L2-031 深入虎穴 (25 分)
    [天梯赛]L2-029 特立独行的幸福
  • 原文地址:https://www.cnblogs.com/alexliuf/p/13788244.html
Copyright © 2011-2022 走看看