使用MySQL数据库,实现你的第一个JDBC程序

熟悉了JDBC的编程步骤后,接下来通过一个案例并依照上一小节所讲解的步骤来演示JDBC的使用。此案例会从tb_user表中读取数据,并将结果打印在控制台。

需要说明的是,Java中的JDBC是用来连接数据库从而执行相关数据相关操作的,因此在使用JDBC时,一定要确保安装有数据库。常用的关系型数据库有MySQL和Oracle,本书就以连接MySQL数据库为例,使用JDBC执行相关操作。

案例的具体实现步骤如下:

(1) 搭建数据库环境

在MySQL数据库中创建一个名称为jdbc的数据库,然后在该数据库中创建一个名称为tb_user的表,创建数据库和表的SQL语句如下:

CREATE DATABASE jdbc;USE jdbc;
CREATE TABLEtb_user(
        id INT PRIMARY KEY AUTO_INCREMENT,NAMEVARCHAR(40),
        sex VARCHAR(2),    
        email VARCHAR(60),
        birthday DATE        
);

上述创建tb_user表时添加了id、NAME、sex、email和birthday共5个字段,其中NAME字段名称为大写形式,这是因为name字段在MySQL数据库中属于关键字,所以为了方便区分,这里将name字段名称全部用大写表示。

数据库和表创建成功后,再向tb_user表中插入3条数据,插入的SQL语句如下所示:

INSERT INTOtb_user(NAME,sex,email,birthday)VALUES('Jack','男','jack@126.com','1980-01-04'),('Tom','男','tom@126.com','1981-02-14'),('Lucy','女','lucy@126.com','1979-12-28');

为了查看数据是否添加成功,使用SELECT语句查询tb_user表中的数据,执行结果如图1所示。

图1 tb_user表中的数据

注意:

数据库和表创建成功后,如果使用的是命令行窗口向tb_user表中插入带有中文的数据,命令行窗口可能会报错,同时从MySQL数据库查询带有中文数据还可能会显示乱码,这是因为MySQL数据库默认使用的是UTF-8编码格式,而命令行窗口默认使用的是GBK编码格式,所以执行带有中文数据的插入语句会出现解析错误。为了在命令行窗口也能正常向MySQL数据库插入中文数据,以及查询中文数据,可以在执行插入语句和查询语句前,先在命令行窗口执行以下两条命令:

set character_set_client=gbk;
set character_set_results=gbk;

执行完上述两条命令后,再次在命令行窗口执行插入和查询操作就不再出现乱码问题了。

(1) 创建项目环境,导入数据库驱动

在Eclipse中新建一个名称为chapter09的Java项目,使用鼠标右键单击项目名称,然后选择【New】→【Folder】,在弹出窗口中将该文件夹命名为lib并单击【Finish】按钮,此时项目根目录中就会出现一个名称为lib的文件夹。将下载好的MySQL数据库驱动文件Jar包(mysql-connector-java-5.1.46-bin.jar)复制到项目的lib目录中,并使用鼠标右击该JAR包,在弹出框中选择【Build Path】→【Add to Build Path】,此时Eclipse会将该JAR包发布到类路径下。加入驱动后的项目结构如图2所示。

其中,MySQL驱动文件可以在其官网地址:http://dev.mysql.com/downloads/connector/j/页面中下载,单击页面Platform Independent (Architecture Independent), ZIP Archive后的“Download”按钮,并在新打开的窗口中的单击 “No thanks, just start my download”超链接后即可下载驱动压缩包(本书编写时的最新驱动版本文件是mysql-connector-java-5.1.46.zip),解压后即可得到相应JAR包。

(1) 编写JDBC程序

在项目chapter09的src目录下,新建一个名称为com.itheima.jdbc的包,并在该包中创建类Example01。在该类读取数据库中的tb_user表,并将结果输出到控制台,如文件1所示。

文件1 Example01.java

importjava.sql.*;publicclassExample01{publicstaticvoidmain(String[] args)throwsSQLException{Connection conn =null;Statement stmt =null;ResultSet rs =null;try{// 1. 加载数据库驱动Class.forName("com.mysql.jdbc.Driver");// 2.通过DriverManager获取数据库连接String url ="jdbc:mysql://localhost:3306/jdbc";String username ="root";String password ="root";
                 conn =DriverManager.getConnection(url,username, password);// 3.通过Connection对象获取Statement对象
                 stmt = conn.createStatement();// 4.使用Statement执行SQL语句String sql ="select * from tb_user";
                 rs = stmt.executeQuery(sql);// 5. 操作ResultSet结果集System.out.println("id    |    name      |    sex  "+"   |    email        |    birthday ");while(rs.next()){int id = rs.getInt("id");// 通过列名获取指定字段的值String name = rs.getString("name");String sex = rs.getString("sex");String email = rs.getString("email");Date birthday = rs.getDate("birthday");System.out.println(id +"    |    "+ name +"    |    "+ sex +"    |    "+ email +"    |    "+ birthday);}}catch(Exception e){
                 e.printStackTrace();}finally{// 6.关闭连接,释放资源if(rs !=null){ rs.close();}if(stmt !=null){ stmt.close();}if(conn !=null){ conn.close();}}}}

运行结果如图3所示。

图3 运行结果

文件1中,首先注册了MySQL数据库驱动,通过DriverManager获取一个Connection对象,然后使用Connection对象创建一个Statement对象,Statement对象通过executeQuery(String sql)方法执行了SQL语句,并返回结果集ResultSet,接下来,通过遍历ResultSet得到查询结果并输出,最后关闭连接,释放数据库资源。

从图3中可以看到,tb_user表中的数据已被打印在了控制台。至此第一个JDBC程序实现成功。

注意:

在进行数据库连接时,连接MySQL数据库的username和password都要与创建MySQL数据库时设置的登录账户一致,否则登录失败。本章以及后续案例都默认MySQL数据库登录的username和password都为“root”。

实现JDBC程序一共需要几步?

通常情况下,JDBC的使用可以按照以下几个步骤进行:

(1) 加载数据库驱动

加载数据库驱动通常使用Class类的静态方法forName()来实现,具体实现方式如下:

Class.forName("DriverName");

在上述代码中,DriverName就是数据库驱动类所对应的字符串。例如,要加载MySQL数据库的驱动可以采用如下代码:

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

加载Oracle数据库的驱动可以采用如下代码:

Class.forName("oracle.jdbc.driver.OracleDriver");

从上面两种加载数据库驱动的代码可以看出,在加载驱动时所加载的并不是真正使用数据库的驱动类,而是数据库驱动类名的字符串。

(2) 通过DriverManager获取数据库连接

DriverManager中提供了一个getConnection()方法来获取数据库连接,获取方式如下:

Connection conn =DriverManager.getConnection(String url,String user,String pwd);

从上述代码可以看出,getConnection()方法中有3个参数,它们分别表示连接数据库的URL、登录数据库的用户名和密码。其中用户名和密码通常由数据库管理员设置,而连接数据库的URL则遵循一定的写法。以MySQL数据库为例,其地址的书写格式如下:

jdbc:mysql://hostname:port/databasename

上面代码中,jdbc:mysql:是固定的写法,mysql指的是MySQL数据库。hostname指的是主机的名称(如果数据库在本机上,hostname可以为localhost或127.0.0.1,如果在其他机器上,那么hostname为所要连接机器的IP地址),port指的是连接数据库的端口号(MySQL端口号默认为3306),databasename指的是MySQL中相应数据库的名称。

(3) 通过Connection对象获取Statement对象

Connection创建Statement的方式有如下三种:

● createStatement():创建基本的Statement对象。

● prepareStatement(String sql):根据传递的SQL语句创建PreparedStatement对象。

● prepareCall(String sql):根据传入的SQL语句创建CallableStatement对象。

以创建基本的Statement对象为例,其创建方式如下:

Statement stmt = conn.createStatement();

(4) 使用Statement执行SQL语句

所有的Statement都有如下三种执行SQL语句的方法:

● execute(String sql):用于执行任意的SQL语句。

● executeQuery(String sql):用于执行查询语句,返回一个ResultSet结果集对象。

● executeUpdate(String sql):主要用于执行DML(数据操作语言)和DDL(数据定义语言)语句。执行DML语句(INSERT、UPDATE或DELETE)时,会返回受SQL语句影响的行数,执行DDL(CREATE、ALTER)语句返回0。

以executeQuery()方法为例,其使用方式如下:

// 执行SQL语句,获取结果集ResultSetResultSet rs = stmt.executeQuery(sql);

(5) 操作ResultSet结果集

如果执行的SQL语句是查询语句,执行结果将返回一个ResultSet对象,该对象里保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象来取出查询结果。

(6) 关闭连接,释放资源

每次操作数据库结束后都要关闭数据库连接,释放资源,以重复利用资源。需要注意的是,通常资源的关闭顺序与打开顺序相反,顺序是ResultSet、Statement(或PreparedStatement)和Connection。为了保证在异常情况下也能关闭资源,需要在try...catch的finally代码块中统一关闭资源。

至此,JDBC程序的大致实现步骤已经讲解完成。

Spring中的JDK动态代理是如何实现的?

JDK动态代理是通过java.lang.reflect.Proxy 类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring默认会使用JDK动态代理来实现AOP。

接下来,通过一个案例来演示Spring中JDK动态代理的实现过程,具体步骤如下。

(1)创建一个名为chapter03的Web项目,导入Spring框架所需JAR包到项目的lib目录中,并发布到类路径下。

(2)在src目录下,创建一个com.itheima.jdk包,在该包下创建接口UserDao,并在该接口中编写添加和删除的方法,如文件1所示。

文件1 UserDao.java

packagecom.itheima.jdk;publicinterfaceUserDao{publicvoidaddUser();publicvoiddeleteUser();}

(3)在com.itheima.jdk包中,创建UserDao接口的实现类UserDaoImpl,分别实现接口中的方法,并在每个方法中添加一条输出语句,如文件2所示。

文件2 UserDaoImpl.java

packagecom.itheima.jdk;// 目标类publicclassUserDaoImplimplementsUserDao{publicvoidaddUser(){System.out.println("添加用户");}publicvoiddeleteUser(){System.out.println("删除用户");}}

需要注意的是,本案例中会将实现类UserDaoImpl作为目标类,对其中的方法进行增强处理。

(4)在src目录下,创建一个com.itheima.aspect包,并在该包下创建切面类MyAspect,在该类中定义一个模拟权限检查的方法和一个模拟记录日志的方法,这两个方法就表示切面中的通知,如文件3所示。

文件3 MyAspect.java

packagecom.itheima.aspect;//切面类:可以存在多个通知Advice(即增强的方法)publicclassMyAspect{publicvoidcheck_Permissions(){System.out.println("模拟检查权限...");}publicvoidlog(){System.out.println("模拟记录日志...");}}

(5)在com.itheima.jdk包下,创建代理类JdkProxy,该类需要实现InvocationHandler接口,并编写代理方法。在代理方法中,需要通过Proxy类实现动态代理,如文件4所示。

文件4 JdkProxy.java

packagecom.itheima.jdk;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;importcom.itheima.aspect.MyAspect;/**
      * JDK代理类
      */publicclassJdkProxyimplementsInvocationHandler{// 声明目标类接口privateUserDao userDao;// 创建代理方法publicObjectcreateProxy(UserDao userDao){this.userDao = userDao;// 1.类加载器ClassLoader classLoader =JdkProxy.class.getClassLoader();// 2.被代理对象实现的所有接口Class[] clazz = userDao.getClass().getInterfaces();// 3.使用代理类,进行增强,返回的是代理后的对象returnProxy.newProxyInstance(classLoader,clazz,this);}/*
          * 所有动态代理类的方法调用,都会交由invoke()方法去处理
          * proxy 被代理后的对象 
          * method 将要被执行的方法信息(反射) 
          * args 执行方法时需要的参数
          */@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{// 声明切面MyAspect myAspect =newMyAspect();// 前增强
             myAspect.check_Permissions();// 在目标类上调用方法,并传入参数Object obj = method.invoke(userDao, args);// 后增强
             myAspect.log();return obj;}}

在文件4中,JdkProxy类实现了InvocationHandler接口,并实现了接口中的invoke()方法,所有动态代理类所调用的方法都会交由该方法处理。在创建的代理方法createProxy()中,使用了Proxy类的newProxyInstance()方法来创建代理对象。newProxyInstance()方法中包含三个参数,其中第1个参数是当前类的类加载器,第2个参数表示的是被代理对象实现的所有接口,第3个参数this代表的就是代理类JdkProxy本身。在invoke()方法中,目标类方法执行的前后,会分别执行切面类中的check_Permissions()方法和log()方法。

(6)在com.itheima.jdk包中,创建测试类JdkTest。在该类中的main()方法中创建代理对象和目标对象,然后从代理对象中获得对目标对象userDao增强后的对象,最后调用该对象中的添加和删除方法,如文件5所示。

文件5 JdkTest.java

packagecom.itheima.jdk;publicclassJdkTest{publicstaticvoidmain(String[] args){// 创建代理对象JdkProxy jdkProxy =newJdkProxy();// 创建目标对象UserDao userDao=newUserDaoImpl();// 从代理对象中获取增强后的目标对象UserDao userDao1 =(UserDao) jdkProxy.createProxy(userDao);// 执行方法
             userDao1.addUser();
             userDao1.deleteUser();}}

执行程序后,控制台的输出结果如图1所示。

图1 运行结果

从图1可以看出,userDao实例中的添加用户和删除用户的方法已被成功调用,并且在调用前后分别增加了检查权限和记录日志的功能。这种实现了接口的代理方式,就是Spring中的JDK动态代理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是四个问题,我会一一回答。 1、安装Mysql、图形化工具SQLYog: 首先,你需要下载安装Mysql数据库和SQLYog图形化工具。可以从Mysql官网下载安装包,也可以使用软件包管理工具进行安装。SQLYog可以从官网下载安装包,也可以使用其他类似的工具,比如Navicat等。 2、实现第一个JDBC程序JDBCJava数据库连接的标准接口,可以用于连接各种关系型数据库。下面是一个简单的JDBC程序示例,可以连接到本地的Mysql数据库: ``` import java.sql.*; public class JdbcDemo { public static void main(String[] args) { try { // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 建立数据库连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password"); // 执行SQL查询 Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM user"); // 遍历查询结果 while (rs.next()) { System.out.println(rs.getInt("id") + ", " + rs.getString("name") + ", " + rs.getInt("age")); } // 释放资源 rs.close(); stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 3、使用JDBC完成数据的增删改查: 下面是一个简单的JDBC程序示例,可以用于执行数据的增删改查操作: ``` import java.sql.*; public class JdbcDemo { public static void main(String[] args) { try { // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 建立数据库连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password"); // 执行SQL插入操作 String sql = "INSERT INTO user (name, age) VALUES (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, "张三"); pstmt.setInt(2, 20); pstmt.executeUpdate(); // 执行SQL更新操作 sql = "UPDATE user SET age = ? WHERE name = ?"; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 25); pstmt.setString(2, "张三"); pstmt.executeUpdate(); // 执行SQL删除操作 sql = "DELETE FROM user WHERE age < ?"; pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 18); pstmt.executeUpdate(); // 执行SQL查询操作 sql = "SELECT * FROM user"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); // 遍历查询结果 while (rs.next()) { System.out.println(rs.getInt("id") + ", " + rs.getString("name") + ", " + rs.getInt("age")); } // 释放资源 rs.close(); stmt.close(); pstmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 4、使用JDBC实现用户的登录功能: 用户登录功能通常需要与数据库中的用户表进行交互。下面是一个简单的JDBC程序示例,可以用于实现用户登录功能: ``` import java.sql.*; public class JdbcDemo { public static void main(String[] args) { try { // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 建立数据库连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password"); // 执行SQL查询操作 String sql = "SELECT * FROM user WHERE username = ? AND password = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, "admin"); pstmt.setString(2, "123456"); ResultSet rs = pstmt.executeQuery(); // 判断查询结果是否为空 if (rs.next()) { System.out.println("登录成功"); } else { System.out.println("登录失败"); } // 释放资源 rs.close(); pstmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 以上就是我对你的四个问题的回答,希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值