6.JDBC学习笔记

本文内容

1.什么是JDBC以及为什么要使用JDBC

2.JDBC核心API的讲解

3.使用JDBC核心API进行CRUD操作

4.JDBC的工具类的抽取与改进

5.JDBC的SQL注入漏洞分析与解决方案

6.使用JDBC的PreparedStatement预编译对象进行CRUD操作(重点)

7.JDBC的批处理操作

使用JDBC的预编译对象进行CRUD操作(重点)

[if !supportLists]1.1 [endif]1.JDBC的概述

JDBC:(Java DataBase Connectivity Java数据库连接).

*是一种用于执行SQL语句的Java 的API.可以为多种关系型数据库提供统一的访问.它是由一组使用Java语言编写的类或接口组成.


简说:用java语言编写的一组用于访问关系型数据库的接口和类.


作用:使用Java语言连接到数据库


驱动:两个设备之间的通信桥梁.

Java语言要连接数据库必须使用数据库的驱动

本质:

SUN公司提供了一组接口,各个数据库生产商提供了这套接口的实现.(这组规范就是JDBC规范.)



[if !supportLists]1.2 [endif]02_JDBC的入门(写)

先解释下,再写


设置工作空间的编码为utf-8

SQL脚本:

create database web_test3;

use web_test3;

create table user(

id int primary key auto_increment,

username varchar(20),

password varchar(20),

nickname varchar(20),

age int

);

insert into user values (null,'aaa','123','小丽',34);

insert into user values (null,'bbb','123','大王',32);

insert into user values (null,'ccc','123','小明',28);

insert into user values (null,'ddd','123','大黄',21);


引入数据库的驱动.


注意:复制驱动包过来后,一定要选中, add to Build Path


1.加载驱动.

2.获得连接.

获得语句(Statement )对象

3.执行SQL

4.释放资源.


public class JDBCDemo1 {

@Test

/**

* JDBC的入门

 */

public void demo1() throws Exception{

// 1.加载驱动

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

// 2.获得连接

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "abc"); //注意:密码改成你的密码

// 3.基本操作:执行SQL

// 3.1获得执行SQL语句的对象

Statement statement = conn.createStatement();

// 3.2编写SQL语句:

String sql = "select * from user";

// 3.3执行SQL:

ResultSet rs = statement.executeQuery(sql);

// 3.4遍历结果集:

while(rs.next()){

System.out.print(rs.getInt("id")+" ");

System.out.print(rs.getString("username")+" ");

System.out.print(rs.getString("password")+" ");

System.out.print(rs.getString("nickname")+" ");

System.out.print(rs.getInt("age"));

System.out.println();

}

// 4.释放资源

rs.close();

statement.close();

conn.close();

}

}



[if !supportLists]1.3 [endif]03_DriverManager的介绍

问题:

DriverManager对象有什么作用?

Ø为什么没有使用registerDriver()注册驱动?

Ø获取连接的url路径的含义?


1.DriverManager对象两个作用:①、注册驱动和②、获取连接;




2.为什么使用没有使用registerDriver注册驱动?


DriverManager类:


原来这样写:

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


com.mysql.jdbc.Driver源码:


现在这样写:

Class.forName(“com.mysql.jdbc.Driver”);//强制加载class到内存


结论:直接调用registerDriver方法会导致驱动加载2次.


[if !supportLists]3.[endif]获取连接的url路径的含义?



[if !supportLists]1.4 [endif]04_Connection的介绍

[if !supportLists]Ø [endif]Connection对象有哪些作用?


有两个作用:①、创建执行SQL的Statement(语句)对象;②、管理事务

作用一、创建执行sql语句的对象:

作用二:管理事务


总结:

[if !supportLists]1.[endif]Connection对象的作用?

获取语句对象

Statement

 CallableStatement(后面Oracle说)

 PreparedStatement

管理事务

setAutoCommit(false);//手动开启事务

...

...

commit()

rollback();



[if !supportLists]1.5 [endif]05_Statement的介绍

[if !supportLists]Ø [endif]Statement对象有哪些作用?

有两个作用:①、执行sql语句;②、进行批处理


作用一:执行sql语句





作用二:进行批处理:就是把几条sql语句添加到Statement对象命令列表中,一次性执行多条sql语句。





[if !supportLists]1.6 [endif]06_ResultSet的介绍

ResultSet代表select查询后的结果集


方法:


*向下移动光标.


*获得结果集中整形数据.


*获得结果集中字符串类型的数据:



...


遍历结果集:

* while(rs.next()){

int id = rs.getInt("id");

String username = rs.getString("username");

String password = rs.getString("password");

System.out.println(id+"    "+username+"    "+password);

}

获得结果集中的数据:

* int id = rs.getInt("id");

String username = rs.getString("username");

String password = rs.getString("password");


如果结果集中只有一条记录:

* if(rs.next()){

...

}

原理:



总结:

   1. Result rs = statement.executeQuery(“select * from user”);

   2.while(rs.next()) {

       rs.getInt(“id”);

rs.getString(“username”);

rs.getObject(“password”);

rs.getInt(4);

}

[if !supportLists]1.7 [endif]07_JDBC的资源的释放

Connection的使用原则:尽量要晚创建,尽量早释放!!!


try{

..

...

}catch(){...}

finally {....}


要掌握,看看代码,晚上写

[if !supportLists]Ø [endif]掌握释放资源标准代码:一般释放资源的代码放到finally里面去执行

finally {

//5、方法资源

if (resultSet!=null) {

try {

resultSet.close();

} catch (SQLException e) {

e.printStackTrace();

}

resultSet=null;

}

if (statement!=null) {

try {

statement.close();

} catch (SQLException e) {

e.printStackTrace();

}

statement=null;

}

if (conn!=null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn=null;

}

}



1、为什么对象调用了close()方法以后还要把对象手动赋值为null?



资源释放的一段标准代码:

// 4.释放资源.

if (rs != null) {

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

rs = null; // 为了让JVM垃圾回收更早回收该对象.

}

if (stmt != null) {

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}


if (conn != null) {

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}


总结:

try {

//加载驱动

//获取连接

//创建statement

//执行SQL

//遍历结果集

}catch(Exception ex) {


}finally {

//释放资源

rs,stat,conn

if (rs!=null) {

try {

rs.close();

}catch() {}

rs = null;

}


}



[if !supportLists]1.8 [endif]08_JDBC的CRUD操作之保存(写)

思路:

加载驱动

获得连接

获得Statement对象,执行SQL

释放资源


@Test

/**

*保存操作的代码实现

 */

public void demo1(){

Connection conn = null;

Statement stmt = null;

try{

//注册驱动:

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

//获得连接:

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

//执行操作:

//创建执行SQL语句对象:

stmt = conn.createStatement();

//编写SQL语句:

String sql = "insert into user values (null,'eee','123','阿黄',21)";

//执行SQL语句:

int num = stmt.executeUpdate(sql);

if(num > 0){

System.out.println("保存用户成功!!!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

//资源释放:

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

}


[if !supportLists]1.9 [endif]09_JDBC的CRUD操作之修改操作(写)

    @Test

/**

*修改操作的代码实现

 */

public void demo2(){

Connection conn = null;

Statement stmt  = null;

try{

//注册驱动:

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

//获得连接

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

//执行操作:

//创建执行SQL语句的对象:

stmt = conn.createStatement();

//编写SQL语句:

String sql = "update user set password='abc',nickname='旺财' where id = 5";

//执行SQL语句:

int num = stmt.executeUpdate(sql);

if(num > 0){

System.out.println("修改用户成功!!!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

//资源释放:

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

}

[if !supportLists]1.10 [endif]10_JDBC的CRUD操作之删除操作

@Test

/**

*删除操作的代码实现

 */

public void demo3(){

Connection conn = null;

Statement stmt = null;

try{

//注册驱动:

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

//获得连接:

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

//创建执行SQL语句对象:

stmt = conn.createStatement();

//编写SQL:

String sql = "delete from user where id = 5";

//执行SQL:

int num = stmt.executeUpdate(sql);

if(num > 0){

System.out.println("删除用户成功!!!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

//资源释放:

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

}


[if !supportLists]1.11 [endif]11_JDBC的CRUD操作之查询操作

@Test

/**

*查询多条记录

 */

public void demo4(){

Connection conn = null;

Statement stmt = null;

ResultSet rs = null;

try{

//注册驱动

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

//获得连接

conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root", "abc");

//执行操作

//创建执行SQL语句的对象:

stmt = conn.createStatement();

//编写SQL:

String sql = "select * from user";

//执行SQL:

rs = stmt.executeQuery(sql);

//遍历结果集:

while(rs.next()){

System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));

}

}catch(Exception e){

e.printStackTrace();

}finally{

//资源释放:

if(rs != null){

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

rs = null;

}

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

}




[if !supportLists]1.12 [endif]12_JDBC的工具类的抽取(写)

[if !supportLists]Ø [endif]总结一下抽取的原则:把相同的操作抽到一个方法里,可以重复利用。


关于JDBC我们可以抽取:加载驱动、获取连接、释放资源这三部分的代码。


/**

* JDBC的工具类

 * @author  itheima

 */

public class JDBCUtils {

private static final String driverClassName;

private static final String url;

private static final String username;

private static final String password;

static{

driverClassName="com.mysql.jdbc.Driver";

url="jdbc:mysql:///web_test3";

username="root";

password="abc";

}


/**

*注册驱动的方法

 */

public static void loadDriver(){

try {

Class.forName(driverClassName);

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

/**

*获得连接的方法

 */

public static Connection getConnection(){

Connection conn = null;

try{

//将驱动一并注册:

loadDriver();

//获得连接

conn = DriverManager.getConnection(url,username, password);

}catch(Exception e){

e.printStackTrace();

}

return conn;

}

/**

*释放资源的方法

 */

public static void release(Statement stmt,Connection conn){

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

public static void release(ResultSet rs,Statement stmt,Connection conn){

//资源释放:

if(rs != null){

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

rs = null;

}

if(stmt != null){

try {

stmt.close();

} catch (SQLException e) {

e.printStackTrace();

}

stmt = null;

}

if(conn != null){

try {

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

conn = null;

}

}

}

测试工具类

@Test

/**

*查询操作:使用工具类

 */

public void demo1(){

Connection conn = null;

Statement stmt = null;

ResultSet rs = null;

try{

//获得连接:

conn = JDBCUtils.getConnection();

// 创建执行SQL语句的对象:

stmt = conn.createStatement();

//编写SQL:

String sql = "select * from user";

//执行查询:

rs = stmt.executeQuery(sql);

//遍历结果集:

while(rs.next()){

System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password"));

}

}catch(Exception e){

e.printStackTrace();

}finally{

//释放资源:

JDBCUtils.release(rs, stmt, conn);

}

}


[if !supportLists]1.13 [endif]13_JDBC的配置信息提取到配置文件

[if !supportLists]Ø [endif]如何定义配置文件以及加载配置文件中的信息?

定义配置文件:


获取配置文件中的信息:



[if !supportLists]1.14 [endif]14_JDBC的SQL注入漏洞(SQL演示)

[if !supportLists]Ø [endif]什么是sql注入漏洞?

在我们的网站中肯定会有登录的操作,用户之所以能登录成功,肯定是通过用户名和对应的密码去数据库中能找到对应的一条数据,假设某个人不清楚密码,只通过输入用户名就能从数据库中找到一条对应的数据,那么这就称为sql注入漏洞。


简单说:

通过表单或界面输入一些SQL字符串,能到达服务器执行,达到非法操作的目的.

正常的基本登录流程代码: 


sql注入代码演示:


输入用户名

[if !supportLists]n [endif]aaa’ or ‘1=1密码随意

[if !supportLists]n [endif]aaa’ -- 密码随意  注意:--后面有空格



SQL环境演示:

SELECT * FROM USER WHERE username='aaa' AND PASSWORD='123'

SELECT * FROM USER WHERE username='aaa' OR '1=1' AND PASSWORD='wrwrw'

SELECT * FROM USER WHERE username='aaa'-- ' AND PASSWORD='wrwrw'


代码参见:/jdbc/src/com/itheima/jdbc/demo4/UserDao.java

[if !supportLists]1.15 [endif]15_JDBC的SQL注入漏洞分析及解决

[if !supportLists]Ø [endif]sql注入漏洞的原因是什么?

[if !supportLists]Ø [endif]如何解决sql注入的漏洞?


[if !supportLists]1、 [endif]原因:主要是用户输入了sql中规定的关键字,导致我们的sql语句的判断条件发生了变化。

使用Statement对象来执行一个sql语句是这样的:

resultSet=statement.executeQuery("select * from user where username='"+username+"' and password='"+password+"';");

   我们把用户输入的内容放到上面的sql语句对应的变量处:

or前面的一部分判断成立就能查到结果。


[if !supportLists]2、 [endif]解决sql注入的漏洞:使用PreparedStatement对象而不是Statement对象。

PreparedStatement有一个预编译的过程,这个过程会固定sql语句的格式,对于变量要求是用?来占位,那么传递过来的数据即使包含了sql关键字也不会当做关键字来识别。


public class UserDao {

public boolean login(String username,String password){

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

//定义一个变量:

boolean flag = false;

try{

//获得连接:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "select * from user where username = ? and password = ?";

//预编译SQL

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setString(1, username);

pstmt.setString(2, password);

//执行SQL语句:

rs = pstmt.executeQuery();//无需传入SQL

if(rs.next()){

//说明根据用户名和密码可以查询到这条记录

flag = true;

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(rs, pstmt, conn);

}

return flag;

}

代码参见:/jdbc/src/com/itheima/jdbc/demo4/UserDao.java


[if !supportLists]1.16 [endif]16_JDBC的CRUD操作之PreparedStatement保存操作(写)

@Test

/**

*保存操作

 */

public void demo1(){

Connection conn = null;

PreparedStatement pstmt = null;


try{

//获得连接:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "insert into user values (null,?,?,?,?)";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setString(1, "eee");

pstmt.setString(2, "abc");

pstmt.setString(3, "旺财");

pstmt.setInt(4, 32);

//执行SQL

int num = pstmt.executeUpdate();//不传SQL

if(num > 0){

System.out.println("保存成功!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

}



[if !supportLists]1.17 [endif]17_JDBC的CRUD操作之PreparedStatement修改操作

@Test

/**

*修改操作

 */

public void demo2(){

Connection conn = null;

PreparedStatement pstmt = null;

try{

//获得连接:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "update user set username = ?,password =?,nickname=?,age = ? where id = ?";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setString(1, "abc");//设置第一个?的值

pstmt.setString(2, "1234");

pstmt.setString(3, "旺旺");

pstmt.setInt(4, 23);

pstmt.setInt(5, 4);

//执行SQL:

int num = pstmt.executeUpdate();

if(num > 0){

System.out.println("修改成功!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

}


[if !supportLists]1.18 [endif]18_JDBC的CRUD操作之PreparedStatement删除操作

@Test

/**

*删除操作

 */

public void demo3(){

Connection conn = null;

PreparedStatement pstmt  = null;

try{

//获得连接:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "delete from user where id = ?";

//预编译SQL

pstmt = conn.prepareStatement(sql);

//设置参数:

pstmt.setInt(1, 4);

//执行SQL:

int num = pstmt.executeUpdate();

if(num > 0){

System.out.println("删除成功!");

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

}


[if !supportLists]1.19 [endif]19_JDBC的CRUD操作之PreparedStatement查询操作

@Test

/**

*查询操作

 */

public void demo4(){

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

try{

//获得连接:

conn = JDBCUtils.getConnection();

//编写SQL:

String sql = "select * from user";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

//设置参数:

//执行SQL:

rs = pstmt.executeQuery();

//遍历结果集:

while(rs.next()){

System.out.println(rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("nickname"));

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(rs, pstmt, conn);

}

}



[if !supportLists]1.20 [endif]20_JDBC的批处理操作

批处理:一批SQL一起执行


@Test

/**

*批处理基本操作

 */

public void demo1(){

Connection conn = null;

Statement stmt = null;

try{

//获得连接:

conn = JDBCUtils.getConnection();

//创建执行批处理对象:

stmt = conn.createStatement();

//编写一批SQL语句:

String sql1 = "create database test1";

String sql2 = "use test1";

String sql3 = "create table user(id int primary key auto_increment,name varchar(20))";

String sql4 = "insert into user values (null,'aaa')";

String sql5 = "insert into user values (null,'bbb')";

String sql6 = "insert into user values (null,'ccc')";

String sql7 = "update user set name = 'mmm' where id = 2";

String sql8 = "delete from user where id = 1";

//添加到批处理

stmt.addBatch(sql1);

stmt.addBatch(sql2);

stmt.addBatch(sql3);

stmt.addBatch(sql4);

stmt.addBatch(sql5);

stmt.addBatch(sql6);

stmt.addBatch(sql7);

stmt.addBatch(sql8);

//执行批处理:

stmt.executeBatch();

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(stmt, conn);

}

}

批量插入(使用PreparedStatement)

@Test

/**

*批量插入记录:

*需要在url后面拼接一个参数即可,效率高

         ?rewriteBatchedStatements=true

 */

public void demo2(){

//记录开始时间:

long begin = System.currentTimeMillis();

Connection conn = null;

PreparedStatement pstmt = null;

try{

//获得连接:

conn = JDBCUtils.getConnection();

//编写SQL语句:

String sql = "insert into user values (null,?)";

//预编译SQL:

pstmt = conn.prepareStatement(sql);

for(int i=1;i<=10000;i++){

pstmt.setString(1, "name"+i);

//添加到批处理

pstmt.addBatch();

//注意问题:

//执行批处理

if(i % 1000 == 0){

//执行批处理:

pstmt.executeBatch();

//清空批处理:

pstmt.clearBatch();

}

}

}catch(Exception e){

e.printStackTrace();

}finally{

JDBCUtils.release(pstmt, conn);

}

long end = System.currentTimeMillis();

System.out.println((end-begin));

}

1.21总结:

阐述什么是JDBC以及为什么要使用JDBC

独立完成使用JDBC核心API对数据库表记录的CRUD操作(重点)

完成JDBC工具类的抽取与改进(重点)

阐述什么是SQL注入漏洞并给出解决方法

独立完成使用JDBC的预编译对象进行CRUD操作(重点)

JDBC的批处理操作

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • JDBC简介 SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。JDBC...
    奋斗的老王阅读 1,507评论 0 51
  • JDBC概述 在Java中,数据库存取技术可分为如下几类:JDBC直接访问数据库、JDO技术、第三方O/R工具,如...
    usopp阅读 3,533评论 3 75
  • jdbc学习 认真的回顾一下jdbc。巩固一下知识。争取用最通俗的话来解释。 首先我们在编程中肯定是要用到数据库的...
    沉醉000阅读 251评论 0 0
  • 2017-6-12【能量世界1013】 桂林阳朔 陈艳霞 幼儿园放学后回到家,人极其的困倦,无力!能量虽然稳定,想...
    陈艳霞小树妈阅读 251评论 0 0
  • 她踩着高跟鞋疾走,清晨还有微凉,今天的天气应该很好,这样美好的念头也是一闪而过,地铁迎来高峰,人流拥着她停不下脚步...
    蒋栖子阅读 166评论 0 0