热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaWeb笔记之JDBC

JDBC连


不点蓝字,我们哪来故事?



数据库的操作步骤:

    1:导入数据库的驱动jar包----> 导入实现类

    2:加载驱动 -----> 告诉他我要连接哪个数据库

    3:获得连接------>让我和数据库发生关系

    4:获得预处理语句对象->让我 发送sql指令到数据库

    5:执行SQL命令;--->预处理语句对象.execute("SQL 命令行");

    6:释放资源 -------> 切断我和数据库的联系

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.Statement;
    import org.junit.Test;


    public class JDBCTest {

    @Test
    public void testJDBC() throws Exception {
    // 1.加载驱动
    //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    Class.forName("com.mysql.jdbc.Driver");//直接使用此方式:因为底层已经实现上面的步骤
    // 2:获得连接----->让java程序和数据库建立联系 . 让程序和数据库发生关系
    Connection cOnnection= DriverManager.getConnection("jdbc:mysql://IP地址:端口号(默认3306)/数据库的名字", "root", "root");
    // 3:获得预处理语句对象-->让java发送SQL语句到数据库
    Statement statement = connection.createStatement();
    // 4.执行需要执行的SQL语句
    statement.execute("create table girl(id int , name varchar(20),age int);");
    // 4:释放资源
    statement.close();
    connection.close();
    }
    }

    如何找到你要操作的数据集库:

        写死 jdbc:不同的数据库的厂商名://ip地址:端口号/数据库的库名

        操作mysql方式1:jdbc:mysql://localhost:3306/数据库的库名

        操作mysql方式2:jdbc:mysql://127.0.0.1:3306/数据库的库名

    如果 操作的数据库在本机 ,并且数据库的端口号是 3306

        可以简写 方式:jdbc:mysql:///数据库的库名


    抽取工具类:DAO规范的设计

    规范DAO组件的类名以及包名.    域名倒写.模块名.组件名----> cn.wolfcode.smis

        1.定义domain包以及类名(操作DAO都是去操作一张表,表应该对应着一个javabean, 取一个特殊的名字domain)

            cn.wolfcode.smis.domain

            Student.java

    2.定义DAO包以及DAO接口.

        cn.wolfcode.smis.dao

            IxxxDAO---> XXX表示domain.

            IStudentDAO.java

    3.定义DAO实现类的包以及实现类

        cn.wolfcode.smis.dao.impl

            StudentDAOImpl.java

    4.测试类

        cn.wolfcode.smis.test

            StudentDAOImplTest.java

    5.工具类

        cn.wolfcode.smis.util

            JDBCUtil.java


    规范的开发步骤---完成保存操作:

        1.创建数据库表.

        2.根据数据库表创建对应的domain包和类.

            注意:表的列的名字和类型与类的属性名和类型要一一匹配.

        3.通过domain来创建DAO包以及接口.

        4.根据接口生成实现类.

        5.根据接口/实现类生成测试类.完成测试的代码.

        6.实现一个方法,测试一个方法,测试通过,再写写一个方法.


    预编译语句对象-PreparedStatement:

    预编译语句对象-PreparedStatement:

    PreparedStatement是静态语句对象的子类.所以,父类中的所有的方法都可以调用到.但是一般我们不会调用.调用自己特有的方法.

    预编译语句对象是通过带有占位符的SQL模板来创建对象的.

        SQL模板:带有占位符?的SQL.相同的操作,SQL语句其实是一样的,仅仅是参数不一样而已.

        参数确定不了,使用占位符?来表示.

    常见API:

        1. 获取预编译语句对象.

        使用数据库连接对象:

    PreparedStatement prepareStatement(String sql); 传递的是SQL模板,有占位符

    2.在执行SQL之前,一定要给占位符设置值.

        void setObject(int parameterIndex,Object x):

            parameterIndex: 参数索引,在JDBC中,索引是从1开始的.

    3.执行SQL命令:

        注意,不要调用父类带有参数的方法.


    DQL操作:增删改

    在JDK中,把如何解析结果集的操作,封装到了一个对象中.ResultSet.

    需求:

        1.查询id为10的学生信息

        2.查询所有的学生信息.

    ResultSet对象:

        把如何解析结果集的过程封装成了对象.

        boolean next(): 往下移动一行,如果返回true,表示有数据,否则没有数据.要获取数据,一定要调用next方法.

        Object getObject(int columnIndex): 根据列的位置来取数据.索引从1开始.

        Object getObject(String columnLabel): 根据列名来获取数据

    优化:

    1.连接数据库四要素重复写很多遍(抽取到公共的位置,只写一遍).

    2.Class.forName加载字节码,字节码只会加载一次(使用静态代码块去加载注册驱动).

    3.硬编码.(连接数据库四要素).

    4.代码重复(DML操作, DQL操作).

    5.每次获取数据库连接对象,用完直接就关闭了.浪费.


    代码:

    配置文件:

    符号javaBean的Student类:

    DAO接口的定义:

    接口的测试类:

    JDBC的工具类:

      package cn.wolfcode.smis.util;


      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Properties;


      //工具类
      public class MyJDBCUtil {
      // 私有化构造器
      private MyJDBCUtil() {
      }


      static Properties p = new Properties();
      // 静态代码块
      static {
      try {
      // 加载配置文件
      p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("pd.properties"));
      // 加载驱动器
      Class.forName(p.getProperty("driverClassName"));
      } catch (Exception e) {
      e.printStackTrace();
      }
      }


      // 获得连接对象
      public static Connection getConnection() {
      Connection cOnnection= null;
      try {
      cOnnection= DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"),
      p.getProperty("password"));
      } catch (Exception e) {
      e.printStackTrace();
      }
      return connection;
      }


      // 关闭资源
      public static void close(Connection connection, Statement statement) {
      try {
      if (statement != null) {
      statement.close();
      }
      } catch (SQLException e) {
      e.printStackTrace();
      }
      try {
      if (connection != null) {
      connection.close();
      }
      } catch (SQLException e) {
      e.printStackTrace();
      }


      }


      // 重载关闭资源
      public static void close(Connection connection, Statement statement, ResultSet resultSet) {
      try {
      if (statement != null) {
      statement.close();
      }
      } catch (SQLException e) {
      e.printStackTrace();
      }
      try {
      if (connection != null) {
      connection.close();
      }
      } catch (SQLException e) {
      e.printStackTrace();
      }
      try {
      if (resultSet != null) {
      resultSet.close();
      }
      } catch (SQLException e) {
      e.printStackTrace();
      }


      }


      }

      接口的实现类:

        package cn.wolfcode.smis.dao.impl;


        import java.sql.Connection;
        import java.sql.PreparedStatement;
        import java.sql.ResultSet;
        import java.util.ArrayList;
        import java.util.List;


        import cn.wolfcode.smis.dao.IStudentDAO;
        import cn.wolfcode.smis.domain.Student;
        import cn.wolfcode.smis.util.MyJDBCUtil;


        public class StudentDAOImpl implements IStudentDAO {


        @Override
        public void insert(Student student) {
        // 获得连接对象
        Connection cOnnection= MyJDBCUtil.getConnection();
        // 获得预编译对象
        PreparedStatement statement = null;
        try {
        statement = connection.prepareStatement("insert into student(id,name,age) values(?,?,?)");
        // 设置站位符
        statement.setObject(1, student.getId());
        statement.setObject(2, student.getName());
        statement.setObject(3, student.getAge());
        // 执行
        statement.execute();
        } catch (Exception e) {
        e.printStackTrace();
        } finally {
        // 关闭资源
        MyJDBCUtil.close(connection, statement);
        }
        }


        @Override
        public void delete(Long id) {
        // 获得连接对象
        Connection cOnnection= MyJDBCUtil.getConnection();
        // 获得预编译对象
        PreparedStatement statement = null;
        try {
        statement = connection.prepareStatement("delete from student where id = ?");
        // 设置站位符
        statement.setObject(1, id);
        // 执行
        statement.execute();
        } catch (Exception e) {
        e.printStackTrace();
        } finally {
        // 关闭资源
        MyJDBCUtil.close(connection, statement);
        }
        }


        @Override
        public void update(Student student) {
        // 获得连接对象
        Connection cOnnection= MyJDBCUtil.getConnection();
        // 获得预编译对象
        PreparedStatement statement = null;
        try {
        statement = connection.prepareStatement("update student set name = ? ,age = ? where id = ?");
        // 设置站位符
        statement.setObject(1, student.getName());
        statement.setObject(2, student.getAge());
        statement.setObject(3, student.getId());
        // 执行更新方法
        statement.executeUpdate();
        } catch (Exception e) {
        e.printStackTrace();
        } finally {
        // 关闭资源
        MyJDBCUtil.close(connection, statement);
        }
        }


        @Override
        public Student selectOne(Long id) {
        // 获得连接对象
        Connection cOnnection= MyJDBCUtil.getConnection();
        // 获得预编译对象
        PreparedStatement statement = null;
        Student student = null;
        try {
        statement = connection.prepareStatement("select * from student where id = ?");
        // 设置站位符
        statement.setObject(1, id);
        // 执行查询,返回结果集
        ResultSet resultSet = statement.executeQuery();
        if (resultSet.next()) {// 结果集中有元素
        // 得到结果集中的元素---->结果集中是一个个字段对应的值,听过字段名获得值,然后创建个对象返回
        Object name = resultSet.getObject("name");
        Object age = resultSet.getObject("age");
        // 创建对象
        student = new Student(id, (String) name, (Integer) age);
        }
        } catch (Exception e) {
        e.printStackTrace();
        } finally {
        // 关闭资源
        MyJDBCUtil.close(connection, statement);
        }
        return student;
        }


        @Override
        public List selectAll() {
        // 创建List
        List list = new ArrayList<>();
        // 获得连接对象
        Connection cOnnection= MyJDBCUtil.getConnection();
        // 获得预编译对象
        PreparedStatement statement = null;
        try {
        statement = connection.prepareStatement("select * from student");
        // 执行查询,返回结果集
        ResultSet resultSet = statement.executeQuery();
        // if (resultSet.next()) {// 结果集中有元素
        // 用while循环将结果集中所有的元素取出来
        while (resultSet.next()) {
        // 得到结果集中的元素---->结果集中是一个个字段对应的值,听过字段名获得值,然后创建个对象返回
        Object id = resultSet.getObject("id");
        Object name = resultSet.getObject("name");
        Object age = resultSet.getObject("age");
        // 创建对象并将对象添加进list中
        list.add(new Student((Long) id, (String) name, (Integer) age));
        }
        } catch (Exception e) {
        e.printStackTrace();
        } finally {
        // 关闭资源
        MyJDBCUtil.close(connection, statement);
        }
        return list;


        }


        }

        上述代码依然有重复:使用模板方法可再进行优化。



        注入问题:经典案例登录安全问题;

          @Test
          public void testLogin() throws Exception {
          // 模拟账户的登录,理解 statement和preparestatement的区别
          String username = "will";
          // String password = "123456";
          // 注入问题
          String password = "' or '1'='1";
          // loginByStatement(username, password);
          // loginByPrepareStatement(username, password);
          loginByPrepareStatement1(username, password);
          }


          // 没有使用预处理语句对象:不安全 String password = "' or '1'='1";时可以屏蔽SQL语句的语义。导致成功登录
          private void loginByStatement(String username, String password) throws Exception {
          // 验证 username 和 password 在数据库中的表 是否存在这一条数据
          Connection cOnnection= JDBCUtil.getConnection();
          Statement statement = connection.createStatement();
          String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
          ResultSet resultSet = statement.executeQuery(sql);
          if (resultSet.next()) {
          System.out.println("登录成功");
          } else {
          System.out.println("账户或者密码错误,登录失败");
          }
          JDBCUtil.close(connection, statement, resultSet);
          }


          // 模拟登录案例--->使用预处理对象:安全
          private void loginByPrepareStatement1(String username, String password) throws Exception {
          // 把参数和数据库中的客户信息对比,相同才能登录成功
          // 1连接数据库
          Connection cOnnection= JDBCUtil.getConnection();
          // 2获得预处理语句对象
          PreparedStatement statement = connection
          .prepareStatement("select * from user where username = ? and password = ?");
          // 2.1设置占位符
          statement.setObject(1, username);
          statement.setObject(2, password);
          // 3查询结果
          ResultSet resultSet = statement.executeQuery();
          // 判断数据库中是否有这条用户数据
          if (resultSet.next()) {
          System.out.println("登录成功!");
          } else {
          System.out.println("账户不存在!登录失败!!");
          }
          // 关闭资源
          JDBCUtil.close(connection, statement, resultSet);
          }


          事务:经典案例,转账安全问题。

          期望结果:如果转账成功,那么数据发生变化.如果转账失败,那么账户余额不应该改变,应该还是转账之前的状态.

          上面这种操作,就是数据库中的事务操作.


          事务(Transaction,简写为tx):

              在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。

          为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:

              当每个逻辑操作单元全部完成时,数据的一致性可以保持,

              而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。


          事务的操作:

              先定义开始一个事务,然后对数据作修改操作,这时如果提交(commit),这些修改就永久地保存下来,如果回退(rollback),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。

              事务:指构成单个逻辑工作单元的操作集合

              事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态

          说白了:

              1.需要把多个操作放在一起作为一个整体.

              2.全部成功,才叫成功,否则一个失败,全部都失败.

          事务的ACID属性:

          1. 原子性(Atomicity):原子在化学中,是最小单位,不可以再分割了.

              原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 

          2. 一致性(Consistency):保证数据的完整性.

              事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)

          3. 隔离性(Isolation):

              事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

          4. 持久性(Durability):

              持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响


          事务相关的细节:

              1):默认情况下,事务在执行完DML操作就自动提交.

              2):查询操作,其实是不需要事务的.但是,一般的,我们在开发中都把查询放入事务中.

              3):开发中,代码完全正确,没有异常,但是就是数据库中数据不变.

          意识:可能没有提交事务.

              4):在MySQL中,只有InnoDB存储引擎支持事务,支持外键,MyISAM不支持事务.

              5):以后事务我们不应该在DAO层处理,应该在service层控制(提出).

              6):事务在讲解框架和项目的时候都会再讲.


          事务操作,在一次连接中进行多次操作.需要将多个操作放在一个整体中,就需要使用事务.

              操作模板:

            try{
            // 手动开启一个事务
            conn.setAutoCommit(false);
            操作1...
            操作2...
            操作N...
            // 全部成功,提交事务
            conn.commit();
            } catch(Exception e){
            // 异常代码处理
            // 如果失败,需要回滚
            conn.rollback();
            } finally{
            // 关闭资源
            }

            注意:

                只有在调用了commit方法之后,数据库才会真正的发生变化.全部成功,调用commit方法.如果失败了一定要调用rollback方法.

                原因:在开启事务的时候,就有一个事务锁的存在.必须要调用commit或者rollback才可以释放.

              @Test
              public void testTransaction() {
              // 模拟转账的效果 西门吹雪 转账给 菠萝吹雪 1000钱。如果转账过程中出现异常,则金额不应该发生改变。// 1:先判断 西门吹雪 有没有钱
              Connection cOnnection= JDBCUtil.getConnection();
              PreparedStatement statement = null;
              ResultSet resultSet = null;
              try {
              // 取消自动提交,让完整的事物执行完后再进行收动提交
              connection.setAutoCommit(false);
              statement = connection.prepareStatement("select * from account where name = '西门吹雪' and balance >= 1000");
              resultSet = statement.executeQuery();
              // 只有金额足够才能转账
              if (resultSet.next()) {
              System.out.println("开始转账");
              // 西门吹雪的 钱 减少1000
              statement.executeUpdate("update account set balance = balance - 1000 where name = '西门吹雪'");
              // int ret = 10 0;//制造异常---->如果转账过程中出现异常,则金额不应该发生改变。// 菠萝吹雪金莲的钱 增加 1000
              statement.executeUpdate("update account set balance = balance + 1000 where name = '菠萝吹雪'");


              // 手动提交事务
              connection.commit();
              } else {
              System.out.println("没钱!!!,我的二叔是公安局长");
              }
              } catch (Exception e) {
              System.out.println("转账异常中断!");
              e.printStackTrace();
              // 回退:出现异常时,将事务回退到最开始的状态。---->只有出现异常中断时才需要回退,所以放到catch语句中
              try {
              connection.rollback();
              } catch (SQLException e1) {
              e1.printStackTrace();
              }
              } finally {
              // 关闭资源:无论如何最后都要关闭资源
              JDBCUtil.close(connection, statement, resultSet);
              }
              }


              获得自动生成的主键:获得注册后信息

              1.设置一个标记,给数据库说,我要自动生成的主键.

                  在获取预编译语句对象的时候,传递要获取的标记.

                  Statement.RETURN_GENERATED_KEYS .

              2.获取自动生成的主键.

                // 模拟注册后显示id和注册时的信息
                @Test
                public void testInsert() throws Exception {
                // 注册时的输入的信息
                String username = "天河首富";
                String password = "lh0030";
                // 获得连接对象
                Connection cOnnection= JDBCUtil.getConnection();
                String sql = "insert into user (username,password) values(?,?)";
                // 获得预处理语句对象
                PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);// 获得自动生成的主键
                // 设置占位符的值
                statement.setObject(1, username);
                statement.setObject(2, password);
                // 执行更新操作
                statement.executeUpdate();
                // 把自动生成的主键放到了一个结果集对象中
                ResultSet keys = statement.getGeneratedKeys();
                // 如果插入成功就返回主键和插入的信息
                if (keys.next()) {
                // 获取自动生成的主键
                long id = (long) keys.getObject(1);
                System.out.println(id + " " + username + " " + password);
                }
                // 关闭资源
                JDBCUtil.close(connection, statement, keys);
                }


                数据库连接池:

                目前我们操作数据库的方式:

                    1.获取数据库连接对象.

                    2.执行SQL命令

                    3.解析结果集.

                    4.关闭资源(结果集对象,预编译语句对象,数据库连接对象)

                执行完了一个SQL命令之后,就会关闭数据库连接对象.问题就出在这里.


                为什么必须使用数据库连接池:

                    普通的JDBC数据库连接(Connection对象)使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间),数据库的连接是比较昂贵的(创建的成本比较大)。

                    需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。

                    数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。

                    对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。

                    这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃.


                说白了:

                    当前的操作数据库的方式是,花费了大量的资源和时间创建的非常昂贵的数据库连接对象,使用一次之后就关闭了.主要存在的问题是,没有充分使用到数据库连接对象.使用连接池来解决这个问题.

                    

                池化技术:管理资源对象,达到最高的效率.

                    池化技术能够减少资源对象的创建次数,提高程序的性能,特别是在高并发下这种提高更加明显。使用池化技术缓存的资源对象有如下共同特点:

                     1,对象创建时间长;

                    2,对象创建需要大量资源;3,对象创建后可被重复使用。比如thread,connection等对象都具有上面的几个共同特点。


                在Java中,连接池使用javax.sql.DataSource接口来表示连接池.

                DataSource(数据源)和连接池(Connection Pool)是同一个.

                注意:DataSource仅仅只是一个接口,由各大服务器厂商来实现(Tomcat,JBoss).


                常用的DataSource的实现:

                     DBCP:  Spring框架推荐的

                     druid: 阿里巴巴的连接池(号称Java语言中性能最好的连接池)德鲁伊.

                ================================================

                使用连接池和不使用连接池的区别在哪里?

                如何获取Connection对象:

                未使用连接池:

                  Connection cOnn= DriverManager.getConnection(url,username,password);

                  使用了连接池:

                    datasource对象.getConnection();// 返回的连接对象已经是一个功能增强的连接对象了.

                     只要获取了Connection对象,接下来的操作和以前是一模一样的.

                     关键在于:如何创建DataSource对象.

                    如何释放Connection对象(Connection对象.close()):

                    未使用连接池: 是和数据库服务器断开.

                    使用了连接池: 还给连接池.


                    使用数据库连接池创建JDBC的工具类:

                    方式1:

                      import java.io.IOException;
                      import java.sql.Connection;
                      import java.sql.DriverManager;
                      import java.sql.ResultSet;
                      import java.sql.SQLException;
                      import java.sql.Statement;
                      import java.util.Properties;


                      //JDBC工具类
                      public class JDBCUtil {
                      // 私有化构造器
                      private JDBCUtil() {
                      }


                      static Properties p = new Properties();
                      static {
                      try {
                      p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
                      Class.forName(p.getProperty("driverClassName"));


                      } catch (IOException e) {
                      System.err.println("你的配置文件加载不到");
                      e.printStackTrace();
                      } catch (ClassNotFoundException e) {
                      e.printStackTrace();
                      }


                      }


                      // 获得数据库的连接对象
                      public static Connection getConnection() {
                      // 获得 资源文件夹中的db.properties文件中数据库连接信息
                      Connection cOnnection= null;
                      try {
                      cOnnection= DriverManager.getConnection(p.getProperty("url"), p.getProperty("username"),
                      p.getProperty("password"));
                      } catch (SQLException e) {
                      e.printStackTrace();
                      }
                      return connection;
                      }
                      }

                      方式2:

                        import java.io.IOException;
                        import java.sql.Connection;
                        import java.sql.ResultSet;
                        import java.sql.SQLException;
                        import java.sql.Statement;
                        import java.util.Properties;
                        import javax.sql.DataSource;


                        import com.alibaba.druid.pool.DruidDataSourceFactory;//德鲁伊的jar包


                        //JDBC工具类
                        public class JDBCUtil {
                        // 私有化构造器
                        private JDBCUtil() {
                        }


                        static DataSource source = null;
                        static {
                        try {
                        Properties p = new Properties();
                        p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
                        //这种方式创建对象
                        source = DruidDataSourceFactory.createDataSource(p);
                        } catch (IOException e) {
                        e.printStackTrace();
                        } catch (Exception e) {
                        e.printStackTrace();
                        }
                        }


                        // 获得数据库的连接对象
                        public static Connection getConnection() {
                        Connection cOnnection= null;
                        try {
                        cOnnection= source.getConnection();
                        } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        }
                        return connection;
                        }
                        //省略关流操作,关流没变
                        }


                        ————  e n d ————


                        觉得文章不错,欢迎点在看转发,长按识别二维码关注公众号 java学途,了解更多精彩。




                        点在看,让更多看见。




                        推荐阅读
                        • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
                        • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
                        • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
                        • 本文介绍了在sqoop1.4.*版本中,如何实现自定义分隔符的方法及步骤。通过修改sqoop生成的java文件,并重新编译,可以满足实际开发中对分隔符的需求。具体步骤包括修改java文件中的一行代码,重新编译所需的hadoop包等。详细步骤和编译方法在本文中都有详细说明。 ... [详细]
                        • OpenMap教程4 – 图层概述
                          本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
                        • Nginx使用AWStats日志分析的步骤及注意事项
                          本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
                        • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
                          本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
                        • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
                          本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
                        • Linux重启网络命令实例及关机和重启示例教程
                          本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
                        • 开发笔记:加密&json&StringIO模块&BytesIO模块
                          篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
                        • android listview OnItemClickListener失效原因
                          最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
                        • web.py开发web 第八章 Formalchemy 服务端验证方法
                          本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
                        • 负载均衡_Nginx反向代理动静分离负载均衡及rewrite隐藏路径详解(Nginx Apache MySQL Redis)–第二部分
                          nginx反向代理、动静分离、负载均衡及rewrite隐藏路径详解 ... [详细]
                        •     这里使用自己编译的hadoop-2.7.0版本部署在windows上,记得几年前,部署hadoop需要借助于cygwin,还需要开启ssh服务,最近发现,原来不需要借助cy ... [详细]
                        • 目录1、将mysql数据导出到SQL文件中(数据库存在的情况)2、将现有的sql文件数据导入到数据库中(前提数据库存在) 3、利用Navicat导出SQL文件和导入SQL文件1)从 ... [详细]
                        author-avatar
                        wwaadd4055
                        这个家伙很懒,什么也没留下!
                        PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
                        Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有