今天这一篇写的是关于JDBC的内容。之前一直在学习mysql数据库,那数据库怎么和我们的程序相互交互呢,它们之间的桥梁就是JDBC。接下来让我们直接进入正题!

一、JDBC概述


1.1、JDBC简介

  JDBC全称为:Java DataBase Connectivity(java数据库连接)

  JDBC是SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范。

  JDBC是一组专门负责连接并操作数据库的标准,在整个JDBC 中实际上大量的提供的是接口。由数据库厂商提供,不同数据库其JDBC驱动程序是不同。

  JDBC与数据库驱动之间的关系:接口与实现的关系

1.2、JDBC操作的步骤

  在操作JDBC时,我们大概可以分成四个步骤来完成:

    1)加载数据库驱动程序,加载的时候需要将驱动程序配置到classpath之中

    2)连接数据库,通过Connection 接口和 DriverManager 类完成

    3)操作数据库,通过Statement、PreparedStatement、ResultSet 三个接口完成

    4)关闭数据库,在实际开发中数据库资源非常有限,操作完之后必须关闭

二、JDBC的一个类和三个接口


2.1、java.sql.Drivermanager类 :(注册驱动和创建连接)

  1)注册驱动

    DriverManager.registerDriver(new com.mysql.jdbc.Driver());

    这种我们不推荐使用:一是导致驱动被注册两次,二是强烈依赖数据库的驱动jar包

  2)与数据库建立连接

    static Connection getConnection(String url)

      URL:SUN公司与数据库厂商之间的一种协议

      jdbc:mysql://localhost:3306/Test
      协议 子协议     IP       :端口号 数据库

    DriverManager.getConnection("jdbc:mysql://localhost:3306/test?user=root&password=root");

    static Connection getConnection(String url, Properties info) 

      Properties info = new Properties();//要参考数据库文档
info.setProperty("user", "root");
     info.setProperty("password","root");

    static Connection getConnection(String url, String user, String password)

    试图建立到给定数据库 URL 的连接

    DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");

2.2、java.sql.Connection接口(一个连接)

  接口的实现在数据库驱动中,所有与数据库交互都是基于连接对象的。

  Statement  createStatement(); //创建操作sql语句的对象

  PreparedStatement  prepareStatement(sql);

2.3、java.sql.Statement接口:(操作sql语句,并返回相应结果的对象(小货车))

  接口的实现在数据库驱动中,用于执行静态 SQL 语句并返回它所生成结果的对象。

  ResultSet  executeQuery(String sql)   根据查询语句返回结果集。只能执行select语句。
     int     executeUpdate(String sql)   根据执行的DML(insert update delete)语句,返回受影响的行数。
  boolean    execute(String sql)    此方法可以执行任意sql语句。返回boolean值,表示是否返回ResultSet结果集。仅当执行select语句,且有返回结果时返回true, 其它语句都返回false。

2.4、java.sql.ResultSet接口:(结果集(客户端存表数据的对象))

  1)封装结果集

    提供一个游标,默认游标指向结果集第一行之前
    调用一次next(),游标向下移动一行
    提供一些get方法

  2)封装数据的方法

  Object getObject(int columnIndex);   根据序号取值,索引从1开始
  Object getObject(String ColomnName);   根据列名取值   boolean next()   将光标从当前位置向下移动一行
  int getInt(int colIndex)      以int形式获取ResultSet结果集当前行指定列号值
  int getInt(String colLabel)    以int形式获取ResultSet结果集当前行指定列名值
  float getFloat(int colIndex)   以float形式获取ResultSet结果集当前行指定列号值
  float getFloat(String colLabel) 以float形式获取ResultSet结果集当前行指定列名值
  String getString(int colIndex)  以String 形式获取ResultSet结果集当前行指定列号值
  String getString(String colLabel) 以String形式获取ResultSet结果集当前行指定列名值
  Date getDate(int columnIndex); 
  Date getDate(String columnName);
  void close()   关闭ResultSet 对象

    MySQL数据库中的数据类型和Java中的数据类型对应关系:

        

  3)可移动游标的方法

  boolean next()  将光标从当前位置向下移一行。
  boolean previous() 将光标移动到此 ResultSet 对象的上一行。
  boolean absolute(int row) 参数是当前行的索引,从1开始。根据行的索引定位移动的指定索引行。
  void afterLast() 将光标移动到末尾,正好位于最后一行之后。
  void beforeFirst() 将光标移动到开头,正好位于第一行之前。

三、细说JDBC连接过程


连接数据库所需要的信息:

  驱动类的全名:com.mysql.jdbc.Driver

  连接数据库的URL:jdbc:mysql://ip:port/db_name?useSSL=true

  用户名:user

  密码:password

3.1、注册驱动

  注册驱动的方式总共有四种:

    第一种:Class.forName("com.mysql.jdbc.Driver");  这种是我们最常用的

    第二种:DriverManager.register(new com,mysql.jdbc.Driver());  

    第三种:System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver);

    第四种:在jvm运行中配置参数 -D jdbc.drivers=com.mysql.jdbc.Driver

3.2、获取(Connection)连接对象

  1)连接MySQL数据库我们需要的数据

    IP、Port、user、password、protocol、schema  

  2)第一种获取Connection对象方式

    String url = protocol+ip+":"+port+"/"+schema+"?user="+user+"&password="+password;
    Connection conn = DriverManager.getConnection(url);

  3)第二种获取Connection的方式    

  Connection conn = DriverManager.getConnection(url,properties);

  3)第三种获取Connection的方式   

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

3.3、获取Statement对象

  Statement stat=conn.createStatement();

3.4、执行SQL语句  

  stat.executeQuery(sql);、stat.execute(sql);、stat.executeUpdate(sql); 

3.5、如果有结果集(ResultSet),则处理结果集

3.6、关闭Statement和Connection的连接,避免计算机资源消耗   

  stat.close();
  conn.close(); 

四、Statement和PrepareStatment


4.1、关系与区别

  关系:PreparedStatement继承自Statement,都是接口。

  区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高。

4.2、实例显示区别

  1)背景:有一个数据库,里面有个tb_users表,有id,name和passwd三列,然后按照给定的name和password值进行数据查询。

    使用Statement查询:

    sql="select * from tb_users where name='"+name+"' and passwd='"+passwd+"'";
    stmt=conn.createStatement();
    rs=stmt.executeQuery(sql);

    使用PrepareStatement查询:

    sql="select * from tb_users where username=? and userpwd=?";
    pstmt=conn.prepareStatement(sql);
    pstmt.setString(,name);
    pstmt.setString(,passwd);
    rs=pstmt.executeQuery();

  2)有一个数据库表tb_books,包含id,name,author,price四列,向该表中插入数据。

    使用Statement:

    sql="insert into tb_books(id,name,author,price) values('"+id+"','"+name+"',"+author+",'"+price+"')";
    stmt = conn.createStatement();
    stmt.executeUpdate(sql);

    使用PrepareStatement:

    String sql="insert into book(id,name,author,price) values (?,?,?,?)";
    pstmt = conn.prepareStatement(sql);
    pstmt.setString(,var1);
    pstmt.setString(,var2);
    pstmt.setString(,var3);
    pstmt.setString(,var4);
    pstmt.executeUpdate();

4.3、PrepareStatement的优点

  1)PrepareStatement可以提高代码的可读性

  2)ParperStatement提高了代码的灵活性和执行效率

    PrepareStatement接口是Statement接口的子接口,他继承了Statement接口的所有功能。它主要是拿来解决我们使用Statement对象多次执行同一个SQL语句的效率问题的。
    ParperStatement接口的机制是在数据库支持预编译的情况下预先将SQL语句编译,当多次执行这条SQL语句时,可以直接执行编译好的SQL语句,这样就大大提高了程序的灵活性和执行效率。

  3)使用PrepareStatement比Statement安全 

    举例:用户登录时进行密码验证

    sql="select * from tb_users where name= '"+name+"' and passwd='"+passwd+"'";
    stmt = conn.createStatement();
    rs = stmt.executeUpdate(sql);

    上面是登录时进行用户名和密码的验证,但是当把‘’or ’1’=’’1’作为密码传递进去会发现如下的SQL语句:

    select * from user where username = 'user' and userpwd='' or ''='';

    上面的SQL语句是个永真式。所以不管怎么样都能获取到权限,这还不是最坏的情况。

    当把'or '1'=1';drop table tb_book;当成密码传进去时,会直接删除数据库表,这样的SQL语句就非常的不安全。

    所以使用PrepareStatement可以解决SQL注入攻击的问题

五、JDBC实例


环境:数据库为test_jdbc

   表:s_emp  

5.1、查询数据库中所有的表

import org.junit.Test;

import java.sql.*;
import java.util.Properties; public class BaseOperation{ @Test
public void getConn() throws ClassNotFoundException, SQLException{
// 1.加载驱动:com.mysql.jdbc.Driver,官方文档
// 在JDBC4.0以后的版本中,可以不显式的指定驱动的类全名
// 第一种注册驱动:
Class.forName("com.mysql.jdbc.Driver");
// 第二种注册驱动:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 第三种注册驱动:
Properties properties=new Properties();
// properties.setProperty("driver","com.mysql.jdbc.Driver");
// Class.forName(properties.getProperty("driver"));
properties.getProperty("driver");
// 第四种注册驱动:在运行程序的时候指定JVM参数:
// -D mysql.driver=com.mysql.jdbc.Driver // 2.获取连接对象:Connection
String protocol="jdbc:mysql://";
String ip="1.0.0.50";
int port=5717;
String schema="briup";
String user="root";
String passwd="root";
String url=protocol+ // 协议
ip+":"+ // MySQL服务器的IP
port+"/"+ // MySQL的端口
schema+ // 数据库名
"?user="+user+ // 用户名
"&password="+passwd+ // 密码
"&useSSL=true"; //在MySQL5.5.*之后的版本中,使用JDBC连接的时候需要该参数。
System.out.println(url);
Connection connection=DriverManager.getConnection(url);
System.out.println(connection); // 3.获取Statement对象:
Statement statement=connection.createStatement(); // 4.执行SQL语句
String sql="show tables";
ResultSet resultSet=statement.executeQuery(sql); // 5.如果有结果集,处理结果集。
while(resultSet.next()){
String tb_names=resultSet.getString(1);
System.out.println(tb_names);
}
// 6.关闭连接
if(statement!=null) statement.close();
if(connection!=null) connection.close();
}
}

BaseOperation

5.2、编写一个JDBC工具类

  1)编写一个db.properties文件

driver=com.mysql.jdbc.Driver

protocol=jdbc:mysql://
host_ip=1.0.0.5
port=3306
user=root
password=123456
schema=db_test

db.properties

  2)编写工具类DBUtils类

import java.io.IOException;
import java.sql.*;
import java.util.Properties; public class DBUtils{
private static DBUtils du;
private static Properties properties; // 获取单例对象:
// 1.私有化构造器
private DBUtils(){}; // 2.提供共有的获取对象的方法,该方法中获得的对象时单例的
public static DBUtils getInstance(){
// 避免过度加锁行为
if(du==null){
synchronized(DBUtils.class){
// 真正的生成单例对象
if(du==null){
du=new DBUtils();
}
}
}
return du;
} static{
properties=new Properties();
try{
properties.load(
ClassLoader.getSystemResourceAsStream(
"db.properties"));
Class.forName(properties.getProperty("driver"));
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
} public static Connection getConn() throws SQLException{
String url=properties.getProperty("protocol")
+properties.getProperty("host_ip")+":"
+properties.getProperty("port")+"/"
+properties.getProperty("schema")+"?useSSL=true";
return DriverManager.getConnection(url,properties);
} public static void close(ResultSet resultSet,
Statement statement,
Connection connection){
if(resultSet!=null){
try{
resultSet.close();
}catch(SQLException e){
e.printStackTrace();
}
} if(statement!=null){
try{
statement.close();
}catch(SQLException e){
e.printStackTrace();
}
} if(connection!=null){
try{
connection.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}

DBUtils

5.3、查询s_emp中的前四行数据

  里面使用两种获得Connection对象的方式

import org.junit.Test;

import java.sql.*;
import java.util.Properties; public class SelectDemo_0010{ @Test
public void selectTest_1(){
ResultSet resultSet=null;
Connection connection=null;
Statement statement=null; String driver="com.mysql.jdbc.Driver";
String ip="1.0.0.50";
String port="5717";
String schema="test_jdbc";
String user="root";
String password="root"; String url="jdbc:mysql://"
+ip+":"
+port+"/"
+schema
+"?useSSL=true";
Properties properties=new Properties();
properties.setProperty("user",user);
properties.setProperty("password",password);
try{
Class.forName(driver); connection=
DriverManager.getConnection(url,properties);
System.out.println(connection); statement=connection.createStatement(); String sql="select * from s_emp";
resultSet=statement.executeQuery(sql); while(resultSet.next()){
String col_1=resultSet.getString(1);
String col_2=resultSet.getString(2);
String col_3=resultSet.getString(3);
String col_4=resultSet.getString(4);
System.out.println(col_1+"=="+col_2+"=="+col_3+"=="+col_4);
}
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(statement!=null){
try{
statement.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(connection!=null){
try{
connection.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
} @Test
public void selectTest_2(){
ResultSet resultSet=null;
Connection connection=null;
Statement statement=null; String driver="com.mysql.jdbc.Driver";
String ip="1.0.0.50";
String port="5717";
String schema="briup";
String user="root";
String password="root"; String url="jdbc:mysql://"
+ip+":"
+port+"/"
+schema
+"?useSSL=true";
try{
Class.forName(driver); connection=
DriverManager.getConnection(url,user,password);
System.out.println(connection); statement=connection.createStatement(); String sql="select * from s_emp";
resultSet=statement.executeQuery(sql); while(resultSet.next()){
String col_1=resultSet.getString(1);
String col_2=resultSet.getString(2);
String col_3=resultSet.getString(3);
String col_4=resultSet.getString(4);
System.out.println(col_1+"==="+col_2+"==="+col_3+"==="+col_4);
}
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(statement!=null){
try{
statement.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(connection!=null){
try{
connection.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}

SelectDemo_0010

5.4、使用工具类获取连接并比较Statement和PrepareStatment的用法

import com.briup.bd1702.jdbc.utils.DBUtils;
import org.junit.Test; import java.sql.*; public class SelectDemo_0020{ @Test
public void selectTest_1(){
Connection conn=null;
Statement statement=null;
ResultSet resultSet=null;
try{
conn=DBUtils.getConn();
statement=conn.createStatement();
resultSet=statement.executeQuery("show tables");
while(resultSet.next()){
System.out.println(resultSet.getString(1));
}
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtils.close(resultSet,statement,conn);
}
} @Test
public void selectTest_2(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try{
conn=DBUtils.getConn();
stmt=conn.createStatement();
String sql="select last_name as ln,dept_id,start_date,salary from s_emp";
rs=stmt.executeQuery(sql);
while(rs.next()){
String last_name=rs.getString("ln");
Integer dept_id=rs.getInt("dept_id");
Date start_date=rs.getDate("start_date");
Float salary=rs.getFloat("salary");
System.out.println(last_name+":"
+dept_id+":"
+start_date+":"
+salary);
}
}catch(SQLException e){
e.printStackTrace();
}finally{
DBUtils.close(rs,stmt,conn);
}
} @Test
public void selectTest_3(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null; String age="53 or 1=1"; try{
conn=DBUtils.getConn();
stmt=conn.createStatement();
String sql="select name from tb_users where age="+age;
rs=stmt.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getString("name"));
}
}catch(SQLException e){
e.printStackTrace();
}finally{
DBUtils.close(rs,stmt,conn);
}
} @Test
public void selectTest_4(){
Connection conn=null;
Statement stmt=null;
PreparedStatement pstmt=null;
ResultSet rs=null; String age="53 or 1=1"; try{
conn=DBUtils.getConn();
// 准备SQL语句
String sql="select name from tb_users where age=?";
// 获取PreparedStatement对象
pstmt=conn.prepareStatement(sql);
// 给SQL语句中的占位符设置值
pstmt.setInt(1,Integer.parseInt(age));
rs=pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getString("name"));
}
}catch(SQLException e){
e.printStackTrace();
}finally{
DBUtils.close(rs,stmt,conn);
}
}
}

SelectDemo_0020

5.5、插入数据,比较Statement和PrepareStatment的插入效率

import com.briup.bd1702.jdbc.utils.DBUtils;
import org.junit.Test; import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date; public class InsertDemo_0010{ @Test
public void insertTest_1(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null; String name="李四";
Integer age=50;
Date birth=new Date();
// 2017-09-14
Double score=99.5; try{
conn=DBUtils.getConn();
stmt=conn.createStatement();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String birth2=sdf.format(birth);
System.out.println(birth2);
String sql="insert into " +
"tb_users(name,age,birth,score) " +
"values('"+name+"',"+age+",'"+birth2+"',"+score+")";
stmt.execute(sql);
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtils.close(rs,stmt,conn);
}
} @Test
public void insertTest_2(){
Connection conn=null;
Statement stmt=null;
ResultSet rs=null; try{
conn=DBUtils.getConn();
stmt=conn.createStatement();
}catch(SQLException e){
e.printStackTrace();
} long oldt=System.currentTimeMillis();
for(int i=0;i<10000;i++){
String name="李四"+i;
Integer age=50+i;
Date birth=new Date(i*1000000);
Double score=99.5;
try{
//转化日期
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
String birth2=sdf.format(birth);
// SQL语句
String sql="insert into " +
"tb_users(name,age,birth,score) " +
"values('"+name+"',"+age+",'"+birth2+"',"+score+")";
//执行插入操作
stmt.execute(sql);
}catch(Exception e){
e.printStackTrace();
}
}
long newt=System.currentTimeMillis();
System.out.println("共耗时:"+(newt-oldt));
} @Test
public void insertTest_3(){
Connection conn=null;
Statement stmt=null;
PreparedStatement pstmt=null;
ResultSet rs=null; String name="王五";
Integer age=50;
Date birth=new Date();
Double score=99.5; try{
conn=DBUtils.getConn();
String sql="insert into " +
"tb_users(name,age,birth,score) " +
"values(?,?,?,?)";
pstmt=conn.prepareStatement(sql);
pstmt.setString(1,name);
pstmt.setInt(2,age);
pstmt.setDate(3,new java.sql.Date(birth.getTime()));
pstmt.setDouble(4,score);
pstmt.execute();
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtils.close(rs,stmt,conn);
}
} @Test
public void insertTest_4(){
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
try{
conn=DBUtils.getConn();
// SQL语句
String sql="insert into " +
"tb_users(name,age,birth,score) " +
"values(?,?,?,?)";
pstmt=conn.prepareStatement(sql);
}catch(SQLException e){
e.printStackTrace();
} long oldt=System.currentTimeMillis();
for(int i=0;i<10000;i++){
String name="李四"+i;
Integer age=50+i;
Date birth=new Date(i*1000000);
Double score=99.5;
try{
pstmt.setString(1,name);
pstmt.setInt(2,age);
pstmt.setDate(3,new java.sql.Date(birth.getTime()));
pstmt.setDouble(4,score);
//执行插入操作
pstmt.addBatch();
if(i%3000==0)
pstmt.executeBatch();
}catch(Exception e){
e.printStackTrace();
}
}
try{
pstmt.executeBatch();
}catch(SQLException e){
e.printStackTrace();
}
long newt=System.currentTimeMillis();
System.out.println("共耗时:"+(newt-oldt));
}
}

InsertDemo_0010

觉得不错的点个“推荐”哦!

JDBC(一)之细说JDBC的更多相关文章

  1. 解决 01-Jul-2016 10:49:05.875 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [ROOT] registered the JDBC driver [com.mysql.jdbc.D

    01-Jul-2016 10:49:05.875 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoade ...

  2. MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  3. DBUtils开源JDBC类库,对JDBC简单封装(作用是:简化编码工作量,同时不会影响程序的性能)

    DBUtils:提高了程序的性能,编程更加简便 架包 mysql-connector-java-jar commons-dbcp-1.4jar commons-pool-1.5.5jar common ...

  4. Hibernate 抓取策略fetch-2 (批量抓取batch-size以及hibernate.jdbc.fetch_size、hibernate.jdbc.batch_size)

    类关系: User N~1 Group 测试代码: System.out.println("1"); List stuList = session.createQuery(&quo ...

  5. SparkSQL使用之JDBC代码访问Thrift JDBC Server

    启动ThriftJDBCServer: cd $SPARK_HOME/sbin start-thriftserver.sh & 使用jdbc访问ThriftJDBCServer代码段: pac ...

  6. org.hibernate.service.classloading.spi.ClassLoadingException: Specified JDBC Driver com.mysql.jdbc.Driver class not found

    今天在使用hibernate搭建开发环境的时候出现了一个不可思议的问题: org.hibernate.service.classloading.spi.ClassLoadingException: S ...

  7. hibernate的速度问题--hibernate.jdbc.fetch_size和 hibernate.jdbc.batch_size

    hibernate的速度问题 这点我也疑惑过,最初应用hibernate的项目,我也感觉速度很慢,知道后来才知道问题的所在.       其实hibernate的速度性能并不差,比起jdbc来说,又是 ...

  8. 解决 Tomcat reload WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [] registered the JDBC driver [com.mysql.jdbc.Driver] but fail

    转自:http://www.cnblogs.com/interdrp/p/5632529.html 我的错误如下: 06-Sep-2016 18:57:10.595 WARNING [localhos ...

  9. MySQL JDBC事务处理、封装JDBC工具类

    MySQL数据库学习笔记(十)----JDBC事务处理.封装JDBC工具类 一.JDBC事务处理: 我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败.在MySQL中提供了Commit. ...

随机推荐

  1. nessus重置密码

    许久不用的nessus密码居然忘记了,查了下: cmd下进入到nessus的安装目录 提升为管理员,登录系统 如果想用之前的账号,可以直接在系统内重置密码.

  2. 华为服务器Linux在线做RAID方法

    背景概述 最近维护大数据的一些主机,大概有3k+的数目,有很大一部分是华为的服务器,大部分是12块数据盘,单盘做RAID0来存放数据,但是通常硬件是不可靠的,磁盘损坏是常态, 然而磁盘损坏进行定位更换 ...

  3. 已有 JFFs2文件系统的修改

    项目应用中,对于前人留下的JFFS2的文件,有时候我们需要修改,但是苦于没有源文件,实际操作很多时候无所适从.每次支持生产之后再进行人为的升级.这样费时费力,也给生产人员增加了负担. 为了解决这个问题 ...

  4. 51NOD 1258 序列求和 V4 [任意模数fft 多项式求逆元 伯努利数]

    1258 序列求和 V4 题意:求\(S_m(n) = \sum_{i=1}^n i^m \mod 10^9+7\),多组数据,\(T \le 500, n \le 10^{18}, k \le 50 ...

  5. Matlab学习笔记(2)

    1. 在MATLAB中默认最开始出现的是命令窗口,也就是Command Window.对应的文件保存后扩展名一般都 是.mat 真正的程序代码编辑窗口应该新建New Script或者其他的.此时保存的 ...

  6. 再说php依赖注入

    前段时间,有朋友问我yii2的依赖注入是怎么个玩法,好吧, 经常看到却一直不甚理解的概念,这里我再对自己认识的依赖注入深刻的表达下我的理解,依赖注入(DI)以及控制器反转(Ioc). 依赖注入就是组件 ...

  7. 设计模式原则(3)--Dependency Inversion Principle(DIP)--依赖倒转原则

    1.定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 抽象不应该依赖于细节,细节应当依赖于抽象.换言之,要针对接口编程,而不是针对实现编程. 2.使用场 ...

  8. 关于android appcompatv7 Menu items should specify a title的解决办法

    做安卓开发时,添加menu时 是AS报以下错误: 解决办法为修改如下: <menu xmlns:android="http://schemas.android.com/apk/res/ ...

  9. python开源项目及示例代码(转)

    本页面是俺收集的各种 Python 资源,不定期更新. 下面列出的各种 Python 库/模块/工具,如果名称带超链接,说明是第三方的:否则是 Python 语言内置的. 1 算法 1.1 字符串处理 ...

  10. 【Tomcat】shell 部署配置 war包

    使用shell 一次执行,将项目中的war包的配置全部修改 #!/bin/bash #----------------------------------------------- # FileNam ...