JDBC

JDBC (java database connection)

    作用:是由sun公司提供的一套 jdbc api 可以使用纯java代码连接"任意"数据库

数据库连接操作

    1.加载驱动        驱动:数据库厂商根据sun公司提供的接口 完成的对自己公司数据库连接的实现
        Class.forName("oracle.jdbc.OracleDriver");        //加载驱动,注册Driver,利用反射原理
    2.获取数据库连接(java.sql.Connection)
        //getConnection(   (协议:ip地址:端口号:数据库名字),用户名,密码   )
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "ami", "ami");
    3.获取Statement对象,发送sql语句(java.sql.Statement)

        Statement st = conn.createStatement();    //Statement 接口代表了一个数据库的状态
        executeUpdate(String sql):int        //返回值的作用,经常用来判断实际更新值是否与预期更新值相符
        executeQuery(String sql):ResultSet
            //当已知查询返回单条记录时使用if(rs.next())即可
            while( rs.next() ){   // next()代表是否有一条数据  true代表有 进入while循环  false代表没有 不会进入while循环
                int userid = rs.getInt("userid");
                String uname = rs.getString("uname");
                String pwd = rs.getString("upwd");
                System.out.println( userid + " " + uname + " " + pwd );
            }

    4.关闭数据库连接(释放资源)
        rs.close(); sta.close(); con.close();
        依次依赖
        按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,
        因为Statement和 ResultSet 是需要连接时才可以使用的,
        所以在使用结束之后有可能其它的 Statement 还需要连接,不能现关闭 Connection

PreparedStatement(Statement的子类)

    使用Statement出现的问题:i.效率低 因为创建过多的字符串对象    ii.sql注入    //"aa"和123' or '1'='1
    PreparedStatement ps = conn.prepareStatement(String sql);    //预加载sql语句
        占位符 ?    //填充sql语句    //将SQL语句中取值发生变化的部分用占位符(?)代替
        //给?赋值(也称参数绑定)
        ps.setXXX(第几个占位符,值);    //第几个占位符:“?”出现的次数       

    空值处理:如果要设置某个?取值为null,需要做如下操作:
           ps.setObject(4, null); // 这种较好理解,建议使用
           ps.setNull(4, java.sql.Types.DECIMAL);
           // 第2参数为?对应列的数据类型,常量

    模糊查询:
        eg:String sql=" select * from emp where ename like ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1,"%M%");    //强调:%的位置不是写在?附近,而是通过setString方法调用时传入

封装重复代码 DBUtils.java

    工具类:XxxUtils.java    //内部常写静态方法
    java中的配置文件:xxx.properties
        1)properties文件中格式采用key=value的形式
        2)properties文件中的注释使用#开头
        3)properties文件中不能出现中文(习惯上都是以ISO-8859-1编码)


    //工具类,内部常写静态方法
    public class DBUtils {
        private static Properties pro = new Properties();    //获取Properties对象,需要设置static,类加载时分配空间    且    静态方法中只能调用静态属性
        static{    //设置静态代码块,类加载时执行一次,只需要读取一次配置文件
            InputStream is=null;
            try {
                is = new FileInputStream("src\\jdbc.properties");    //读取文件
                pro.load(is);    //加载输入流
            } catch (Exception e) {e.printStackTrace();
            }finally{
                if(is!=null){    //关闭读写流
                    try{
                        is.close();
                    }catch(Exception e) {e.printStackTrace();}
                }
            }
        }

        // 声明一个静态的ThreadLocal变量,泛型表示它只能存取Connection类型的变量
        private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();    //定义ThreadLocal对象

        public static Connection getConnection(){    //静态方法,获取数据库连接
            Connection conn = tl.get();    //先获取conn对象,如果是null,则继续执行,否则要直接返回
            try {
                if(conn==null){
                    Class.forName(pro.getProperty("Driver"));    //加载驱动    //根据key值获取value值
                    conn = DriverManager.getConnection(pro.getProperty("url"),pro.getProperty("username"),pro.getProperty("userpassword"));    //获取数据库连接
                    tl.set(conn);    //保存conn对象到ThreadLocal中
                }
            } catch (Exception e) {e.printStackTrace();}
            return conn;
        }

        public static void close(ResultSet rs,Statement st,Connection conn){    //静态方法,关闭资源
            try {
                if(rs!=null)rs.close();
                if(st!=null)st.close();
                if(conn!=null){
                    conn.close();
                    // 连接关闭后移除Thread中的conn对象
                    tl.remove();    //清除ThreadLocal对象,防止对下一个线程造成破坏
                }
                } catch (SQLException e) {e.printStackTrace();}
        }
    }


关闭资源:
    由于Service(Biz) 和 Dao 公用了一个数据库连接,所以要在最后关闭数据库连接
    如果中途关闭数据库连接,则会出现数据库连接已关闭这样的异常

    在Biz中统一关闭数据库连接        DBUtils.close(null,null,conn);
    在Dao中关闭ResultSet,Statement,但不关闭Connection        DBUtils.close(rs,ps,null);

实体类 把数据库的数据存到的对象中

    根据主键查询数据库后,会得到一组相关数据,这些数据共同描述了Java里关于一个对象的属性信息,
    所以将这组数据提取封装成一个整体,方便数据在java程序之间的传递。
    这个对象一般称为实体(entity,也称为JavaBean)。

    Java实体类型与数据库对应关系:
        Java实体类        ?     数据库表
        实体类实例      ???      表中一条记录
        实体类OID        ?     表主键
        实体类普通属性    ?      表中列

    标准实体Bean定义的语法要求:
        属性全部私有
        提供get/set方法
        提供无参构造方法    //最好也提供有参构造方法
        实现Serializable接口
        对于可以为空的属性,定义时选择包装类型,以表示 null 值

Dao层(数据访问层) (database access object) 数据库访问模型

    对一张表做增删改查等操作   ---    写到一个 类中
        命名规范:BookDao.java

Biz层(业务逻辑层)(Service) (Business Object)

    主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计
    避免写重复的代码,因为有些功能需要同时增删除改查等操作,所以直接在业务层重复调用即可
    命名规范:BookBiz.java | BookService.java

view层(视图层/显示层)

    主要完成数据的录入和结果的展示
    它面向的群体是真正的用户,主要负责接收用户的访问请求,收集完成请求所需数据
    当处理结束后,向用户展示执行结果

事务

    如果在一个事务中有多条sql语句, 我们希望某一条sql语句如果执行是失败了。
    那么刚才执行成功的sql语句 能够(撤销执行)回滚

    JDBC里默认的事务提交策略是执行成功一条记录就提交一次

    conn.setAutoCommit(boolean a);    //true自动提交,false手动提交
        注意:此方法一经设置,永久生效。
        经由这个conn执行的命令的结果都需要手动提交,不需要反复设置。
    conn.commit();
    conn.rollback();    //在Biz层回滚
    conn.getAutoCommit();    //获取当前提交状态

ThreadLocal        --为了保证Service(Biz) 中的  Connection 对象 和 Dao中的 Connection 对象是同一个
    在当前自己的线程中保存一个对象到ThreadLocal中,
    过一会,在当前线程中可以取出来刚才保存的对象

    ThreadLocal<E> tl = new ThreadLocal<E>();
    tl.set(value);    //保存对象
    tl.get();        //取出对象
    tl.remove();    //清除ThreadLocal的对象

日期数据处理

    如何得到一个java.util.Date对象
        方法1:从字符串转换为日期
            String dateStr = "1999-10-10";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            java.util.Date d = sdf.parse(dateStr);
        方法2:从日历对象得到日期
            Calendar c = Calendar.getInstance(); // 日历对象
            c.set(1999,11,23);
            java.util.Date d2 = c.getTime();
        方法3:从一个毫秒值得到日期
            java.util.Date d3 = new java.util.Date(System.currentTimeMillis()));
    如何得到一个java.sql.Date对象    //获得java.sql.Time, java.sql.Timestamp与此类似
           long time = new java.util.Date().getTime();  // 拿到毫秒时
           // 通过毫秒值构造子类型对象
            java.sql.Date sd = new java.sql.Date(time);   
    如何得到一个字符串时间值
        java.util.Date  date = new java.util.Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String time = sdf.format(date);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值