您的位置:首页 > 数据库

jdbc操作数据库

2016-07-08 11:18 357 查看
[align=left]JDBC全称为:Java DataBase Connectivity(java数据库连接)。[/align]
[align=left]SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。[/align]
[align=left]学习JDBC 技术目的,使用Java技术操作数据库中数据记录[/align]
[align=left] [/align]
[align=left]什么是驱动? 两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信[/align]
[align=left] [/align]
[align=left]如果没有JDBC,Java程序员需要面向各个数据库驱动接口编程,开发复杂 ; sun 公司提供一套统一JDBC接口规范,Java程序只需要使用JDBC就可以操作任何数据库,JDBC实现类由各个数据库厂商提供,[/align]
[align=left] [/align]
[align=left]学习JDBC[/align]
[align=left]1、学习JDK中自带JDBC接口规范 java.sql javax.sql[/align]
[align=left]DriverManager 驱动管理类[/align]
[align=left]Connection 连接接口[/align]
[align=left]Statement (PreparedStatement、CallableStatement) 数据库操作[/align]
[align=left]ResultSet 结果集接口[/align]
[align=left] [/align]
[align=left]2、必须在工程中引入不同数据库驱动实现[/align]
[align=left] [/align]
[align=left]JDBC体验[/align]
[align=left]编程从user表中读取数据,并打印在命令行窗口中。[/align]
[align=left]create table user([/align]
[align=left] id int primary key auto_increment,[/align]
[align=left] username varchar(20) unique not null,[/align]
[align=left] password varchar(20) not null,[/align]
[align=left] email varchar(40) not null[/align]
[align=left]);[/align]
[align=left] 一、搭建实验环境 :[/align]
[align=left] 1、在mysql中创建一个库,并创建user表和插入表的数据。[/align]
[align=left] 2、新建一个Java工程,并导入数据驱动。[/align]
[align=left]二、编写程序,在程序中加载数据库驱动[/align]
[align=left] DriverManager. registerDriver(Driver driver)[/align]
[align=left]三、建立连接(Connection)[/align]
[align=left] Connection conn = DriverManager.getConnection(url,user,pass);[/align]
[align=left]四、创建用于向数据库发送SQL的Statement对象,并发送sql[/align]
[align=left] Statement st = conn.createStatement();[/align]
[align=left] ResultSet rs = st.executeQuery(sql);[/align]
[align=left]五、从代表结果集的ResultSet中取出数据,打印到命令行窗口[/align]
[align=left]六、断开与数据库的连接,并释放相关资源[/align]
[align=left] [/align]
[align=left]JDBC API 详解(重点)[/align]
[align=left]DriverManager 类[/align]
[align=left]static void registerDriver(Driver driver) 注册一个JDBC驱动程序[/align]
[align=left]注意:DriverManager中可以同时注册多个JDBC驱动 例如:同时注册 mysql、oralce、db2 驱动 ,通过对JDBC URL分析,决定采用哪个驱动[/align]
[align=left]static Connection getConnection(String url, String user, String password) 根据jdbc url 和 用户名、密码获得一个数据库连接[/align]
[align=left] [/align]
[align=left]实际开发中,不推荐使用DriverManager.registerDriver 会导致驱动注册两次、会使得程序依赖 具体数据库API[/align]
[align=left]推荐使用 :Class.forName("com.mysql.jdbc.Driver"); 加载Driver类时完成驱动注册,使得程序不依赖MySQL的API[/align]
[align=left] [/align]
[align=left]***** 不要引入 与数据库相关 具体 API[/align]
[align=left] [/align]
[align=left]JDBC URL[/align]
[align=left]jdbc:mysql://localhost:3306/day13[/align]
[align=left]这里 jdbc: 是JDBC连接协议[/align]
[align=left]这里 mysql:// 是mysql数据库连接协议,JDBC子协议[/align]
[align=left]localhost:3306 主机和端口[/align]
[align=left]day13数据库[/align]
[align=left] [/align]
[align=left]常用数据库URL写法[/align]
[align=left]MYSQL jdbc:mysql://localhost:3306/day13[/align]
[align=left]ORACLE jdbc:oracle:thin:@localhost:1521:sid[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] [/align]
[align=left]创建数据表 users[/align]
[align=left]create table users([/align]
[align=left] id int primary key ,[/align]
[align=left] username varchar(20) unique not null,[/align]
[align=left] password varchar(20) not null,[/align]
[align=left] email varchar(40) not null[/align]
[align=left]);[/align]
[align=left] [/align]
[align=left]插入一些数据记录[/align]
[align=left]insert into users values(1,'zhangsan','123','zhangsan@itcast.cn');[/align]
[align=left]insert into users values(2,'lisi','123','lisi@itcast.cn');[/align]
[align=left]insert into users values(3,'wangwu','123','wangwu@itcast.cn');[/align]
[align=left] [/align]
[align=left]oracle中执行 insert update delete 后 必须使用commit 操作[/align]
[align=left] [/align]
[align=left]4) 在工程引入oracle的jdbc 驱动[/align]
[align=left]安装目录\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar[/align]
[align=left] [/align]
[align=left]5) 修改Oracle驱动类 oracle.jdbc.driver.OracleDriver 和 URL jdbc:oracle:thin:@localhost:1521:orcl[/align]
[align=left] [/align]
[align=left]MySQL 如果连接localhost:3306 可以省略[/align]
[align=left]jdbc:mysql://localhost:3306/day13 --------------- jdbc:mysql:///day11[/align]
[align=left]JDBCURL 可以通过?和& 携带参数[/align]
[align=left]常用属性:useUnicode=true&characterEncoding=UTF-8 ----------- 解决操作数据库乱码问题[/align]
[align=left] [/align]
[align=left]Connection 连接接口[/align]
[align=left]应用一:获得SQL的操作对象[/align]
[align=left]Statement conn.createStatement() 该对象可以将SQL发送给数据库进行执行[/align]
[align=left]PreparedStatement conn.prepareStatement(sql) 对SQL语句进行预编译,防止SQL注入[/align]
[align=left]CallableStatement conn.prepareCall(sql); 该对象可以调用数据库中存储过程 (以后Oracle学习)[/align]
[align=left] [/align]
[align=left]应用二:对数据库事务进行管理(明天)[/align]
[align=left]conn.setAutoCommit(boolean); 设置事务是否自动提交[/align]
[align=left]conn.commit(); 提交数据库事务[/align]
[align=left]conn.rollback(); 回滚数据库事务[/align]
[align=left]Statement 用于将SQL 发送给数据库 获得操作结果[/align]
[align=left]发送单条SQL[/align]
[align=left]executeUpdate 用于向数据库发送 insert update delete 语句,返回int 类型参数,代表影响记录行数[/align]
[align=left]executeQuery 用于向数据库发送 select 语句,返回ResultSet 结果集对象[/align]
[align=left]execute 用于数据库发送任何SQL语句(包括 DDL DML DCL) 返回boolean ,SQL执行结果是ResultSet 返回true,否则 false[/align]
[align=left] [/align]
[align=left]发送多条SQL[/align]
[align=left]addBatch(sql) 将SQL加入批处理队列[/align]
[align=left]executeBatch() 执行队列中所有SQL语句 ,一次性向数据库发送多条SQL[/align]
[align=left] [/align]
[align=left]使用ResultSet 遍历结果集[/align]
[align=left]while(rs.next()){[/align]
[align=left] // 根据数据库内部 列类型,选择相应 getXXX方法[/align]
[align=left] int ---- getInt[/align]
[align=left] varchart ---- getString[/align]
[align=left] date ----- getDate[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]在java.sql 定义Date、Time 、TimeStamp 对应数据库中 date time timestamp 类型 --------------- java.sql.Date/Time/TimeStamp 都是 java.util.Date 子类[/align]
[align=left]java.sql.Date 只有日期没有时间[/align]
[align=left]java.sql.Time 只有时间没有日期[/align]
[align=left]java.sql.TimeStamp 既有日期也有时间[/align]
[align=left] [/align]
[align=left]getXXX 有两种写法 第一种 getString(index) 结果集中列索引 第二种 getString(列名)[/align]
[align=left] [/align]
[align=left]思考:如果SQL语句可能会返回一行数据,也可能查不到任何记录时,代码应该怎么写? ----- 用于登陆[/align]
[align=left]if(rs.next()){[/align]
[align=left] // 查到了数据[/align]
[align=left]}else{[/align]
[align=left] // 没有查到数据[/align]
[align=left]}[/align]
[align=left] [/align]
[align=left]ResultSet 高级应用 ---- 滚动结果集[/align]
[align=left]Connection 接口的 createStatement() 返回Statement对象,操作SQL后 产生ResultSet 默认执行next 向前滚动,不支持在滚动中对数据进行修改 (只读不执行滚动)[/align]
[align=left]Connection 接口还提供 createStatement(int resultSetType, int resultSetConcurrency) 在创建Statement对象 设置结果集类型,并发策略[/align]
[align=left] [/align]
[align=left]结果集类型[/align]
[align=left]ResultSet.TYPE_FORWARD_ONLY 只能向前,只能调用next 不能向回滚动[/align]
[align=left]ResultSet.TYPE_SCROLL_INSENSITIVE 支持结果集向回滚动,不能查看修改结果[/align]
[align=left]ResultSet.TYPE_SCROLL_SENSITIVE 支持结果集向回滚动,查看修改结果[/align]
[align=left] [/align]
[align=left]结果集并发策略[/align]
[align=left]ResultSet.CONCUR_READ_ONLY 只读[/align]
[align=left]ResultSet.CONCUR_UPDATABLE 支持修改[/align]
[align=left] [/align]
[align=left]常见三种组合[/align]
[align=left]ResultSet.TYPE_FORWARD_ONLY 和 ResultSet.CONCUR_READ_ONLY (默认) 只读不支持向回滚动[/align]
[align=left]ResultSet.TYPE_SCROLL_INSENSITIVE 和 ResultSet.CONCUR_READ_ONLY 只读,支持向回滚动[/align]
[align=left]ResultSet.TYPE_SCROLL_SENSITIVE 和 ResultSet.CONCUR_UPDATABLE 支持向回滚动,支持对数据修改[/align]
[align=left]JDBC完成CRUD示例[/align]
[align=left]编写对user表 增删改查程序,从重复代码中提取公共方法 JDBCUtils 工具类 ,将数据库连接参数写入properties 配置文件[/align]
[align=left] [/align]
[align=left]示例代码[/align]
[align=left] [/align]
[align=left]DAO模式[/align]
[align=left]DAO模式(Data Access Object 数据访问对象):在持久层通过DAO将数据源操作完全封装起来,业务层通过操作Java对象,完成对数据源操作[/align]
[align=left]* 业务层无需知道数据源底层实现 ,通过java对象操作数据源[/align]
[align=left] [/align]
[align=left]DAO模式结构 :[/align]
[align=left]1、数据源(MySQL数据库)[/align]
[align=left]2、Business Object 业务层代码,调用DAO完成 对数据源操作[/align]
[align=left]3、DataAccessObject 数据访问对象,持久层DAO程序,封装对数据源增删改查,提供方法参数都是Java对象[/align]
[align=left]4、TransferObject 传输对象(值对象) 业务层通过向数据层传递 TO对象,完成对数据源的增删改查[/align]
[align=left] [/align]
[align=left]DAO登录示例[/align]
[align=left] [/align]
[align=left]使用三层结构和DAO模式登陆[/align]
[align=left]cn.itcast.web ---- 表现层[/align]
[align=left]cn.itcast.service ---- 业务层[/align]
[align=left]cn.itcast.dao ----- 持久层[/align]
[align=left]cn.itcast.domain ----- 对应数据表实体类 TO对象[/align]
[align=left] [/align]
[align=left]1、编写login.jsp 登陆表单,提交 /day11/login[/align]
[align=left]2、编写LoginServlet 获得请求数据,调用业务层UserService[/align]
[align=left]3、UserService编写业务逻辑,调用数据层UserDAO 返回结果[/align]
[align=left]4、在LoginServlet获得结果,判断结果跳转页面[/align]
[align=left] [/align]
[align=left]示例代码[/align]
[align=left] [/align]
[align=left]SQL注入[/align]
[align=left]由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些SQL 关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击。[/align]
[align=left] [/align]
[align=left]String sql = select * from user where username ='' and password ='' ;[/align]
[align=left] [/align]
[align=left]例如:[/align]
[align=left]一、输入 username: 老李' or '1'='1 password 随意[/align]
[align=left]select * from user where username ='老李' or '1'='1' and password ='';[/align]
[align=left]* and 优先级 执行 高于 or[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]解决SQL注入:使用PreparedStatement 取代 Statement[/align]
[align=left]PreparedStatement 解决SQL注入原理,运行在SQL中参数以?占位符的方式表示[/align]
[align=left]select * from user where username = ? and password = ? ;[/align]
[align=left]将带有?的SQL 发送给数据库完成编译 (不能执行的SQL 带有?的SQL 进行编译 叫做预编译),在SQL编译后发现缺少两个参数[/align]
[align=left]PreparedStatement 可以将? 代替参数 发送给数据库服务器,因为SQL已经编译过,参数中特殊字符不会当做特殊字符编译,无法达到SQL注入的目的[/align]
[align=left] [/align]
[align=left]问题:[/align]
[align=left]SQL注入原理是什么?[/align]
[align=left] 1.在输入时连接一个永远为真的一个值[/align]
[align=left] 2.使用mysql 中的 – 注释[/align]
[align=left]为什么PreparedStatement 可以防止SQL注入 ?[/align]
[align=left] 因为它对sql语句进行预编译。[/align]
[align=left] [/align]
[align=left] [/align]
[align=left]JDBC处理大数据[/align]
[align=left]在实际开发中,程序需要把大文本 Text 或二进制数据 Blob保存到数据库。[/align]
[align=left]Text是mysql叫法,Oracle中叫Clob[/align]
[align=left] [/align]
[align=left]基本概念:大数据也称之为LOB(Large Objects),LOB又分为:[/align]
[align=left]•clob和blob[/align]
[align=left]•clob用于存储大文本。Text[/align]
[align=left]•blob用于存储二进制数据,例如图像、声音、二进制文等。[/align]
[align=left] [/align]
[align=left]对MySQL而言只有blob,而没有clob,mysql存储大文本采用的是Text,Text和blob分别又分为:[/align]
[align=left]•TINYTEXT(255)、TEXT(64k)、MEDIUMTEXT(16M)和LONGTEXT(4G)[/align]
[align=left]•TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB[/align]
[align=left]JDBC进行批处理[/align]
[align=left]业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。[/align]
[align=left]实现批处理有两种方式,第一种方式:[/align]
[align=left]•Statement.addBatch(sql)[/align]
[align=left]•执行批处理SQL语句[/align]
[align=left]•executeBatch()方法:执行批处理命令[/align]
[align=left]•clearBatch()方法:清除批处理命令[/align]
[align=left]采用Statement.addBatch(sql)方式实现批处理:[/align]
[align=left]•优点:可以向数据库发送多条不同的SQL语句。[/align]
[align=left]•缺点:[/align]
[align=left]SQL语句没有预编译。[/align]
[align=left]当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:[/align]
[align=left] Insert into user(name,password) values(‘aa’,’111’);[/align]
[align=left] Insert into user(name,password) values(‘bb’,’222’);[/align]
[align=left] Insert into user(name,password) values(‘cc’,’333’);[/align]
[align=left] Insert into user(name,password) values(‘dd’,’444’);[/align]
[align=left] [/align]
[align=left]实现批处理的第二种方式:[/align]
[align=left]•PreparedStatement.addBatch()[/align]
[align=left] [/align]
[align=left]采用PreparedStatement.addBatch()实现批处理[/align]
[align=left]•优点:发送的是预编译后的SQL语句,执行效率高。[/align]
[align=left]•缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。[/align]
[align=left] [/align]
[align=left]注:[/align]
[align=left]默认使用PreparedStatement是不能执行预编译的,这需要在url中给出useServerPrepStmts=true参数(MySQL Server 4.1之前的版本是不支持预编译的,而Connector/J在5.0.5以后的版本,默认是没有开启预编译功能的)。[/align]
[align=left]例如:jdbc:mysql://localhost:3306/test?useServerPrepStmts=true[/align]
[align=left]这样才能保证mysql驱动会先把SQL语句发送给服务器进行预编译,然后在执行executeQuery()时只是把参数发送给服务器。[/align]
[align=left] [/align]
[align=left]当使用不同的PreparedStatement对象来执行相同的SQL语句时,还是会出现编译两次的现象,这是因为驱动没有缓存编译后的函数key,导致二次编译。如果希望缓存编译后函数的key,那么就要设置cachePrepStmts参数为true。例如:[/align]
[align=left]jdbc:mysql://localhost:3306/test?useServerPrepStmts=true&cachePrepStmts=true[/align]
[align=left] [/align]
[align=left]MySQL的批处理也需要通过参数来打开:rewriteBatchedStatements=true[/align]
[align=left]例如:jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true[/align]
[align=left] [/align]
[align=left]Mysql驱动要使用mysql-connector-java-5.1.13以上[/align]
[align=left] [/align]
[align=left][/align]
[align=left][/align]
[align=left]importjava.sql.Connection;[/align]
[align=left]import java.sql.DriverManager;[/align]
[align=left]import java.sql.SQLException;[/align]
[align=left]import java.sql.Statement;[/align]
[align=left] [/align]
[align=left]import org.gjt.mm.mysql.Driver;[/align]

// 注册驱动
DriverManager.registerDriver(new Driver());

// 连接测试
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb1", "root", "root");
// 通过连接对象 创建操作sql语句对象 Statement
Statement st = conn.createStatement();
// 操作的sql语句
String t_sql = "select * from employee";
// 执行sql 返回 查询结果集 ResultSet;
java.sql.ResultSet rs = st.executeQuery(t_sql);

// 遍历结果集
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String gender = rs.getString("gender");
System.out.println("流水编号:" + id + ", 姓名:" + name + " ,职位:" + gender
+ ";");
}

[align=left] // 释放资源[/align]
[align=left] rs.close();[/align]
[align=left] st.close();[/align]
[align=left] conn.close();[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: