使用JDBC连接MySQL数据库的一个基本案例
JDBC的概念(摘自百度百科)
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。
将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言“编写一次,处处运行”的优势。
JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。
简单地说,JDBC 可做三件事:与数据库建立连接、发送 操作数据库的语句并处理结果。
JDBC的相关架构
jdbc的作用位置:
jdbcAPI:
jdbc相关URL:
JDBC的构建步骤:
注意:
1)测试数据程序之前,一定要记得打开数据库所在计算机的mySQL服务。不然浪费的时间不可限量。
2)一定记得导入mySQL的jar包。
3)最好将Connection对象设置成单例模式,以防止数据库访问量过大时,造成内存崩溃。
4)使用Class对象的forName()方法,要在静态方法中或者静态块中。
5)记得相关数据库操作后进行释放内存,清理环境。
6)PreparedStatement继承自Statement,所以Statement的相关方法,PreparedStatement可以调用。同时PreparedStatement很强大,推荐多使用它。
7)要将相关释放内存的语句放在try...catch语句中的finally中,以防止try块中的语句执行失败而相关内存没有得到释放。
展示案例
package com.java_JDBC; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class JDBC_test { private static String Driver="com.mysql.jdbc.Driver"; //数据库驱动
//连接数据库的URL地址
private static String url="jdbc:mysql://localhost:3306/hellojdbc?useUnicode=true&characterEncoding=UTF-8";
private static String username="root";//数据库连接用户名
private static String password="123456";//数据库连接密码 private static Connection conn=null;//数据库连接对象
private static Statement stat=null;//语句陈述对象
private static ResultSet rs=null;//结果数据集
private static PreparedStatement pst=null;//预编译语句 //使用静态块的方式加载驱动
static {
try {
//调用Class对象的静态forName()方法加载数据库驱动类
Class.forName(Driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} } //使用单例模式返回数据库连接对象
public static Connection getConnection() throws SQLException{
if(conn==null){
conn=DriverManager.getConnection(url, username, password);
return conn;
}
return conn; } //测试数据库连接是否正常
public static void isConnect() throws SQLException{
Connection con=getConnection();
if(con!=null)
System.out.println("数据库连接正常");
else
System.out.println("数据库连接失败");
} //查询全部数据库表中所有信息
public static void QueryToAll(){
try {
stat=conn.createStatement();//由连接获取语句陈述对象
rs=stat.executeQuery("select * from roster");//获取结果集信息
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+",age:"+rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //按名字查找数据库中信息
public static void QueryForName(String name){
try {
pst = conn.prepareStatement("select * from roster where name=?");//获取预编译语句
pst.setString(1, name);//设置预编译语句参数
rs=pst.executeQuery();//执行预编译语句,获取结果数据集
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+",age:"+rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //增加数据库中数据信息
public static void insert(){
try {
String sql="insert into roster(id,name,age) values ('4','zhangsan','14')";
stat=conn.createStatement();
int count=stat.executeUpdate(sql);//执行语句陈述对象的更新操作
System.out.println("插入操作成功,插入信息条数为"+count);
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //修改数据库中数据信息
public static void alter(){
try {
String sql="update roster set age=12 where name='zhangsan'";
stat=conn.createStatement();
int count = stat.executeUpdate(sql);//执行语句陈述对象的更新操作
System.out.println("修改操作成功,修改信息条数为"+count);
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //删除数据库中数据信息
public static void delete(){
try {
String sql="delete from roster where name='zhangsan'";
stat=conn.createStatement();
int count=stat.executeUpdate(sql);//执行语句陈述对象的更新操作
System.out.println("删除操作成功,删除信息条数为"+count);
} catch (SQLException e) {
e.printStackTrace();
}finally{
clean();
} } //释放内存,清理环境
public static void clean(){
try {
if(rs!=null)
rs.close();
if(pst!=null)
pst.close();
if(stat!=null)
stat.close(); //不能关闭单例模式下的connection连接对象,否则当一个数据库操作完成后便不能进行其他数据库操作
// if(conn!=null)
// conn.close();
// } catch (SQLException e) {
e.printStackTrace();
} } public static void main(String[] args) throws SQLException {
isConnect();
QueryForName("Bob");
System.out.println("--------------------------------------");
QueryToAll();
System.out.println("--------------------------------------");
insert();
System.out.println("--------------------------------------");
QueryToAll();
System.out.println("--------------------------------------");
alter();
System.out.println("--------------------------------------");
QueryToAll();
System.out.println("--------------------------------------");
delete();
System.out.println("--------------------------------------");
QueryToAll(); } }
执行结果:
使用JDBC常遇到的问题:
问题一:
编写sql语言的过滤条件太弱,导致一次读出过多的数据记录。
解决方法:修改或增加过滤条件。
问题二:
海量数据读取,可能造成溢出异常。(数据条数过多)
分析原因:读出的数据量超过了JVM的内存限制。
解决方法:使用“游标”。每次只读出来一部分数据记录进行处理,处理完成以后再对下一部分数据记录进行读取处理。
如何使用“游标”?
1)首先需要在数据库的URL中增加一个参数:
相关代码示例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class JDBC_fetch { private static String Driver="com.mysql.jdbc.Driver";
private static String url="jdbc:mysql://localhost:3306/hellojdbc?useCursorFetch=true";
private static String username="root";//数据库连接用户名
private static String password="123456";//数据库连接密码
private static PreparedStatement pst=null;
private static ResultSet rs=null; private static Connection conn=null;
static {
try {
Class.forName(Driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} public static void fetchTest(){
try {
conn=DriverManager.getConnection(url, username, password);
pst=conn.prepareStatement("select * from roster");
pst.setFetchSize(1);//设置游标大小
rs=pst.executeQuery();
while(rs.next()){
System.out.println("id:"+rs.getInt("id")+",name:"+rs.getString("name")+",age:"+rs.getInt("age"));
} } catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public static void main(String[] args) { fetchTest(); }
如上面游标大小设置,JDBC就会一次读取一条记录,处理完再读取下一条记录。
在本案例中输出效果和不设置游标的结果是相同的。
问题三:
读取数据库表大字段,例如博客,图片等等。(单个数据量所占内存过大)
解决方法:
使用流方式。将数据以流的方式,每次读取一段。
相关代码实例:
while(rs.next()){
//获取对象流
InputStream in=rs.getBinaryStream("blog");
//将对象流写入文件
File f=new File(FILE_URL);
OutputStream out=null;
out=new FileOutStream(f);
int temp=0;
while((temp=in.read())!=-1)
out.write(temp);//边读边写
}
in.close();
out.close();
问题四:
海量数据插入数据库,一条一条地插入————太慢
分析原因:每一条数据的插入都需要客户端到服务器的交互,每一次都存在时间消耗和代价。
解决方法:
批处理。一次提交多条sql语句,节省网络开销。
怎么进行批处理?
相关代码示例:
//批处理
Statement stmt=conn.createStatement();
for(String user:users){
stmt.addBatch("insert into roster(name) values("+user+")");
}
stmt.executeBatch();
stmt.clearBatch();
问题五:
中文乱码的问题。
解决方法:
在数据库URL中加入“characterEncoding=UTF-8”
private static String url="jdbc:mysql://localhost:3306/hellojdbc?useUnicode=true&characterEncoding=UTF-8";
参考博客:
https://www.cnblogs.com/erbing/p/5805727.html
https://www.cnblogs.com/wuziyue/p/4827295.html
使用JDBC连接MySQL数据库的一个基本案例的更多相关文章
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- Crystal Reports 2008(水晶报表) JDBC连接mysql数据库
在本blog中,主要介绍的是Crystal Reports 2008使用JDBC连接mysql数据库. 在连接之间,首先要确认你电脑上面都安装了mysql数据库. 其次,就是jdbc连接数据时候所使用 ...
- JDBC连接MySQL数据库及演示样例
JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...
- JDBC连接MySQL数据库及示例
JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一 ...
- java用JDBC连接MySQL数据库的详细知识点
想实现java用JDBC连接MySQL数据库.需要有几个准备工作: 1.下载Connector/J的库文件,下载Connector/J的官网地址:http://www.mysql.com/downlo ...
- 分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)
分页查询信息 使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目 ...
- JDBC——使用JDBC连接MySQL数据库
在JDBC--什么是JDBC一文中我们已经介绍了JDBC的基本原理. 这篇文章我们聊聊如何使用JDBC连接MySQL数据库. 一.基本操作 首先我们需要一个数据库和一张表: CREATE DATABA ...
- ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库
1.MySQL存储过程 1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if while)等等 的sql语句 1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...
- JDBC连接MySQL数据库代码
******************************************************1********************************************* ...
随机推荐
- Python爬虫-萌妹子图片
最近发现一个可以看图的地方,一张张翻有点累,毕竟只有一只手(难道鼠标还能两只手翻?).能不能下到电脑上看呢,毕竟不用等网速,还可以预览多张,总之很方便,想怎么就怎么,是吧? 刚好这几天在学python ...
- compose函数
compose函数 在学习redux源码的时候看到了其中的工具函数compose,compose函数的作用就是组合函数,依次组合传入的函数: 后一个函数作为前一个函数的参数 最后一个函数可以接受多个参 ...
- Android项目创建.prorperties配置文件和调用方法
刚接触Android开发不久,今天写项目发现里面的可变参数有点多,(主要是服务器访问路径), 如果路径改变或者改名字了的话,若都写在代码里,岂不是要炸了? 我想到了Java项目里的有个.prorper ...
- Python编程Day6——元组类型、字典类型、集合
一.元组类型(tuple) 1.用途:记录多个值,当多个值没有改变的需求此时元组更为合适 2.定义:在()内用逗号分隔开多个任意类型的值(参数为for可以循环的对象) 3.常用操作: 索引(正取向+反 ...
- 不得不提的volatile及指令重排序(happen-before)
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- github提交代码contributions不显示小绿块
问题描述: 最近发现一个问题就是不管是提交新增的代码还是修改后提交的代码在github的contributions上都不显示贡献小绿块. 于是我在 github help 里面找到了答案: 官方链接如 ...
- API防重放机制
说说API的防重放机制 我们在设计接口的时候,最怕一个接口被用户截取用于重放攻击.重放攻击是什么呢?就是把你的请求原封不动地再发送一次,两次...n次,一般正常的请求都会通过验证进入到正常逻辑中,如果 ...
- leetcode — valid-number
/** * * Source : https://oj.leetcode.com/problems/valid-number/ * * * Validate if a given string is ...
- MFC原理第四讲.动态创建机制
MFC原理第四讲.动态创建机制 一丶要学习的知识点以及简介 动态创建是什么意思? 动态创建其实就是跟C++的new一样.都是创建对象.但是规避了C++语法的缺陷. 例如: char * ClassNa ...
- Windows编程之模块遍历(C++实现)
Windows编程之模块遍历 PS: 主要扣代码使用,直接滑动到最下面使用. 遍历模块需要几个API,和一个结构体 1.创建进程快照 2.遍历首次模块 3.继续下次遍历 4.模块信息结构体 API 分 ...