【JavaWeb】知识点总结(三)—— JDBC

一、 JDBC

1.1 使用命令行直接建立数据库和表

1. 使用命令行

打开开始菜单找到mysql-点击打开命令行-输入使用的密码:123456(机房使用root)

2. 建立数据库

-使用命令create建立数据库:“create database shop(数据库名); ”注意每一句命令后面使用分号结束-使用“use shop”打开数据库(这一句比较特殊不用加分号,不输入这句没办法打开数据库使用来创建表)

3. 创建数据表

-创建表:“create table t_user(id int auto_increment primary key,username varchar(20) not null,password varchar(20) not null,age int(3) default 0,description text);”

使用id自动增长来标识id(如果字段太长可以使用分号换行输入,只要不使用分号就会继续输入) ;char和varchar的区别在于char是定长的,varchar是变长的,char如果只有6个字节,则其余的会用空格补齐,而varchar是设置最长的字节,有多少字节就是多少字节,不会加空格补齐;auto_increment 是设置自动增长;not null不空属性,必须要有,这个属性一般是在程序实现验证不使用数据库验证,避免插入为空时不能往数据库插入导致出错没办法控制;int的默认长度是11;default 0是设置缺省值为0,没有输入时默认为0。

Ok就是提示成功了,error就要重新查看代码问题(这里直接使用键盘的上下箭头,可以直接重新调出代码,直接修改有问题的语句就可以了)

4. 查看

-剩下数据的操作就在程序里面去操作了-使用“show tables;”查看表建好没有-使用“desc t_user;”查看表的结构属性(字段,长度等); “select * from t_user; ”查看表的具体数据

5. 完整代码

  1. 打开mysql5.7,输入密码:“123456”
  2. “create database shop(数据库名);  ”  //建立数据库
  3. “use shop ”//打开使用数据库
  4. “create table t_user(id int auto_increment primary key,username varchar(20) not null,password varchar(20) not null,age int(3) default 0,description text);” //建表
  5. show tables;//查看表有哪些
  6. desc t_user;//查看表的结构
  7. select * from t_user; //查看表的数据

2.2 JDBC项目

新建项目jdbc-直接点击完成-配置服务器-调试,访问http://localhost:8080/jdbc检查项目启动-打开index.jsp,修改pageEncoding为UTF-8-编写项目:

2.1. 数据库访问的步骤

2.1.1 导入数据库驱动jar包(将jar包复制到WEB-INF/lib文件夹)

导入jar有很多种方式可以创建自己的userlib,我们这里使用的jar包只适用于5.几的数据库,不适合其他8.几的数据库,我们将文件ctrl+c ctrl+v到lib下面,这里成功后会产生一个Web App Libraries,下面的jar包是无法展开的,但我们可以通过这个文件查看jar包的结构;如果没有出现上面的文件,可以右键jar包,点击Build Path,Add to Build Path来添加

2.1.2 加载驱动

使用Class.forName(className)把驱动器类加载到内存中去,就可以使用它了,className是驱动器名称,不同的数据库包括mysql不同版本的名称都比一样,“域名的倒序.产品名.类名”:

Class.forName("com.mysql.jdbc.Driver");

2.1.3 获得连接

因为我们要使用驱动,所以需要导入mysql包,所有mysql的包都是在java.sql.*下面,所以我们在import中导入或者在写一条page指令,所有数据库访问的包都在这下面(在servlet中导包方式就不一样,因为有实现类和实现接口,导的时候就要导导接口,而不是实现类,因为要注意面向接口编程)

<%@ page language="java" import="java.util.*,java.sql.*" page

Encoding="UTF-8"%>

获得数据库的连接Connection:

   String url = "jdbc:mysql://localhost:3306/shop";

   String user = "root";

   String password = "123456";

Connection connection = DriverManager.getConnection(url, user, password);

使用的是访问数据库唯一的类,选择有三个参数的get方法,并在上面定义这三个属性:

连接的url:http协议+域名/IP地址(端口号)+数据库名称;不同的数据库有不同的url,修改这三个属性可以使用不同的数据库“jdbc:mysql://”就是jdbc的协议,所有的数据库访问都是这个,只是mysql有变化;mysql默认端口是3306;http协议+域名(IP地址+端口号)访问到机器,然后再加上数据库的名称:“String url = "jdbc:mysql://localhost:3306/shop";”;局域网里面直接IP地址就可以了,互联网要访问数据库需要域名,本地就使用localhost;连接的用户user,连接的密码password

2.1.4 获得句子对象(Statement)

Statement st = connection.createStatement();

2.1.5 通过句子对象执行SQL语句

          三个方法: execute(sql) 几乎不用;executeQuery(sql) 用来执行select语句,只要是select就使用这个,其它全部是executeUpdate,executeQuery(sql)返回一个ResultSet对象(结果集),查询的结果数据都存放在它里面;executeUpdate(sql) 用来执行除select语句之外的SQL语句,增加、删除、修改,返回值与前面不同,返回的是一个整数,表示SQL语句影响的记录条数。

String sql = "insert into t_user(username,password,age,description) value('user1','123456',20,'test')";

int count = st.executeUpdate(sql);

if(count==1){

     out.print("数据插入成功");

}else{

     out.print("数据插入失败");

}

2.1.6 完整代码及效果

  <body>

    <%

        /**

           1.导入数据库驱动jar包(将jar包复制到WEB-INF/lib文件夹)

        */

        //2.加载驱动  

        Class.forName("com.mysql.jdbc.Driver");

       //3.获得连接Connection

       String url = "jdbc:mysql://localhost:3306/shop";

       String user = "root";

       String password = "123456";

       Connection connection = DriverManager.getConnection(url, user, password);

       //4.获得句子对象(Statement)

       Statement st = connection.createStatement();

       //5.通过句子对象执行SQL语句

       //三个方法 execute(sql) 几乎不用

       //executeQuery(sql) 用来执行select语句

       //executeUpdate(sql) 用来执行除select语句之外的SQL语句,返回一个整数,表示SQL语句影响的记录条数

       String sql = "insert into t_user(username,password,age,descript

ion)value('user1','123456',20,'test')";

        int count = st.executeUpdate(sql);

        if(count==1){

           out.print("数据插入成功");

        }else{

           out.print("数据插入失败");

        }

     %>

  </body>

导完了包之后一定要重启服务器,再访问http://localhost:8080/jdbc,显示“数据插入成功”,完成后还要在命令行输入“select * from t_user;”查看表格是否增加了新的数据

2.2 编写项目

复制index.jsp页面命名为list.jsp,用来显示插入的表格数据,复制后如果出现乱码,ctrl+A重新粘贴一遍-除了sql语句其余都是一样的,我们从第5步重新开始编写:

2.2.1 executeQuery(sql)查询返回ResultSet对象

使用executeQuery(sql)来查询,返回ResultSet对象(其实是接口,返回的是它的子对象,这里也不牵涉导包的问题,我们前面已经一次性导完了,后面编写servlet代码时才考虑按需引入,如果这里编写时出现红线,可能前面代码引入出错,可以重新引入)

2.2.1 ResultSet对象的方法的使用

       String sql = "select * from t_user";

   ResultSet rs = st.executeQuery(sql);

rs代表我们所有存储的记录都在这个对象里面,rs这个对象有next()方法,用于查询下一条记录;rs有一个指针,查询时它是指向第一条记录之前,不能直接访问,它是指向第一条之前的位置;

使用next()方法有两个作用:它将我们的指针移动到下一条,并返回一个逻辑值,表示是否还有记录,如果指针指向一条记录就返回true,如果指向最后一条,没有记录就返回false,所以可以使用这种方法引入指针,并判断还有无记录;

  1. 现在要把所有数据都找出来,可以使用while循环,先while(next()),一调用这个就指向第一条数据,返回true进入循环读数据;
  2. 然后如果我们要做登录操作,实际上还是根据用户名和密码去数据库查询,返回一个rs,只有两种情况“成功”和“失败”,成功我们判断用户名和密码都正确了,查找到一条记录,失败了就一条记录都没有,我们使用if(rs.next())判断就可以了,看他返回真or假来判断登录情况;
  3. 如果我们要查询一个表里面有多少条记录使用:“select count(*) from t_user;”现在我们要取count值,可以调用rs的方法,但是它指针还是放在第一条记录之前的,一定要先调用next()方法后就可以取出这个记录了,如果一条没有就返回查询为0.          

rs.next();

return rs.getInt(1);

2.2.3 表格显示数据

         <table>

            <tr>

               <th>ID</th>

               <th>用户名</th>

               <th>密码</th>

               <th>年龄</th>

               <th>描述</th>

            </tr>

         </table>

    <style>

       table{

           width: 40%;

           margin:100px auto;

           border:1px solid #ccc;

       }

</style>

这样没有表格中间的竖线,使用给th td单独加边框,

       th,td{

           border:1px solid #ccc;

    }

使用border-collapse: collapse;添加细线表格

我们使用rs一系列的get方法把字段取出来,根据不同类型来调用不同方法,这里有两个方法,整数的表示字段的顺序,从1开始,比如要取ID可以getInt(1),根据字段的顺序来判断,使用索引可以用来查字段的数量这种只有一个字段的数据,更加方便快捷;string就是使用字段的名称,getInt(“ID”);通常使用字符名称的方法,避免顺序错误或者添加字段后顺序更改,字段名称是不区分大小写的,与getParameter()不同

2.2.4 表格显示数据完整代码

    <style>

       table{

           width: 40%;

           margin:100px auto;

           border:1px solid #ccc;

           border-collapse: collapse;

       }

       th,td{

           border:1px solid #ccc;

       }

    </style>

  </head>



  <body>

    <%

        /**

           1.导入数据库驱动jar包(将jar包复制到WEB-INF/lib文件夹)

        */

        //2.加载驱动  

        Class.forName("com.mysql.jdbc.Driver");

       //3.获得连接Connection

       String url = "jdbc:mysql://localhost:3306/shop";

       String user = "root";

       String password = "123456";

       Connection connection = DriverManager.getConnection(url, user, password);

       //4.获得句子对象(Statement)

       Statement st = connection.createStatement();

       //5.通过句子对象执行SQL语句

       //三个方法 execute(sql) 几乎不用

       //executeQuery(sql) 用来执行select语句,返回一个ResultSet对象

       //executeUpdate(sql) 用来执行除select语句之外的SQL语句,返回一个整数,表示SQL语句影响的记录条数

       String sql = "select * from t_user";

       ResultSet rs = st.executeQuery(sql);

     %>

         <table>

            <tr>

               <th>ID</th>

               <th>用户名</th>

               <th>密码</th>

               <th>年龄</th>

               <th>描述</th>

            </tr>

            <%

               while(rs.next()){

            %>

            <tr>

               <td><%=rs.getInt("id") %></td>

               <td><%=rs.getString("username") %></td>

               <td><%=rs.getString("password") %></td>

               <td><%=rs.getInt("age") %></td>

               <td><%=rs.getString("description") %></td>

            </tr>    

<%} %>

         </table>

  </body>

</html>

2.2.5 注册页面reg.jsp

假设项目一进去到登录页面,但是这时没有用户,要先注册;我们点击注册输入信息,点击注册按钮就到UserServlet进行注册

2.2.6 登录页面login.jsp

登录和注册访问同一个servlet,只是传入了不同参数,现在访问都是使用的dopost方法,使用不同的参数判断是登录还是注册

2.2.8 Servlet

1. 新建Servlet

右键src新建servlet-包名以servlet结尾,类名首字母大写-点击下一步-修改映射路径-点击下一步-取消构造方法-点击完成

2. 将Connection定义为全局变量

因为都要访问数据库,所以将Connection其定义为全局变量,然后使用ctrl+shift+o导入包(注意一定要选择java.sql.Connection,这里不提倡使用*导入,我们用什么导什么)

3. 加载驱动

然后加载驱动:Class.forName("com.mysql.jdbc.Driver");输入完后会提示异常,处理异常有两种方法:抛给上级处理;或我们悬停鼠标有提示直接点击添加try/catch就自己添加处理

4. 获得连接

获得连接(如果复制前面的代码,记得把Connection的定义删除掉,因为前面已经有了全局定义了),ctrl+shift+o导入包,处理异常

5. 判断是登录还是注册

判断是登录还是注册:获取用户的参数(method,我们自己定义的method,不是说后面请求方式的method)

String method = request.getParameter("method");

这里编写if代码时,为了后续添加其他方法(例如修改、删除(doget),后续再添加分支就可以),就不将注册代码写到dopost里面,而是添加一个方法

     if("reg".equals(method)){

           reg(request,response);             

     }else if("login".equals(method)){

           //login(request,response);

}

6. 编写Reg方法:
(1)复制修改

我们直接复制dopost方法,修改名字为reg,然后使用request.getPara

Meter()获取信息,整形的要转换成整数;然后插入到数据库,使用组合sql语句

protected void reg(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String username = request.getParameter("username");

    String password = request.getParameter("password");

    int age = Integer.parseInt(request.getParameter("age"));

    String description = request.getParameter("description");

    String sql = "insert into t_user(username,password,age,

description)values('"+ username +"','" + password + "'," + age +",'" + description +"')" ;

}  

(2)Sql语句

获取sql语句,导包(一定要选sql的),处理异常(不要抛给上级处理,自己捕获就可以,使用try/catch)

       try {

           Statement st = connection.createStatement();

       } catch (SQLException e) {

           e.printStackTrace();

       }

执行sql语句,如果是1说明注册成功,跳转登陆页面登录,可以直接使用客户端跳转;失败打印一个注册失败,先获得使用printWriter,导包,然后输出信息,并且一定要输出编码才能输出正常的,

   Statement st = connection.createStatement();

   int count = st.executeUpdate(sql);

   if(count==1){

      response.sendRedirect("login.jsp");

   else{

      PrintWriter out = response.getWriter();

      response.setContentType("text/html");

      response.setCharacterEncoding("UTF-8");

      out.write("注册失败");

      out.flush();

      out.close();

}

(3)完整代码:

先获得所有参数,然后形成sql语句,然后把数据插入到数据库里面去,然后就成功了就可以跳转登录页面,失败则显示登录失败的信息,要执行要重启服务器,成功后跳转到登录页面后,要使用“select * from t_user;”查看数据库里面是否有该信息

    protected void reg(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

       String username = request.getParameter("username");

       String password = request.getParameter("password");

       int age = Integer.parseInt(request.getParameter("age"));

       String description = request.getParameter("description");

       String sql = "insert into t_user(username,password,age,description)values('"+ username +"','" +

                  password + "'," + age +",'" + description +"')" ;

       try {

           Statement st = connection.createStatement();

           int count = st.executeUpdate(sql);

           if(count==1){

              response.sendRedirect("login.jsp");

           }else{

              PrintWriter out = response.getWriter();

              response.setContentType("text/html");

              response.setCharacterEncoding("UTF-8");

              out.write("注册失败");

              out.flush();

              out.close();

           }

       } catch (SQLException e) {

           e.printStackTrace();

       }

    }  

7. 接口

三种接口:Statement<-PreparedStatement<-CallableStatement

Statement是最上面的接口,有两个子接口<-PreparedStatement可以执行带参数的sql语句,使用最多,比Statement多了三个方法,Statement说的有三个方法,而PreparedStatement多了三个不带sql参数的方法,创建时就需要去指定参数<-CallableStatement调用存储课程

8. 使用PreparedStatement重写reg
(1)重写reg

复制刚刚的reg方法,将reg重命名为reg1,粘贴使用PreparedStatement重写reg,删除values里面的内容,使用“?”代替,使用带参数的sql语句来写,导包选择java.sql的,创建对象时就要把sql语句传给它,后续的executeUpdate()方法就不带sql了,传参数相当于调用父类的方法了,“int count = pst.executeUpdate(); ”这里要特别注意不要传参数,不要就会使用到父类的方法,而父类的方法不能带“?”

//Statement st = connection.createStatement();

PreparedStatement pst = connection.prepareStatement(sql);

int count = pst.executeUpdate();

(2)给“?”赋值:

Prepared是准备,我们准备好后使用一系列set方法给它赋值,根据类型不同调用不同的方法,方法有两个参数,第一个是索引,从1开始,第二个是要赋的值

   pst.setString(1, username);

   pst.setString(2, password);

   pst.setInt(3, age);

pst.setString(4, description);

(3) 完整代码:

   //Statement<- PreparedStatement<- CallableStatement

   protected void reg(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

       String username = request.getParameter("username");

       String password = request.getParameter("password");

       int age = Integer.parseInt(request.getParameter("age"));

       String description = request.getParameter("description");

       String sql = "insert into t_user(username,password,age,description)values(?,?,?,?)";

       try {

          //Statement st = connection.createStatement();

          PreparedStatement pst = connection.prepareStatement(sql);

          pst.setString(1, username);

          pst.setString(2, password);

          pst.setInt(3, age);

          pst.setString(4, description);

          int count = pst.executeUpdate();//特别注意,不要传参数

          if(count==1){

              response.sendRedirect("login.jsp");

          }else{

              PrintWriter out = response.getWriter();

              response.setContentType("text/html");

              response.setCharacterEncoding("UTF-8");

              out.write("注册失败");

              out.flush();

              out.close();

          }

       } catch (SQLException e) {

          e.printStackTrace();

       }

   }  

9. 检查数据库用户名是否存在

我们获取到了用户,现在要检查数据库中用户是否存在,存在就不能让他注册,可以使用username去数据库查询,返回true就是存在,那找到一条记录就已经重复,不能注册;这种参数比较少的就不用使用到PreparedStatement;使用ResultSet导包要选java.sql的,然后处理异常:

    //判断用户名是否存在

    private boolean isExists(String username){

       String sql = "select * from t_user where username='"+ username +"'";

       try {

           Statement st = connection.createStatement();

           ResultSet rs = st.executeQuery(sql);

           if(rs.next()){

              return true;

           }else{

              return false;

           }

       } catch (SQLException e) {

           e.printStackTrace();

           return false;

       }

    }

使用,获取到数据后,使用if判断是否已经存在,存在就提示然后跳转到注册页面,我们存到了request里面,跳转也只能使用服务器端跳转了:

protected void reg(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

       String username = request.getParameter("username");

       String password = request.getParameter("password");

       int age = Integer.parseInt(request.getParameter("age"));

       String description = request.getParameter("description");

      

       if(isExists(username)){

           request.setAttribute("msg", "用户名已存在");

          request.getRequestDispatcher("reg.jsp").forward(request, response);

           return;

       }     

我们在reg.jsp页面可以把处理信息拿过来,告诉用户为什么还是在这个页面,使用${msg},错误提示不用管,就可以显示刚刚的信息,如果为空就什么都不显示;就跟request.getAttribute(name)是一个样的,但是request.getAttribute(name)这个方法需要我们判断是否为空,为空才不显示,这个就不需要判断,直接就可以显示信息:

也可以将其它用户填的值存起来,避免让用户再填一遍,把它保存起来,然后使用value填进去,判断这个值不为空,就填进去

  • 33
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值