Java MySQL 连接

本章节我们为大家介绍 Java 如何使用 使用 JDBC 连接 MySQL 数据库。

Java 连接 MySQL 需要驱动包,最新版下载地址为:http://dev.mysql.com/downloads/connector/j/,解压后得到jar库文件,然后在对应的项目中导入该库文件。

本实例使用的是 Eclipse,导入 jar 包:

Java MySQL 连接 - 图1

MySQL 8.0 以上版本的数据库连接有所不同:

  • 1、MySQL 8.0 以上版本驱动包版本
  • 2、com.mysql.jdbc.Driver 更换为com.mysql.cj.jdbc.Driver。
  • MySQL 8.0 以上版本不需要建立 SSL 连接的,需要显示关闭。
  • 最后还需要设置 CST。

加载驱动与连接数据库方式如下:

  1. Class.forName("com.mysql.cj.jdbc.Driver");
  2. conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test_demo?useSSL=false&serverTimezone=UTC","root","password");

创建测试数据

接下来我们在 MySQL 中创建 javatest 数据库,并创建 websites 数据表,表结构如下:

  1. CREATE TABLE `websites` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `name` char(20) NOT NULL DEFAULT '' COMMENT '站点名称',
  4. `url` varchar(255) NOT NULL DEFAULT '',
  5. `alexa` int(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名',
  6. `country` char(10) NOT NULL DEFAULT '' COMMENT '国家',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

插入一些数据:

  1. INSERT INTO `websites` VALUES ('1', 'Google', 'https://www.google.cm/', '1', 'USA'), ('2', '淘宝', 'https://www.baidu.com/', '13', 'CN'), ('3', '百度', 'http://www.weibo.com', '5892', ''), ('4', '微博', 'http://weibo.com/', '20', 'CN'), ('5', 'Facebook', 'https://www.facebook.com/', '3', 'USA');

连接数据库

以下实例使用了 JDBC 连接 MySQL 数据库,注意一些数据如用户名,密码需要根据你的开发环境来配置:

MySQLDemo.java 文件代码:

  1. package com.java.test;
  2. import java.sql.*;
  3. public class MySQLDemo {
  4. // MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL
  5. static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
  6. static final String DB_URL = "jdbc:mysql://localhost:3306/javatest";
  7. // MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL
  8. //static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
  9. //static final String DB_URL = "jdbc:mysql://localhost:3306/javatest?useSSL=false&serverTimezone=UTC";
  10. // 数据库的用户名与密码,需要根据自己的设置
  11. static final String USER = "root";
  12. static final String PASS = "123456";
  13. public static void main(String[] args) {
  14. Connection conn = null;
  15. Statement stmt = null;
  16. try{
  17. // 注册 JDBC 驱动
  18. Class.forName(JDBC_DRIVER);
  19. // 打开链接
  20. System.out.println("连接数据库...");
  21. conn = DriverManager.getConnection(DB_URL,USER,PASS);
  22. // 执行查询
  23. System.out.println(" 实例化Statement对象...");
  24. stmt = conn.createStatement();
  25. String sql;
  26. sql = "SELECT id, name, url FROM websites";
  27. ResultSet rs = stmt.executeQuery(sql);
  28. // 展开结果集数据库
  29. while(rs.next()){
  30. // 通过字段检索
  31. int id = rs.getInt("id");
  32. String name = rs.getString("name");
  33. String url = rs.getString("url");
  34. // 输出数据
  35. System.out.print("ID: " + id);
  36. System.out.print(", 站点名称: " + name);
  37. System.out.print(", 站点 URL: " + url);
  38. System.out.print("\n");
  39. }
  40. // 完成后关闭
  41. rs.close();
  42. stmt.close();
  43. conn.close();
  44. }catch(SQLException se){
  45. // 处理 JDBC 错误
  46. se.printStackTrace();
  47. }catch(Exception e){
  48. // 处理 Class.forName 错误
  49. e.printStackTrace();
  50. }finally{
  51. // 关闭资源
  52. try{
  53. if(stmt!=null) stmt.close();
  54. }catch(SQLException se2){
  55. }// 什么都不做
  56. try{
  57. if(conn!=null) conn.close();
  58. }catch(SQLException se){
  59. se.printStackTrace();
  60. }
  61. }
  62. System.out.println("Goodbye!");
  63. }
  64. }

以上实例执行输出结果如下:

  1. 连接数据库...
  2. 实例化Statement对...
  3. ID: 1, 站点名称: Google, 站点 URL: https://www.google.com/
  4. ID: 2, 站点名称: 淘宝, 站点 URL: https://www.taobao.com/
  5. ID: 3, 站点名称: 百度, 站点 URL: https://www.baidu.com/
  6. ID: 4, 站点名称: 微博, 站点 URL: https://www.weibo.com/
  7. ID: 5, 站点名称: Facebook, 站点 URL: https://www.facebook.com/
  8. Goodbye!

DAO 模式

DAO (DataAccessobjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。通俗来讲,就是将数据库操作都封装起来。

对外提供相应的接口 在面向对象设计过程中,有一些"套路”用于解决特定问题称为模式。 DAO 模式提供了访问关系型数据库系统所需操作的接口,将数据访问和业务逻辑分离对上层提供面向对象的数据访问接口。

从以上 DAO 模式使用可以看出,DAO 模式的优势就在于它实现了两次隔离。

  • 1、隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用DAO方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了藕合性,提高了可复用性。

  • 2、隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加 DAO 接口的新实现类即可,原有 MySQ 实现不用修改。这符合 "开-闭" 原则。该原则降低了代码的藕合性,提高了代码扩展性和系统的可移植性。

一个典型的DAO 模式主要由以下几部分组成。

  • 1、DAO接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现。

  • 2、DAO 实现类: 针对不同数据库给出DAO接口定义方法的具体实现。

  • 3、实体类:用于存放与传输对象数据。

  • 4、数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。

DAO 接口

  1. public interface PetDao {
  2. /**
  3. * 查询所有宠物
  4. */
  5. List<Pet> findAllPets() throws Exception;
  6. }

DAO 实现类

  1. public class PetDaoImpl extends BaseDao implements PetDao {
  2. /**
  3. * 查询所有宠物
  4. */
  5. public List<Pet> findAllPets() throws Exception {
  6. Connection conn=BaseDao.getConnection();
  7. String sql="select * from pet";
  8. PreparedStatement stmt= conn.prepareStatement(sql);
  9. ResultSet rs= stmt.executeQuery();
  10. List<Pet> petList=new ArrayList<Pet>();
  11. while(rs.next()) {
  12. Pet pet=new Pet(
  13. rs.getInt("id"),
  14. rs.getInt("owner_id"),
  15. rs.getInt("store_id"),
  16. rs.getString("name"),
  17. rs.getString("type_name"),
  18. rs.getInt("health"),
  19. rs.getInt("love"),
  20. rs.getDate("birthday")
  21. );
  22. petList.add(pet);
  23. }
  24. BaseDao.closeAll(conn, stmt, rs);
  25. return petList;
  26. }
  27. }

宠物实体类(里面get/set方法就不列出了)

  1. public class Pet {
  2. private Integer id;
  3. private Integer ownerId; //主人ID
  4. private Integer storeId; //商店ID
  5. private String name; //姓名
  6. private String typeName; //类型
  7. private int health; //健康值
  8. private int love; //爱心值
  9. private Date birthday; //生日
  10. }

连接数据库

  1. public class BaseDao {
  2. private static String driver="com.mysql.jdbc.Driver";
  3. private static String url="jdbc:mysql://127.0.0.1:3306/epet";
  4. private static String user="root";
  5. private static String password="root";
  6. static {
  7. try {
  8. Class.forName(driver);
  9. } catch (ClassNotFoundException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. public static Connection getConnection() throws SQLException {
  14. return DriverManager.getConnection(url, user, password);
  15. }
  16. public static void closeAll(Connection conn,Statement stmt,ResultSet rs) throws SQLException {
  17. if(rs!=null) {
  18. rs.close();
  19. }
  20. if(stmt!=null) {
  21. stmt.close();
  22. }
  23. if(conn!=null) {
  24. conn.close();
  25. }
  26. }
  27. public int executeSQL(String preparedSql, Object[] param) throws ClassNotFoundException {
  28. Connection conn = null;
  29. PreparedStatement pstmt = null;
  30. /* 处理SQL,执行SQL */
  31. try {
  32. conn = getConnection(); // 得到数据库连接
  33. pstmt = conn.prepareStatement(preparedSql); // 得到PreparedStatement对象
  34. if (param != null) {
  35. for (int i = 0; i < param.length; i++) {
  36. pstmt.setObject(i + 1, param[i]); // 为预编译sql设置参数
  37. }
  38. }
  39. ResultSet num = pstmt.executeQuery(); // 执行SQL语句
  40. } catch (SQLException e) {
  41. e.printStackTrace(); // 处理SQLException异常
  42. } finally {
  43. try {
  44. BaseDao.closeAll(conn, pstmt, null);
  45. } catch (SQLException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. return 0;
  50. }
  51. }

MySQL 8.0 以上版本

驱动包版本 mysql-connector-java-8.0.12.jar

数据库 URL 需要声明是否使用 SSL 安全验证及指定服务器上的时区:

  1. static final String DB_URL = jdbc:mysql://localhost:3306/javatest?useSSL=false&serverTimezone=UTC;
  2. conn = DriverManager.getConnection(DB_URL,USER,PASS);

原本的驱动器是:

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

在 IDEA 里面提示是:Loading class com.mysql.jdbc.Driver&#39;. This is deprecated. The new driver class iscom.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary

意思是说原本的驱动器不赞成 或者 是废弃了,自动换成了新的驱动器 com.mysql.cj.jdbc.Driver

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

运行程序时抛出异常

  1. Caused by: java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.

解决办法:

  1. jdbcUrl=jdbc:mysql://localhost:3306/spring

后面加上:

  1. jdbcUrl=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC

但如果你的 jdbcUrl 类似下面:

  1. jdbcUrl=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC&characterEncoding=utf-8

就是有多个 params 的时候需要以 & 分开,但 & 要改为 & 如下:

  1. jdbcUrl=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC&amp;characterEncoding=utf-8

使用 Maven 自动下载 mysql-connector-java

在 maven 工程下的 pom.xml 中加mysql-connector-java 的依赖,只需要填想要的版本号,就能自动下载对应的 jar 包,更加方便。

  1. <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. <version>8.0.16</version>
  5. </dependency>