美文网首页
[java]29、JDBC

[java]29、JDBC

作者: 史记_d5da | 来源:发表于2022-03-26 13:52 被阅读0次

1、JDBC

1.1、JDBC,全称是 Java Database Connectivity

Java中用来规范如何访问关系型数据库,由各大数据库厂商去实现

1.2、JDBC 项目

1、首先去官网下载 JDBC

下载选项
  • Product Version5.1.43
  • Operationg SystemPlatform Independent
  • 下载文件选择:Platform Independent(Architecture Independent), ZIP Archive

2、选择Modules 选择创建 Java项目,在目录下新建一个lib 文件夹,将下载好的jdbcjar包拷贝到 lib 目录下,右键选择 Add as Library...

添加库文件

2、JDBC的使用

2.1、MySQL 的细节

1、url格式
jdbc:mysql://IP地址:端口号/数据库名 例如:jdbc:mysql://localhost:3306/xmg
2、驱动类的差别:

  • MySQL 驱动包 6.x 以前
    驱动类:com.mysql.jdbc.Driver
  • MySQL 驱动包 6.x 以后
    驱动类:com.mysql.cj.jdbc.Driver,(需要指定一个时区,比如在url后加参数serverTimeZone=UTC)
2.2、JDBC的具体使用步骤

1、注册DriverDriverManager
Class.forName("com.mysql.jdbc.Driver");

Driver.class
注册com.mysql.jdbc.Driver 最终会执行静态方法中的DriverManager.registerDriver(new Driver());
2、利用DriverManager创建数据库连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/xmg", "root", "xxxxx");
3、利用Connection 创建 Statement
Statement statement = connection.createStatement();
4、利用Statement来执行Sql语句
statement.execute("UPDATE student SET age = 50 WHERE id = 1");
5、关闭后续操作
statement.close();
connection.close();
另一种写法
String className = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/xmg";
String user = "root";
String password = "xxxxxx";
try {
     Class.forName(className);
     try(Connection conn = DriverManager.getConnection(url, user, password);Statement stmt = conn.createStatement();) {
           stmt.execute("UPDATE student SET age = 50 WHERE id = 1");
     }
} catch (Exception e) {
      e.printStackTrace();
}
2.3、JDBC 版本

JDBC 4.0开始,显示注册驱动程序是可选的

try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); Statement stmt = conn.createStatement();){
}
2.4、Statement 的常用API

1、执行 SQL 语句
ResultSet executeQuery(String sql)
2、执行DMLDDL语句
int executeUpdate(String sql)
如果是DML语句,返回值代表影响的记录数量;如果数据库没有返回任何值,返回0
3、让游标指向下一行,如果指向这一行有数据,就返回true 否则返回false
boolean next()
4、返回当前行的某一列数据(columnIndex 的数值从1开始)
xx getXX(int columnIndex)xx getXX(String columnLabel)

2.5、SQL注入

案例

public static void main(String[] args) throws Exception {
      String username = "";
      String password = "' OR '1' = '1";
      login(username, password);
}

private static void login(String username, String password) throws  Exception {
      try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); Statement stmt = conn.createStatement();){
          String sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = '" + password + "'";
          ResultSet res = stmt.executeQuery(sql);
          if (res.next()) {
              System.out.println("登录成功");
          } else {
              System.out.println("登录失败");
          }
      }
}

分析
生成的sql语句:SELECT * FROM user WHERE username = '' AND password = '' OR '1' = '1'
此时查询的结果为所有数据,登录校验通过。
解决
使用PreparedStatement 操作数据库

private static void login2(String username, String password) throws  Exception{
    String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
    try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
          PreparedStatement pstmt = conn.prepareStatement(sql);) {
        // 设置参数
        pstmt.setString(1, username);
        pstmt.setString(2, password);
        // 执行sql语句
        ResultSet res = pstmt.executeQuery();
    }
}

分析
生成的sql语句:SELECT * FROM user WHERE username = '' AND password = '\' OR \'1\' = \'1\'
此时查询用户名和密码不存在(输入的密码当做一整串字符处理)。
优点
可以防止SQL注入
执行速读比 Statement
支持批量处理

2.6、配置文件

一些经常修改的值,建议放入到配置文件中。
1、常见的配置文件有两类:
properties :比较单一,适合量小、简单的配置。

  • keyvalue的分隔符是=: (建议分隔符左右不要留空格)
  • #!开头是单行注释(可以用\链接多行内容)

xml:比较灵活,适合量大、比较复杂的配置。
2、选中resources文件、点击右键选择NewResource bundle、输入名称点击OK即可

properties
2.7、Servlet调整

一个Servlet类中需要实现多个url请求。
1、在注解中采用模糊匹配的方式

@WebServlet("/customer/*")

2、在postget请求中采用反射调用类方法。
例如:下面的请求url分别为 /customer/save/customer/remove的解析方法。

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String uri = req.getRequestURI();
    String[] cmps = uri.split("/");
    String methodName = cmps[cmps.length - 1];
    // 利用方法名调用方法
    try {
         Method method = getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class );
         method.invoke(this, req, resp);
    } catch (Exception e) {
         e.printStackTrace();
    }
}
public void save(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException  {
    System.out.println("save--------------");
}

public void remove(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException  {
    System.out.println("remove--------------");
}
2.8、数据库连接池

1、数据库连接池,可以提高访问数据库的性能,负责创建、分配、管理和释放数据库连接
2、基本思想

  • 在初始化时,创建一定数量的数据库连接对象存储在内存中。
  • 当需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已创建的空闲连接对象。
  • 使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。
  • 当连接的空闲时间已超过最大空闲时间时,将会释放掉该连接。
  • 可以通过设置参数来控制初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间。
  • 可以通过其自身的管理机制来监视数据库连接的数量、使用情况。

3、Java中常见的开源的数据库连接池
C3P0ProxoolDBCPBoneCPDruid
Druidjar包下载地址

Druid
点击View All
Druid
选择源码和jar包下载、然后将jar包添加到lib目录下面、右键选择Add as Library
2.9、Spring JDBC(适合小型项目)

1、Spring JDB框架可以帮助开发者节省大量开发工作,自动去处理一些低级细节,比如:异常处理、打开和关闭资源(ConnectionStatementResultSet
需要的Jar包:spring-jdbcspring-beansspring-corespring-txspring-jcl
2、Spring JDBC核心类:jdbcTemplate

  • 构造方法
public class Dbs {
    private static JdbcTemplate tpl;
    static {
        try {
            InputStream is = Dbs.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties properties = new Properties();
            properties.load(is);
            DataSource ds = DruidDataSourceFactory.createDataSource(properties);
            tpl = new JdbcTemplate(ds);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static JdbcTemplate getTpl() {
        return tpl;
    }
}
  • 数据库操作
public class CustomerDao {
    public boolean save(Customer customer) {
        String sql = "INSERT INTO customer (name, age, height) VALUES (?,?,?)";
        return Dbs.getTpl().update(sql, customer.getName(), customer.getAge(), customer.getHeight()) > 0;
    }
    public List<Customer> list() {
        String sql = "SELECT id, name, age, height FROM customer";
        return Dbs.getTpl().query(sql, new BeanPropertyRowMapper<>(Customer.class)); // 自动映射成Customer对象
    }
}

3、Junit

JunitJava 中最常用的单元测试开源框架。

3.1、使用步骤

1、依赖的jar包:junit-4.13.2.jarhamcrest-2.2.jarhamcrest-core-2.2.jar
2、在main下新建一个test文件夹、右键选择Mark Directory asTest Sources Root,目的是不让test代码不会被编译到工程中

junit
3、在测试代码的方法上添加注解@Test,方法的左边会有绿色的小箭头,点击箭头即可测试
3.2、常用注解

1、@Test:正常的测试方法建议使用 public void testXx()
2、@Before:在每个@Test执行方法之前执行,建议格式是public void before()
3、@After:在每个@Test方法执行之后执行,建议格式是public void after()
4、@BeforeClass:在第一个@Test方法执行之前执行,建议格式是public static void before()
5、@AfterClass:在第一个@Test方法执行之后执行,建议格式是public static void after()

相关文章

网友评论

      本文标题:[java]29、JDBC

      本文链接:https://www.haomeiwen.com/subject/snxddrtx.html