JDBC概述

  java 数据库链接,sun公司退出的 java 访问数据库的标准规范接口

  是一种用于执行SQL语句的 java API

  可以作为多种关系数据库提供统一接口

  是一组 java 工具类和接口的组成。

JDBC 原理

  

  JDBC是接口,驱动接口的实现,没有驱动无法完成数据库链接,而不能操作数据库。

  每个数据库厂商都需要提供自己的驱动,用来链接自己公司的数据库

  也就是说,驱动一般由数据库厂商提供。

  当然还有第三方公司专门为某一数据库提供驱动,这样的驱动往往不会是开源免费的!

  例如:mysql 驱动包 是 mysql-connector-java-5.1.28-bin.jar

   

创建项目

1. 修改项目的编码格式为 UTF-8

  点击 window -> workspace -> 修改UTF-8  点击应用 ok。

  

2. 创建新项目

  

3.  导入jar包

  首先new一个文件夹

  创建一个 lib 文件夹存放 jar 包

  将 mysql-connector-java-5.1.28-bin.jar 放入 lib 文件夹

  然后:

   

  完成之后

  

4. 单元测试

  先创建一个包,然后建立一个类

  

编辑代码

package cn.study.test;

import org.junit.Test;

public class TestJunit {

    /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub } @Test
public void testJunit(){
System.out.println("hello junit");
} }

  

  右击 @Test 点击运行

  

  

  修改代码

package cn.study.test;

import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class TestJunit { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub } @Test
public void testJunit(){
System.out.println("hello junit");
} @Before
public void testBefore() {
System.out.println("before!");
} @After
public void testAfter() {
System.out.println("after!");
} }

  

JDBC开发步骤

  1. 注册驱动

  2. 获得链接

  3. 获得语句执行者

  4. 执行 sql 语句

  5. 处理结果

  6. 释放资源

API详解:注册驱动

代码:

class.forName(“com.mysql.jdbc.Driver”)

分析步骤1 :

  JDBC规范定义驱动接口:java.sql.Driver

  mysql 驱动包提供了实现类:com.mysql.jdbc.Driver

分析步骤2:

  DriverManager工具类提供注册驱动的方法

  方法的参数是 java.sql.Driver 所以我们可以通过如下语句进行注册

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

  以上代码不推荐使用,存在两方面不足

    1. 硬编码,后期不易于拓展和维护

    2. 驱动被注册两次

分析步骤3:

  通常开发我们使用 Class.forName() 加载一个使用字符串描述的驱动类。

  如果使用Class.forName() 将类加载到内存,该类的静态代码将自动执行。

  通过查询 com.mysql.jdbc.Driver 源码,我们发现Driver类主动将自己进行注册。

API 详解:获取链接

代码:

Connection con=DriverManager.getConnection{"jdbc:mysql://localhost:3306/mydb1","root","123456"};

  获取链接需要使用方法 DriverManager.getConnection(url , username , password)

  URL 表示链接数据库的位置(网址)

    user 表示用户名

    password :表示数据库密码

    jdbc:mysql://localhost:3306/mydb1

  URL由三部分组成,每部分用逗号隔开

    第一部分 jdbc 为固定的

    第二部分是数据库名称

    第三部分为数据库厂商制定:数据库服务地址ip、端口、数据库名称。

  拓展参数:

jdbc:mysql://localhost:3306/mydb1?useUnicode=true&characterEncoding=UTF8

API 详解:获取语句执行

String sql = "insert into category(cid,cname) value ( 'c107' ,  '分类' )"

Statemet 语句执行代码: 

Statement stmt = con.createStatement();

执行sql语句:

执行  insert   update   delete 语句

int executeUpdate(string sql); 

执行select语句

ResultSet executeQuery( string sql );

执行 select 语句返回 true ,执行其他语句返回 false

boolean execute(string sql); 

  如果返回true 需要使用 getResultSet() 获取查询结果。

  如果返回 false 需要使用 getUpdateCount() 获取影响行数。

执行批处理:

addBatch(string sql);

clearBath();

executeBatch();

如果有参数需要在sqql语句中进行拼凑,存在sql注入问题。

API 详解:处理结果集

ResultSet 实际上就是一张二维表格,内部有一个行光标,光标默认位置在第一行上方,我们可以调用 rs 对象的 next() 方法把 行光标向下移动一行,当第一次调用 next() 的时候,行光标就到了第一行记录的位置,这时候就可以使用 resultSet 提供的 getXXX(int col)方法来获取指定的列数据了。

光标移动到第一行

rs.next();  

获取第一行第一列数据

rs.getInt(1);  

  

常用的方法有:

获取任意对象

object getObject(int col) 

获取字符串

string getString(inr col) 

获取整形

int getInt(int col) ;

获取双精度浮点数

double getDouble(int col);

API 详解:释放资源

与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭!

rs.close();

stmt.close();

con.close();

案例代码:

package cn.study.test;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.Connection; import java.sql.Statement; import org.junit.Test; /**
* 测试sql注入问题
* @author Administrator
*
*/
public class TestLogin { @Test
public void testLogin() {
try {
login("wjw", "20");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* 用户登录方法
* @param username
* @param password
* @throws ClassNotFoundException
* @throws SQLException
*/
public void login(String username,String password) throws ClassNotFoundException, SQLException { // 1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2. 获取链接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbtest","root","123456");
// 3. 创建执行sql语句的对象
Statement stmt = conn.createStatement();
// 4. 书写sql语句
String sql = "select * from student where "+"name='"+username+"' and age='"+password+"'";
// 5. 执行sql语句
ResultSet rs = stmt.executeQuery(sql);
// 6.对结果集进行处理
if (rs.next()) {
System.out.println("恭喜你 "+username +" 登录成功!");
System.out.println(sql);
}else{
System.out.println("账号或密码错误!");
}
// 7. 释放资源
if (rs!=null) rs.close();
if (stmt!=null) stmt.close();
if (conn!=null) conn.close();
}
}

sql 注入问题

防止sql攻击

  过滤用户输入的数据是否包含非法字符。—— 很难做到

  分布校验,先使用用户名来查询用户,如果查找到了在比较密码。

  使用 PrepareStatement。

PrepareStatement是什么?

  PrepareStatement 叫预编译声明。

  PrepareStatement是Statement的子接口,可以使用 PrepareStatement 来替代 Statement。

PrepareStatement 的好处:

  防止sql攻击

  提高代码可读性和可维护性

  提高效率

PreparedStatement的使用:

  使用 Connection 的 prepareStatement(string sql):即创建它时就让他与一条sql锁定。

  调用PrepareStatement 的 setXXX() 系列方法为问号设置值。

  调用 executeUpdate() 或 executeQuery() 方法,但要注意,调用没有参数的方法。

package cn.study.test;

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.Connection; import java.sql.Statement; import org.junit.Test; /**
* 测试sql注入问题
*
* @author Administrator
*
*/
public class TestLogin { @Test
public void testLogin() {
try {
login("wjw", "20");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* 用户登录方法
*
* @param username
* @param password
* @throws ClassNotFoundException
* @throws SQLException
*/
public void login1(String username, String password)
throws ClassNotFoundException, SQLException { // 1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2. 获取链接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/dbtest", "root", "123456");
// 3. 编写sql语句
String sql = "select * from student where name=? and age=?";
// 4. 创建预处理对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 5. 设置参数
pstmt.setString(1, "fasda");
pstmt.setString(2, "365351");
// 6. 执行查询编辑
ResultSet rs = pstmt.executeQuery();
// 7.对结果集进行处理
if (rs.next()) {
System.out.println("恭喜你 " + username + " 登录成功!");
System.out.println(sql);
} else {
System.out.println("账号或密码错误!");
}
// 8. 释放资源
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} }

分页查询 limit

(limit , 2 , 2)第一个起始位置,要查询(第几页-1)*第二个参数,   第二个是数量。

项目代码https://github.com/wjw1014/JavaMysqlStudy/tree/master/my_JDBC (小白操作,仅供参考!)

最新文章

  1. web.xml中load-on-startup的作用
  2. Sql Server中查询今天、昨天、本周、上周、本月、上月数据
  3. 使用echarts开发电子屏数据展示页面
  4. 无废话SharePoint入门教程一[SharePoint概述]
  5. RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.7 版本发布
  6. ios 数组排序
  7. Linux网络编程必看书籍推荐
  8. ansible playbook最佳实践
  9. 删除织梦所有待审核稿件sql语句
  10. js 效果样式大全
  11. Spring基础学习(一)—初识Spring
  12. PS调出清新风格社区街拍照片
  13. 2018-2019-2 20165236郭金涛《网络对抗》Exp1 PC平台逆向破解
  14. 南阳236----心急的C小加
  15. CORSFilter 跨域资源访问
  16. [转]MAC系统下Sublime Text3 配置Python3详细教程(亲测有效)
  17. Javascript MVC 学习笔记(一) 模型和数据
  18. c# 抓取和解析网页,并将table数据保存到datatable中(其他格式也可以,自己去修改)
  19. Python 内部类
  20. jQuery 复制节点的元素实现添加到购物车功能

热门文章

  1. Wannafly Camp 2020 Day 5A Alternative Accounts
  2. SDOI2010 粟粟的书架 lg2468(可持久化,前缀和)
  3. Oracle监听出现的问题总结,以及解决办法
  4. JUC-JUC强大的辅助类讲解(Semaphore、CyclicBarrier、CountDownLatch)
  5. Linux下基于PAM机制的USB Key的制作
  6. .net 文件接口的封装,写日志,创建文件log
  7. django 搭建一个投票类网站(一)
  8. IntelliJ IDEA 2017.3尚硅谷-----创建的静态 Java Web
  9. 2019-08-02 纪中NOIP模拟B组
  10. STM32F103之DMA学习记录