IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java全栈(三)JavaSE:4.数据库之JDBC下 -> 正文阅读

[Java知识库]Java全栈(三)JavaSE:4.数据库之JDBC下

第四章 封装JDBCTools

配置文件:src/jdbc.properties

#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=123456
initialSize=5
maxActive=10
maxWait=1000

JDBCTools工具类:

package com.atguigu.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

/*
 * 获取连接或释放连接的工具类
 */
public class JDBCTools {
	// 1、数据源,即连接池
	private static DataSource dataSource;
	
	// 2、ThreadLocal对象
	private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

	static {
		try {
			//1、读取druip.properties文件
			Properties pro = new Properties();
			pro.load(JDBCTools2.class.getClassLoader().getResourceAsStream("druid.properties"));
			
			//2、创建线程池
			dataSource = DruidDataSourceFactory.createDataSource(pro);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取连接的方法
	 * 
	 * @return
	 * @throws SQLException
	 */
	public static Connection getConnection() {
		// 从当前线程中获取连接
		Connection connection = threadLocal.get();
		if (connection == null) {
			// 从连接池中获取一个连接
			try {
				connection = dataSource.getConnection();
				// 将连接与当前线程绑定
				threadLocal.set(connection);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return connection;
	}

	/**
	 * 释放连接的方法
	 * 
	 * @param connection
	 */
	public static void releaseConnection() {
		// 获取当前线程中的连接
		Connection connection = threadLocal.get();
		if (connection != null) {
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}finally{
				// 将已经关闭的连接从当前线程中移除
				threadLocal.remove();
			}
		}
	}
}

ThreadLocal:

JDK 1.2的版本中就提供java.lang.ThreadLocal,为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。通常用来在在多线程中管理共享数据库连接、Session等

ThreadLocal用于保存某个线程共享变量,原因是在Java中,每一个线程对象中都有一个ThreadLocalMap<ThreadLocal, Object>,其key就是一个ThreadLocal,而Object即为该线程的共享变量。而这个map是通过ThreadLocal的set和get方法操作的。对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。

1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。

2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。

3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。

第五章 封装BasicDAOImpl

package com.atguigu.test08.dao;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;

import com.atguigu.util.JDBCTools;

public class BasicDAOImpl {
	/*
	 * 通用的增、删、改的方法
	 */
	protected int update(String sql,Object... args) throws SQLException{
		//1、获取链接对象
		Connection conn = JDBCTools.getConnection();
		
		//2、编写sql,用形参传入的方式代替
		
		//3、获取Statement或PreparedStatement对象
		PreparedStatement pst = conn.prepareStatement(sql);
		
		//设置?的值
		//因为不知道sql中是否有?,以及?设置为什么值,通过形参来传入
		//Object... args可变形参,可以传入0~n个值
		//如果没有传入,说明没有?需要设置
		//如果传入了n个值,那么说明sql中有n个?需要设置
		if(args!=null  && args.length>0){
			for (int i = 0; i < args.length; i++) {
				//数组的下标从0开始,pst的?的序号是从1开始,所以这里用i+1
				pst.setObject(i+1, args[i]);
			}
		}
		
		//4、执行sql
		int len = pst.executeUpdate();
		//5、关闭		
		pst.close();
		//这里不关闭conn,因为它在同一个事务的其他地方还要使用
		return len;
	}
	
	/*
	 * 通用查询多个Javabean对象的方法
	 */
	protected <T> ArrayList<T> getList(Class<T> clazz,String sql,Object... args) throws Exception{
		//1、获取链接对象
		Connection conn = JDBCTools.getConnection();
		//2、编写sql,由形参传入
		
		//3、获取PreparedStatement对象
		PreparedStatement pst = conn.prepareStatement(sql);
		
		//4、设置?,由形参传入
		if(args!=null  && args.length>0){
			for (int i = 0; i < args.length; i++) {
				//数组的下标从0开始,pst的?的序号是从1开始,所以这里用i+1
				pst.setObject(i+1, args[i]);
			}
		}
		
		//5、执行sql
		ResultSet rs = pst.executeQuery();
		/*
		 * 如何把ResultSet结果集中的数据变成一个一个的Javabean对象,放到ArrayList对象,并且返回
		 */
		ArrayList<T> list = new ArrayList<>();
		/*
		 * 要从ResultSet结果集中获取一共有几行,决定要创建几个对象
		 * 要从ResultSet结果集中获取一共有几列,决定要为几个属性赋值
		 * ResultSet结果集对象中,有一个方法ResultSetMetaData getMetaData()获取结果集的元数据
		 * 元数据就是描述结果集中的数据的数据,例如:列数,列名称等
		 */
		ResultSetMetaData metaData = rs.getMetaData();
		int count = metaData.getColumnCount();//获取列数
		
		while(rs.next()){//循环一次代表一行,就要创建一个Javabean对象
			//(1)创建一个Javabean对象
			T t  = clazz.newInstance();//这个方法有要求,要求Javabean这个类要有无参构造
			
			//(2)设置对象的属性值
			/*
			 * 反射操作属性的步骤:
			 * ①获取Class对象,现在有了
			 * ②获取属性对象Field
			 * 		Field f = clazz.getDeclaredField("属性名");
			 * ③创建Javabean对象,已经创建
			 * ④设置属性的可访问性  setAccessible(true)
			 * ⑤设置属性的值
			 */
			for (int i = 0; i < count; i++) {//一共要为count个属性赋值
//				Field f = clazz.getDeclaredField("属性名");
				String fieldName = metaData.getColumnLabel(i+1);//获取第几列的字段名
				Field f = clazz.getDeclaredField(fieldName);
				
				f.setAccessible(true);
				
				f.set(t, rs.getObject(i+1));//rs.getObject(i+1)获取第几列的值
			}
			
			//(3)把Javabean对象放到list中
			list.add(t);
		}
		pst.close();
		rs.close();
		//这里不关闭conn,因为它在同一个事务的其他地方还要使用
		return list;
	}

	protected <T> T getBean(Class<T> clazz,String sql,Object... args) throws Exception{
		return getList(clazz,sql,args).get(0);
	}
}

使用BasicDAOImpl实现Employee的增删改查

在这里插入图片描述

示例代码:EmployeeDAO.java

public interface EmployeeDAO {
	void addEmployee(Employee emp);
	void updateEmployee(Employee emp);
	void deleteByEid(int eid);
	Employee getByEid(int eid);
	ArrayList<Employee> getAll();
}

示例代码:EmployeeDAOImpl.java

package com.atguigu.test08.dao;

import java.sql.SQLException;
import java.util.ArrayList;

import com.atguigu.bean.Employee;

public class EmployeeDAOImpl extends BasicDAOImpl implements EmployeeDAO {

	@Override
	public void addEmployee(Employee emp) {
		//`ename`,`tel`,`gender`,`salary`,`commission_pct`,`birthday`,
		//`hiredate`,`job_id`,`email`,`mid`,`address`,`native_place`,`did`
		String sql = "insert into t_employee values(null,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		
		try {
			update(sql, emp.getEname(),emp.getTel(),emp.getGender(),emp.getSalary(),emp.getCommissionPct(),
					emp.getBirthday(),emp.getHiredate(),emp.getJobId(),emp.getEmail(),emp.getMid(),emp.getAddress(),
					emp.getNativePlace(),emp.getDid());
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void updateEmployee(Employee emp) {
		String sql = "update t_employee set `ename`=?,`tel`=?,`gender`=?,`salary`=?,`commission_pct`=?,`birthday`=?,`hiredate`=?,`job_id`=?,`email`=?,`mid`=?,`address`=?,`native_place`=?,`did`=? where eid=?";
		try {
			update(sql, emp.getEname(),emp.getTel(),emp.getGender(),emp.getSalary(),emp.getCommissionPct(),
					emp.getBirthday(),emp.getHiredate(),emp.getJobId(),emp.getEmail(),emp.getMid(),emp.getAddress(),
					emp.getNativePlace(),emp.getDid(),emp.getEid());
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void deleteByEid(int eid) {
		String sql = "delete from t_employee where eid=?";
		try {
			update(sql, eid);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public Employee getByEid(int eid) {
		//这里sql中通过取别名的方式,来指定对应的Javabean的属性名
		String sql = "select `eid`,`ename`,`tel`,`gender`,`salary`,`commission_pct` commissionPct ,`birthday`,`hiredate`,`job_id` jobId,`email`,`mid`,`address`,`native_place` nativePlace,`did` from t_employee where eid=?";
		Employee emp = null;
		try {
			emp = getBean(Employee.class, sql, eid);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}	
		return emp;
	}

	@Override
	public ArrayList<Employee> getAll() {
		//这里sql中通过取别名的方式,来指定对应的Javabean的属性名
		String sql = "select `eid`,`ename`,`tel`,`gender`,`salary`,`commission_pct` commissionPct ,`birthday`,`hiredate`,`job_id` jobId,`email`,`mid`,`address`,`native_place` nativePlace,`did` from t_employee";
		ArrayList<Employee>  list = new ArrayList<Employee>();
		try {
			list = getList(Employee.class, sql);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return list;
	}
}

第六章 Apache的DBUtils

commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

其中QueryRunner类封装了SQL的执行,是线程安全的。

(1)可以实现增、删、改、查、批处理、

(2)考虑了事务处理需要共用Connection。

(3)该类最主要的就是简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。

(1)更新

public int update(Connection conn, String sql, Object… params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。

(2)插入

public T insert(Connection conn,String sql,ResultSetHandler rsh, Object… params) throws SQLException:只支持INSERT语句,其中 rsh - The handler used to create the result object from the ResultSet of auto-generated keys. 返回值: An object generated by the handler.即自动生成的键值

(3)批处理

public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException: INSERT, UPDATE, or DELETE语句

public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException:只支持INSERT语句

(4)使用QueryRunner类实现查询

public Object query(Connection conn, String sql, ResultSetHandler rsh,Object… params) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。

***ResultSetHandler***接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet rs)该方法的返回值将作为QueryRunner类的query()方法的返回值。

该接口有如下实现类可以使用:

  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • ScalarHandler:查询单个值对象
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。

示例代码:BasicDAOImpl.java

package com.atguigu.test09.dbutil;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.atguigu.util.JDBCTools;

//在这里都不关闭连接,统一关闭,因为Connection对象需要共享使用
public class BasicDAOImpl4 {
	private QueryRunner qr = new QueryRunner();
	
	protected int update(String sql,Object... args) throws SQLException{
		Connection conn = JDBCTools2.getConnection();
		int len = qr.update(conn, sql, args);
		return len;
	}
	
	protected <T> List<T> getList(Class<T> clazz,String sql,Object... args) throws Exception{
		Connection conn = JDBCTools2.getConnection();
		/*
		 * ResultSetHandler接口,用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
		 * (1)BeanListHandler等形式
		 */
		List<T> list = qr.query(conn, sql, new BeanListHandler<>(clazz), args);
		return list;
	}
	
	protected <T> T getBean(Class<T> clazz,String sql,Object... args) throws Exception{
		Connection conn = JDBCTools2.getConnection();
		/*
		 * ResultSetHandler接口,用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
		 * (2)BeanHandler等形式
		 */
		T t = qr.query(conn, sql, new BeanHandler<>(clazz), args);
		
		return t;
	}
	
	/*
	 * 通用的查询单个值的方法
	 * 例如:员工总数,最高工资,平均工资等
	 */
	protected Object getObject(String sql,Object... args) throws Exception{
		Connection conn = JDBCTools2.getConnection();
		
		/*
		 * ResultSetHandler接口,用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
		 * (3)?ScalarHandler:查询单个值对象等形式
		 */
		Object obj = qr.query(conn, sql, new ScalarHandler<>(), args);
		
		return obj;
	}
	
	/*
	 * 通用的查询多行多列的方法
	 * 例如:每个部门的平均工资
	 */
	protected List<Map<String, Object>> getMapList(String sql,Object... args) throws Exception{
		Connection conn = JDBCTools2.getConnection();
		/*
		 * ResultSetHandler接口,用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
		 * (4)?MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
		 */
		List<Map<String, Object>> list = qr.query(conn, sql, new MapListHandler(), args);
		
		return list;
	}
	
}

示例代码:

public interface EmployeeDAO2 {
	void addEmployee(Employee emp);
	void updateEmployee(Employee emp);
	void deleteByEid(int eid);
	Employee getByEid(int eid);
	List<Employee> getAll();
	long empCount();//查询员工总数
	double avgSalary();//查询全公司的平均工资
	
	//key是部门编号,Double是平均工资
	Map<Integer,Double> avgSalaryPerDepartment();
}

示例代码:

public class EmployeeDAOImpl2 extends BasicDAO2 implements EmployeeDAO2 {

	@Override
	public void addEmployee(Employee emp) {
		//`ename`,`tel`,`gender`,`salary`,`commission_pct`,`birthday`,
		//`hiredate`,`job_id`,`email`,`mid`,`address`,`native_place`,`did`
		String sql = "insert into t_employee values(null,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		
		try {
			update(sql, emp.getEname(),emp.getTel(),emp.getGender(),emp.getSalary(),emp.getCommissionPct(),
					emp.getBirthday(),emp.getHiredate(),emp.getJobId(),emp.getEmail(),emp.getMid(),emp.getAddress(),
					emp.getNativePlace(),emp.getDid());
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void updateEmployee(Employee emp) {
		String sql = "update t_employee set `ename`=?,`tel`=?,`gender`=?,`salary`=?,`commission_pct`=?,`birthday`=?,`hiredate`=?,`job_id`=?,`email`=?,`mid`=?,`address`=?,`native_place`=?,`did`=? where eid=?";
		try {
			update(sql, emp.getEname(),emp.getTel(),emp.getGender(),emp.getSalary(),emp.getCommissionPct(),
					emp.getBirthday(),emp.getHiredate(),emp.getJobId(),emp.getEmail(),emp.getMid(),emp.getAddress(),
					emp.getNativePlace(),emp.getDid(),emp.getEid());
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void deleteByEid(int eid) {
		String sql = "delete from t_employee where eid=?";
		try {
			update(sql, eid);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public Employee getByEid(int eid) {
		//这里sql中通过取别名的方式,来指定对应的Javabean的属性名
		String sql = "select `eid`,`ename`,`tel`,`gender`,`salary`,`commission_pct` commissionPct ,`birthday`,`hiredate`,`job_id` jobId,`email`,`mid`,`address`,`native_place` nativePlace,`did` from t_employee where eid=?";
		Employee emp = null;
		try {
			emp = getBean(Employee.class, sql, eid);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}	
		return emp;
	}

	@Override
	public List<Employee> getAll() {
		//这里sql中通过取别名的方式,来指定对应的Javabean的属性名
		String sql = "select `eid`,`ename`,`tel`,`gender`,`salary`,`commission_pct` commissionPct ,`birthday`,`hiredate`,`job_id` jobId,`email`,`mid`,`address`,`native_place` nativePlace,`did` from t_employee";
		List<Employee>  list = new ArrayList<Employee>();
		try {
			list = getList(Employee.class, sql);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return list;
	}

	@Override
	public long empCount() {
		String sql = "select count(1) from t_employee";
		Long count = 0L;
		try {
			Object obj = getObject(sql);
			count = (Long) obj;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return count;
	}

	@Override
	public double avgSalary() {
		String sql = "select avg(salary) from t_employee";
		Double avg = 0.0;
		try {
			avg = (Double) getObject(sql);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return avg;
	}

	@Override
	public Map<Integer, Double> avgSalaryPerDepartment() {
		String sql = "select did,avg(salary) from t_employee group by did";
		
		Map<Integer, Double> map = new HashMap<>();
		try {
			List<Map<String, Object>> mapList = getMapList(sql);
			/*
			 * String:字段的名称,例如:did,avg(salary)
			 * Object:字段的值,例如1,19819.408666666666
			 *  {did=1, avg(salary)=19819.408666666666}
				{did=2, avg(salary)=11708.5}
				{did=3, avg(salary)=70223.0}
				{did=4, avg(salary)=12332.0}
				{did=5, avg(salary)=11065.5}
			 */
			
			for (Map<String, Object> map2 : mapList) {
				map.put((Integer)map2.get("did"),(Double)map2.get("avg(salary)"));
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
		return map;
	}

}

示例代码:

package com.atguigu.test09.dbutil;

import java.util.List;
import java.util.Map;

import org.junit.Test;

import com.atguigu.bean.Employee;

public class TestEmployeeDAOImp2 {
	@Test
	public void test1(){
		EmployeeDAOImpl2 ed2 = new EmployeeDAOImpl2();
		List<Employee> all = ed2.getAll();
		for (Employee employee : all) {
			System.out.println(employee);
		}
	}
	
	@Test
	public void test2(){
		EmployeeDAOImpl2 ed2 = new EmployeeDAOImpl2();
		long count = ed2.empCount();
		System.out.println(count);
	}
	
	@Test
	public void test3(){
		EmployeeDAOImpl2 ed2 = new EmployeeDAOImpl2();
		double avgSalary = ed2.avgSalary();
		System.out.println(avgSalary);
	}
	
	@Test
	public void test4(){
		EmployeeDAOImpl2 ed2 = new EmployeeDAOImpl2();
		Map<Integer, Double> map = ed2.avgSalaryPerDepartment();
		map.forEach((k,v) -> System.out.println(k+"->"+v));
	}
}

经典错误

1、jar包版本不兼容

Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
	at com.mysql.jdbc.Util.getInstance(Util.java:383)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1023)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:997)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:983)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:928)
	at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2576)
	at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2309)
	at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:834)
	at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:46)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
	at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:419)
	at com.mysql.jdbc.NonRegisteringDriver.connect(Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Exception in thread "main" 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.
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)
	at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
.java:344)
	at java.sql.DriverManager.getConnection(DriverManager.java:664)
	at java.sql.DriverManager.getConnection(DriverManager.java:247)

看异常好像是无事务连接异常,无法创建连接。将MySQL驱动改为了最新的8.0版本的MySQL驱动。显示那个驱动类已经过时了,新的驱动类是“com.mysql.cj.jdbc.Driver”,而不是“com.mysql.jdbc.Driver”了,并且还说我没有配置时区,查了一下,原来从JDBC6.0开始驱动类使用了新的,并且url中必须要设置时区,否侧会报错。

第一步:使用最新的MySQL驱动jar包。
第二步:把驱动的类名改为:
static String driver="com.mysql.cj.jdbc.Driver";
第三步:在访问mysql的url后加入时区设置:
static String url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC"
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-29 16:10:49  更:2021-11-29 16:13:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:47:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码