了解历史----
在以前如果想要java连结数据库需要编写不同的驱动(不同的连接地址)来完成对各自不同的数据库的连接,非常麻烦,于是考虑到java语言的快速发展以及连接数据库的方便性,各家数据库厂商找java语言开发人员商量如何用java快速连结自家数据库,
这一商量-----java说都要符合我制定的标准 jdbc 于是就有了java现系统中的数据库连结方式;
说了这么多,还是直接上图来的直观,在以前的老版本教程中
连接数据库的方式需要需要配置文件,
jdbc----- 数据库驱动厂商单独提供,
另连接地址格式也不统一
如老教程中-----
public class ConnectJDBC{
//驱动程序就是之前在classpath中配置的jdbc的驱动程序的jar包中
public static final String DBDRIVER="oracle.jdbc.driver.OracleDriver";
//连接地址是由各个数据库生产商单独提供的,所以需要单独记住
public static final String DBURL="jdbc:oracle:thin:@localhost:1521:orcl";
现在就比较简便了;
连接jdbc
import java.sql.*;
public class test001 {
public static void main(String[] args) throws SQLException {
//加载依赖
Driver driver = new com.mysql.cj.jdbc.Driver();
//注册驱动
DriverManager.registerDriver(driver);
//得到连接----连接参数---连接地址,用户名和密码
final String URL = "jdbc:mysql://localhost:3306/gavin";
final String USER = "gavin";
final String PASSWORD = "gavin";
Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
//创建描述以用来操作数据库
Statement statement = connection.createStatement();
//接着操作数据库--要准备sql语句
String sql = "insert into test values(1,'张三',18);";
//执行该语句
int rows = statement.executeUpdate(sql);
System.out.println("插入了===" + rows + "行数据");
//释放资源
statement.close();
connection.close();
}
}
在操作过程中可能会遇到连接失败的情况,可能的原因是数据库URL的错误
/* * url:统一资源定位符 定位我们要连接的数据库的
* 1协议 jdbc:mysql
* 2IP 127.0.0.1/localhost
* 3端口号 3306
* 4数据库名字 mydb
* 5参数
* 协议://ip:端口/资源路径?参数名=参数值&参数名=参数值&....
* jdbc:mysql://127.0.0.1:3306/mydb
* */
String url="jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
useSSL----表示是否用ssl加密传输=====false一般不选择加密
useUnicode=======表示用Unicode编码格式-------true
characterEncoding=表示字符编码格式-----用UTF-8
serverTimeZone==表示时区-------国内用Asia/Shanghai
查看Driver的源码
可以发现只要Driver这个类加载到内存中静态代码块就帮助我们完成了驱动的注册;所以上述加载驱动的时候完全没有必要,只需要通过反射将该类加载到内存就可以了;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class test002 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class aClass = Class.forName("com.mysql.cj.jdbc.Driver");//加载完毕接着就注册了
final String URL = "jdbc:mysql://localhost:3306/gavin";
final String USER = "gavin";
final String PASSWORD = "gavin";
Connection connection= DriverManager.getConnection(URL,USER,PASSWORD);
String sql="update test set name='Gavin' where id=1 ;";
Statement statement = connection.createStatement();
int rows = statement.executeUpdate(sql);
System.out.println("影响了----"+rows+"条数据");
statement.close();
connection.close();
}
}
常见错误原因总结
- Access denied for user ‘gavin’@‘localhost’ (using password: YES)------用户名/密码输入错误
- Communications link failure-----数据库连接错误,可能是URL配置错误;
- Exception in thread “main” java.lang.ClassNotFoundException: com.mysql.jdbc2.Driver
-----Driver配置错误,导入正确的Driver------com.mysql.cj.jdbc.Driver(); - Exception in thread “main” java.sql.SQLException:
No suitable driver found for jbdc:mysql://127.0.0.1:3306/stumgr
----可能也是URL错误; - Public Key Retrieval is not allowed---- 这种情况一般是在密码错的时候出现;
产生的原因:
数据库密码加密规则与当前不符,可以在连接中通过 ServerRSAPublicKeyFile 指定服务器的 RSA 公钥,或者AllowPublicKeyRetrieval=True参数以允许客户端从服务器获取公钥;
jdbc执行查询操作-------
import java.sql.*;
public class test002 {
private final static String URL = "jdbc:mysql://localhost:3306/gavin";
private final static String USER = "gavin";
private final static String PASSWORD = "955945";
public static void main(String[] args) {
searchT();
}
public static void searchT(){
ResultSet resultSet;
Statement statement = null;
Connection connection = null;
int id;
String name;
int age;
try {
Class aClass = Class.forName("com.mysql.cj.jdbc.Driver");//加载完毕接着就注册了
connection = DriverManager.getConnection(URL, USER, PASSWORD);//获得连接
//查询语句
String sql = "select * from test where id=6;";
//获得执行器
statement = connection.createStatement();
//执行后返回结果
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
id = resultSet.getInt("id");
name = resultSet.getString("name");
age = resultSet.getByte("age");
System.out.println(id + "-----" + name + "------" + age);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != statement) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (null != statement) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
将以上代码做一个汇总和优化----
package com.test.jdbc;
import java.sql.*;
public class SearchTest {
private final static String URL = "jdbc:mysql://localhost:3306/gavin?useSSL=false&useUnicode=true&characterEncode=UTF-8&serverTimezone=Asia/Shanghai";
private final static String USER = "gavin";
private final static String PASSWORD = "gavin";
private static String SQL = "insert into test values(11,'吴哥',34),(23,'Gavin',19);";
private static String sql = "select * from test ;";
private static Connection connection = null;
private static Statement statement = null;
private static ResultSet resultSet = null;
public static void main(String[] args) {
createLink();// 创建连接
try {
statement = connection.createStatement();//执行器
int rows = statement.executeUpdate(SQL);//执行
System.out.println("影响了--" + rows + "行数据");
int id;
String name;
int age;
resultSet = statement.executeQuery(sql);
while ( resultSet.next()) {
id= resultSet.getInt("id");
name = resultSet.getString("name");
age= resultSet.getInt("age");
System.out.println(id + "-----" + name + "-----" + age);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
closeLink(resultSet,statement, connection);
}
}
static void closeLink(ResultSet resultSet,Statement statement, Connection connection) {
if(null!= statement){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(null!= connection) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(null!= resultSet) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void createLink() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");//导入驱动方式二
connection = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
}
}
问题来了,如何将查到的数据返回给客户端呢???
1,将查到的数据包装成类----
2,如果取用类中的数据—通过实例化对象来调用()set,get方法
3,既然能发送出去,就要实现序列化
下面开搞-----
定义一个类-----
定义以前的要求--------------------->>>>>>>>
1,类名要和表名一致,
2,类中属性要和字段名一致(最好是,因为见名知意)
3,类中属性要和字段属性相匹配,最好是用包装类来接收;
4,类中必须要有空参构造
package com.test.jdbc.SendData;
import java.io.Serializable;
import java.util.Date;
public class EMP implements Serializable {
private Integer empno;
.................封装参数...........
public EMP() {
.........空参构造.........
}
public EMP(Integer empno, String ename, String job, Integer mgr, Date date, Double sal, Double comm, Integer deptno) {
..........................
}
.......................覆写tostring...............
@Override
public String toString() {
return "EMP{" +
...........
'}';
}
}
封装完毕后,开始
package com.test.jdbc.SendData;
import com.test.jdbc.SearchTest;
import javax.xml.crypto.Data;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class empJdbc {
private final static String URL = "jdbc:mysql://localhost:3306/gavin";
private final static String USER = "gavin";
private final static String PASSWORD = "955945";
private static String sql="select * from emp;";
static Connection connection=null;
static Statement statement=null;
static ResultSet resultSet=null;
static List <EMP>list = new ArrayList<EMP>();
public List searchAll(){
try {
connection = DriverManager.getConnection(URL, USER, PASSWORD);
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
while(resultSet.next()){
int empno=resultSet.getInt("EMPNO");
...........获取对应的字段然后装进emp对象中........
EMP emp=new EMP(empno,ename,job,mgr,hiredate,sal,comm,deptno);//
list.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//释放资源
SearchTest.closeLink(resultSet,statement,connection);//在SearchTest类中有释放资源的静态方法
}
return list;//返回值
}
}
网络化-----发送接收…
package com.test.jdbc.SendData;
--导入相关包中的类
import java.util.List;
............
public class Client {
public static void main(String[] args) throws IOException, ClassNotFoundException {//有异常向外抛
Socket client =null;
client=new Socket("localhost",8888);//绑定客户端
InputStream ops = client.getInputStream();//得到服务器发送过来的信息
ObjectInputStream ois=new ObjectInputStream(ops);//由于是对象,所以用object接收
List <EMP>list = (ArrayList<EMP>)ois.readObject();//传过来的是一个List对象
迭代方法---foreach
for (EMP e:list
) {
System.out.println(e);
}
//释放资源
ois.close();
ops.close();
client.close();
}
}
package com.test.jdbc.SendData;
--导入相关包中的类
import java.io.IOException;
..........
public class serverSocketC {
public static void main(String[] args) throws IOException {
ServerSocket server=null;
server=new ServerSocket(8888);//服务器开启了8888端口
Socket accept = server.accept();//服务器接收到客户端请求
OutputStream ops = accept.getOutputStream();//服务器向外发送数据
ObjectOutputStream oos= new ObjectOutputStream(ops);
oos.writeObject(new empJdbc().searchAll());//发送数据
//释放资源
oos.close();
ops.close();
server.close();
}
}
运行后结果-----