JDBC

104 阅读7分钟

JDBC

JDBC的全称是Java Database Connectivity,是Java连接数据库的规范和API。该规范中定义了一系列的接口,由数据库厂商根据自身数据库的特点提供实现类。开发者根据接口调用方法,就可以屏蔽不同数据库的差异。这样,无论连接和操作哪种数据库,都是一套API。

maven

配置maven文件

apache-maven-3.6.3----setting----修改setting位置,配置mirror的aliyun

idea里面配置maven:

setting---builder----maven----配置maven

驱动包

是数据库厂商针对jdbc规范所写的实现类,连接不同数据库时,应该使用不同数据库厂商提供的驱动包。

JDBC开发流程

1、建立连接

2、执行sql语句,操作数据库数据

3、关闭连接

依赖包:

dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>

开发流程

  • 加载驱动

    Class.forName("com.mysql.jdbc.Driver");
    
  • 建立连接

    //连接对象
    Connection con=null;
    //sql语句执行对象
    PreparedStatement ps =null;
    //建立连接  localhost表示连接数据库所在服务器的ip地址  
    // 12345为连接的端口号  mydb表示连接mysql数据库的库名
    //characterEncoding=utf-8设置编码集
    con= DriverManager.getConnection("jdbc:mysql://localhost:12345/mydb?characterEncoding=utf-8");
    
  • 执行语句

    //执行sql语句
    ps=con.prepareStatement("insert into t_link(l_name,l_birthday,l_sex,l_phone) values(?,?,?,?)");
    //填充占位符
    ps.setObject(1,linkObj.getName());
    ps.setObject(2,linkObj.getBirthday());
    ps.setObject(3,linkObj.getSex());
    ps.setObject(4,linkObj.getPhone());
    //更新数据库,将数据真正写入数据库
    ps.executeUpdate();
    
  • 关闭连接

    //关闭连接,后建立先关闭
    ps.close();
    con.close();
    

模糊查询

Connection con=null;
    PreparedStatement ps=null;
    ResultSet rs=null;
    List<LinkBean> list=new ArrayList<>();
    try {
        //加载驱动
        Class.forName("com.mysql.jdbc.Driver");
​
        //建立连接
        con=DriverManager.getConnection("jdbc:mysql://localhost:12345/mydb?characterEncoding=utf-8","root","root");
        //执行sql语句
        ps=con.prepareStatement("select * from t_link where l_name like ?");
        ps.setObject(1,"%"+name+"%");
        rs=ps.executeQuery();
        while(rs.next()){
            LinkBean linkObj=new LinkBean();
            linkObj.setId(rs.getInt("pk_linkId"));
            linkObj.setName(rs.getString("l_name"));
            linkObj.setBirthday(LocalDate.parse(rs.getString("l_birthday")));
            linkObj.setSex(rs.getString("l_sex"));
            linkObj.setPhone(rs.getString("l_phone"));
            list.add(linkObj);
        }
​
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        try {
            rs.close();
            ps.close();
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return list;
​
}

常见异常

java.lang.ClassNotFoundException: com.mysql.jdbc.Drver类没有找到异常,加载类时,指定路径的类不存在时抛出 Caused by: java.net.UnknownHostException: 连接主机异常,通常是主机的IP有误 Caused by: java.net.ConnectException: Connection refused: connect连接超时,通常是指定端口连接不上抛出

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'homewerk'指定数据库名不存在时抛出

java.sql.SQLException: Access denied for user 'rot'@'172.17.0.1' (using password: YES)登录mysql的账号或密码错误

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax;执行sql语句语法错误

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'u_rade' in 'where clause'指定列不存在时抛出

java.sql.SQLException: Parameter index out of range (4 > number of parameters, which is 3).占位符的个数和填充值得个数不匹配时抛出

java.sql.SQLException: Before start of result set结果集指针指向第一条记录的上一条记录,当前结果集指针的指向没有数据时抛出,解决方案是:用rs.next()将结果集指针指向第一条记录

java.sql.SQLException: Column 'pk_serId' not found.

SQL注入

再JDBC执行SQL语句时,如果以拼接字符串方式插入值,一旦值中有SQL语句的关键字,会导致SQL语句语法错误,或执行结果不正确情况,这称为SQL注入攻击。

Statement和prepareStatement的区别

Statement是prepareStatement的父接口,Statement执行SQL语句时,只能以拼接字符串方式插入值,效率低,而容易引起SQL注入。

prepareStatement提供了占位符方式插入SQL语句的值,无论时什么值,都当字符串处理,不会引起SQL注入。

拼接操作

同时查询多个条件

public List<UserBean> findByItem(String name, LocalDate beginDate, LocalDate endDate) {
    List<UserBean> list =new ArrayList<>();
    this.setConnection();
    try {
        String sql="select * from t_user where 1=1 ";
        List valueList =new ArrayList<>();
        if (name!=null && name.length()!=0){
            sql+="and u_name like ? ";
            valueList.add("%"+name+"%");
        }
        if (beginDate!=null){
            sql+="and u_birthday >= ? ";
            valueList.add(beginDate);
        }
        if (endDate !=null){
            sql+="and u_birthday <= ?";
            valueList.add(endDate);
        }
        ps= con.prepareStatement(sql);
        for (int i=0;i<valueList.size();i++){
            ps.setObject(i+1,valueList.get(i));
        }
        rs=ps.executeQuery();
​
       while (rs.next()){
           list.add(this.getUser());
       }
​
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        this.colseConnection();
    }
    return list;
}

idea打断点

Show Execution Point (Alt + F10):如果你的光标在其它行或其它页面,点击这个按钮可跳转到当前代码执行的行。

Step Over (F8):步过,一行一行地往下走,如果这一行上有方法不会进入方法。
​
Step Into (F7):步入,如果当前行有方法,可以进入方法内部,一般用于进入自定义方法内,不会进入官方类库的方法。
​
 Force Step Into (Alt + Shift + F7):强制步入,能进入任何方法,查看底层源码的时候可以用这个进入官方类库的方法。
​
 Step Out (Shift + F8):步出,从步入的方法内退出到方法调用处,此时方法已执行完毕,只是还没有完成赋值。
​
 Drop Frame (默认无):回退断点。
​
 Run to Cursor (Alt + F9):运行到光标处,你可以将光标定位到你需要查看的那一行,然后使用这个功能,代码会运行至光标行,而不需要打断点。
​
 Evaluate Expression (Alt + F8):计算表达式。

blog.csdn.net/piano_diano…

三层架构

三层架构模式

三层架构模式数据架构模式。将整个业务应用从低到高划分为:表示层、业务逻辑层、数据访问层(持久层)

数据访问层:完成内存和数据库之间的数据交互

表示层:完成数据

数据持久层采用DAO模式(Date Access Object),只做数据交互

业务逻辑层采用事务脚本模式,业务满足需要

表现层采用MVC模式

M:模式,实体

V:视图

C:

对象模型

class Man{

private List roomList;

}

class Room{

private Man man;

}

业务接口:一个实体类一个业务接口,一次提交一个业务方法,业务方法参数来自表现层

持久接口:一个实体类一个持久接口,一次数据库操作一个持久方法。持久方法参数来自业务层。

接口隔离原则:使用专门的接口比用统一接口好。便于项目组织和分工,不要让开发者面对自己用不到的方法

网络编程

OSI模型

在计算机网络中,存在不同厂商、不同结构的网络产品。这些网络产品在进行互连时会遇到不兼容的问题。

国际标准化组织ISO提出OSI(Open System Interconnection )开放系统互联的参考模型,为异构系统互联提供了概念性的框架

OSI网络模型:将网络分为七个层:应用层、表示层、会话层、传输层、数据链路层、物理层。

TCP/IP协议对OSI网络模型中的一些层进行了合并,将应用层、表示层、会话层,合并为应用层。传输层不变,网络层变成了网络互联层,数据链路层和物理层,合并为网络接口层。

端口:就是应用程序用于数据交互的通道,用于实现程序间的通信,每个应用程序都有固定的端口。

两个应用程序如果使用同一个端口,那么会抛出端口冲突异常java.net.BindException

常见的端口: tel协议-----23

smtp协议------25

ftp协议-----21

http协议----80

数据传输由TCP/IP分层模型中的传输层负责,该层包括TCP和UDP两种协议。TCP协议是一种比较可靠的传输协议,提供三次握手机制。信息在传输过程中有遗失,有损耗,会要求发送方重新发送,从而保证信息的完整性。

UDB协议是一种比较不可靠的传输协议,信息在传输过程中,有遗失,有损耗,不会要求发送方重新发射。特点时速度快。

端口号范围:0-65535

html全称超文本标记语言。超文本的意思是在HTML中不仅仅包含文本数据,而且可以通过一系列标记,链接各式各样的资源(图片、音频、视频、css、js等)。客户端在显示html网页,不仅仅需要下载文本数据,还需要发出一系列的请求,将该网页链接资源一一下载。

GIT

git 是一种分布式版本控制工具,目前项目中比较常见得版本控制器有svn,cvs等,这些版本控制工具数据集中式版本控制器。

集中式版本控制器的主要特点就是项目的版本库保存在服务器,该服务器和开发人员的开发机要在同一网段中,开发机从服务器down下项目,然后进行开发,开发过程中需要实时地将新的版本更新到服务器。一旦服务器挂掉了,整个开发就会受到很大影响。

分布式版本控制器得主要特点就是不需要专用服务器,每台开发机都有独立得版本库,相当于每台开发机都是服务器,开发机之间可以相互传递版本内容,由于没有中央服务器,也不用担心网络中断后影响开发,当然,为了方便传递数据,也可以建立一个专门用来交换数据得服务器,比如github、码云就充当着这个角色。

git的本地操作

Git作为分布式版本库软件,每个机器都是一个版本库。

git初始化后,有3个区:分别式工作区、暂存区、本地库。

工作区是我们编辑代码的区域,包括新增、修改、删除代码操作,我们编码代码后,添加到暂存区。

暂存区是临时存储代码的地方,方便批量提交数据到本地库

本地库是最终的历史版本文件的暂存地。

设置邮箱和用户名

git config --global user.name "用户名" git config --global user.email "邮箱"

git的初始化: git init

在工作空间会出现.git的隐藏文件夹。该目录是版本管理的一些配置文件和控制程序,以及存储目录。

git status 查看状态

通过git status查看状态,可以看到有哪些文件没有提交到暂存区。

通过git add 命令,可以提交新加文件到暂存区

git add * 提交所有新加文件到暂存区

通过git commit 命令,将所有暂存区文件提交到本地库,需要写注释

eg:git commit -m "add 1.jpg 2.jpg"

当已提交的文件修改后需要重新提交到本地库

eg:git commit -a -m "update 1.txt"

删除本地文件后,需要重新提交

git commit -a -m "delete 1.txt"

查看历史操作命令

git reflog

可以通过git reset回退到历史版本,需要指定版本号

git reset --hard head~1

提交到本地库-----------再推送push