写点什么

JDBC 速查手册

用户头像
jiangling500
关注
发布于: 2021 年 02 月 14 日

JDBC URL

  1. JDBC URL 格式

jdbc:mysql://主机名称:mysql服务端口号(默认为3306)/数据库名称?参数1=值1&参数2=值2
复制代码
  1. 如果 JDBC 程序与服务器端的字符集不一致,会导致乱码,那么可以通过参数指定服务器端的字符集

jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
复制代码
  1. 也可以用“属性名=属性值”方式告诉数据库

jdbc:mysql://localhost:3306/test?user=root&password=123456
复制代码

获取连接

注意:jar 包版本要和 MySQL 版本匹配,否则会连接不上。

方式一

直接使用第三方数据库的 API。

@Testpublic void testConnection1() throws Exception {    // 获取 Driver 实现类对象    Driver driver = new com.mysql.jdbc.Driver();
// test:test数据库 String url = "jdbc:mysql://localhost:3306/test"; // 将用户名和密码封装在 Properties 中 Properties info = new Properties(); info.setProperty("user", "root"); info.setProperty("password", "abc123");
Connection conn = driver.connect(url, info); System.out.println(conn);}
复制代码

方式二

不使用第三方的 API,使用反射实例化 Driver,体现了面向接口编程的思想,使得程序具有更好的可移植性。

@Testpublic void testConnection2() throws Exception {    // 1. 获取 Driver 实现类对象:使用反射    Class clazz = Class.forName("com.mysql.jdbc.Driver");    Driver driver = (Driver) clazz.newInstance();
// 2. 提供要连接的数据库 String url = "jdbc:mysql://localhost:3306/test";
// 3. 提供连接需要的用户名和密码 Properties info = new Properties(); info.setProperty("user", "root"); info.setProperty("password", "abc123");
// 4. 获取连接 Connection conn = driver.connect(url, info); System.out.println(conn);}
复制代码

方式三

使用 DriverManager 替换 Driver

@Testpublic void testConnection3() throws Exception {    // 1. 获取 Driver 实现类的对象    Class clazz = Class.forName("com.mysql.jdbc.Driver");    Driver driver = (Driver) clazz.newInstance();
// 2. 提供另外三个连接的基本信息: String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "abc123";
// 注册驱动 DriverManager.registerDriver(driver);
// 获取连接 Connection conn = DriverManager.getConnection(url, user, password); System.out.println(conn);}
复制代码

方式四

可以只是加载驱动,不用显式地注册驱动了。

@Testpublic void testConnection4() throws Exception {    // 1. 提供三个连接的基本信息:    String url = "jdbc:mysql://localhost:3306/test";    String user = "root";    String password = "abc123";        // 2. 加载 Driver    Class.forName("com.mysql.jdbc.Driver");
// 3.获取连接 Connection conn = DriverManager.getConnection(url, user, password); System.out.println(conn);}
复制代码

之所以可以只加载驱动,而不用显式地注册驱动,是因为在 MySQL 的 Driver 实现类中,存在如下的静态代码块:

static {    try {        java.sql.DriverManager.registerDriver(new Driver());    } catch (SQLException E) {        throw new RuntimeException("Can't register driver!");    }}
复制代码

方式五-最终版

将数据库连接需要的 4 个基本信息声明在配置文件中,通过读取配置文件的方式,获取连接。这种方式的好处是:

  • 实现了数据与代码的分离,即实现了解耦

  • 如果需要修改配置文件信息即可,可以避免程序重新打包

public class ConnectionTest {  @Test  public void getConnection5() throws Exception{   		// 1. 读取配置文件中的 4 个基本信息    	InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties(); pros.load(is);
String user = pros.getProperty("user"); String password = pros.getProperty("password"); String url = pros.getProperty("url"); String driverClass = pros.getProperty("driverClass");
// 2. 加载驱动 Class.forName(driverClass);
// 3. 获取连接 Connection conn = DriverManager.getConnection(url, user, password); System.out.println(conn); }}
复制代码

src/jdbc.properties 文件内容如下:

user=rootpassword=abc123url=jdbc:mysql://localhost:3306/testdriverClass=com.mysql.jdbc.Driver
复制代码

注意:在 .properties 文件中,= 左右不要有空格。

执行 SQL 语句

Statement

使用 Statement 的弊端:需要拼写 SQL 语句,并且存在 SQL 注入的问题。

public class StatementTest {	@Test	public void testLogin() {		Scanner scan = new Scanner(System.in);
System.out.print("用户名:"); String userName = scan.nextLine(); // 这里之所以用 nextLine(),而不是 next() 方法,是因为要从标准输入中读取:"1' OR "和"=1 OR '1' = '1'" System.out.print("密码:"); String password = scan.nextLine();
// SELECT user, password FROM user_table WHERE USER = '1' OR ' AND PASSWORD = '=1 OR '1' = '1'; String sql = "SELECT user, password FROM user_table WHERE USER = '" + userName + "' AND PASSWORD = '" + password + "'"; User user = get(sql, User.class); if (user != null) { System.out.println("登陆成功!"); } else { System.out.println("用户名或密码错误!"); } }
// 使用Statement实现对数据表的查询操作 public <T> T get(String sql, Class<T> clazz) { T t = null; Connection conn = null; Statement st = null; ResultSet rs = null; try { // 1. 加载配置文件 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); Properties pros = new Properties(); pros.load(is);
// 2. 读取配置信息 String user = pros.getProperty("user"); String password = pros.getProperty("password"); String url = pros.getProperty("url"); String driverClass = pros.getProperty("driverClass");
// 3. 加载驱动 Class.forName(driverClass);
// 4. 获取连接 conn = DriverManager.getConnection(url, user, password);
st = conn.createStatement();
rs = st.executeQuery(sql);
// 获取结果集的元数据 ResultSetMetaData rsmd = rs.getMetaData();
// 获取结果集的列数 int columnCount = rsmd.getColumnCount();
if (rs.next()) {
t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) { // //1. 获取列的名称 // String columnName = rsmd.getColumnName(i+1);
// 1. 获取列的别名 String columnName = rsmd.getColumnLabel(i + 1);
// 2. 根据列名获取对应数据表中的数据 Object columnVal = rs.getObject(columnName);
// 3. 将数据表中得到的数据,封装进对象 Field field = clazz.getDeclaredField(columnName); field.setAccessible(true); field.set(t, columnVal); } return t; } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭资源 if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } }
if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
return null; }}
复制代码


发布于: 2021 年 02 月 14 日阅读数: 29
用户头像

jiangling500

关注

万丈高楼平地起,勿在浮沙筑高台! 2019.12.17 加入

一名IT从业者,熟悉Linux下C/C++,了解MySQL、Java等。

评论

发布
暂无评论
JDBC速查手册