1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > JDBC——Java连接关系型数据库

JDBC——Java连接关系型数据库

时间:2020-05-23 06:13:37

相关推荐

JDBC——Java连接关系型数据库

JDBC(Java Data Base Connection) java数据库连接 是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一的访问,是由一组Java语言编写的类和接口,JDBC提供了一种基准,以此可以构建更高级的工具和接口。

之前我们简单讲了数据库的一些知识,我们利用驱动程序简介管理数据库。就是因为我们安装好数据库后,我们的应用程序也是不能直接使用数据库的,必须通过响应的数据库驱动程序,通过驱动程序去和数据库打交道,其实也就是数据库的厂商的JDBC接口的实现。

今天我们简单说一下,Java连接数据库的一些步骤。

首先加载mysql驱动

这里边的路径是固定的,是由mysql厂家提供的驱动去找接口。

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

有了驱动,找接口。

加载connection接口

getConnection后三个参数:

连接字符串 :jdbc:mysql://(ip地址/localhost本机):(数据库端口号)/数据库名称数据库账号数据库密码

Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool","root","root");

整体代码如下,连接成功就会输出:连接成功。然后我们再去查询、更新数据。

import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;//连接数据库public class Demo1 {public static void main(String[] args) {Connection connection = null;try {//加载mysql驱动Class.forName("com.mysql.jdbc.Driver");//加载connection接口 getConnection(连接字符串,数据库账号,数据库密码);connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool","root","root");System.out.println("连接成功");} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {try {//关闭连接if (null != connection)connection.close();} catch (SQLException e) {e.printStackTrace();}}}}

注意:连接数据库操作完,要关闭连接!!!

这里有个问题,我们要导入的jar包,需要自己下载,javav本身不提供。

mysql-connector-java-5.1.0-bin.jar,就是mysql提供的jar包,网上很多,自己找找。

然后我们来操作数据。

通过Connection 的 createStatement()方法 获取Statement接口

Statement statement = connection.createStatement();

定义SQL 语句

String sql = "UPDATE student SET Phone = '15229975743' WHERE StudentNo = '1010'";

statement接口的executeUpdate()方法传入操作语句,返回影响成功的行数

int row = statement.executeUpdate(sql);

具体代码如下:

import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;//执行修改语句,返回成功影响行数public class Demo3 {public static void main(String[] args) {Connection connection = null;Statement statement = null;try {Class.forName("com.mysql.jdbc.Driver");connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool","root","root");System.out.println("连接成功");statement = connection.createStatement();String sql = "UPDATE student SET Phone = '15229975743' WHERE StudentNo = '1010'";int row = statement.executeUpdate(sql);System.out.println(row != 0?"修改成功":"修改失败");} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {try {if (statement != null){statement.close();}if (connection != null ){connection.close();}} catch (SQLException e) {e.printStackTrace();}}}}

注意:还是一样的,用完即关。而且是正着用倒着关,这很好理解。

然后是查询语句,查询语句不一样的是用的statement接口的executeQuery()方法,照样传入查询语句,但是返回的是一个结果集合ResultSet。

ResultSet rs = statement.executeQuery(sql);

这个集合同样的在最后用完要关掉。

这里我们说一下,查询和更新是都要传入sql语句,而有的人会利用这个去注入恶意代码,常见的sql注入,使得躲避掉数据库操作权限限制。

最简单的举个例子,我们要求用户名密码都一致,才能查询自己的成绩,sql语句:

select * from student WHERE studentUser = '李四' AND loginPwd = '123456789'

我并不知道李四的密码,甚至不知道李四的用户名,那我要查询这个数据库的信息,怎么办,我想了个办法,输入这个句子:

select * from student WHERE studentUser = '' or 1=1 -- 'AND loginPwd = ''

我们可以看到,我利用(’ or 1=1 – )构造了一个1=1的永真条件,后边直接被注释掉,那数据库那边收到这样的语句条件判断肯定为真,那我前边要查的肯定也可以查到。

那么,mysql厂商肯定也注意到这种情况,所以为connection接口提供了prepareStatement()方法。

之前我们要先利用connection接口的createStatement()方法获取statement接口,然后定义sql语句,在查询或者更新数据时用statement接口的executeQuery(sql)或executeUpdate(sql)方法去传入sql语句,进行操作,有被sql注入的风险。

现在我们利用connection接口的prepareStatement()方法去获取preparedStatement接口,它和statement接口有相同的功能,但是会预编译,而且prepareStatement()方法强制先传入sql语句进行预编译。

String sql = "select * from student WHERE studentNo = ? AND loginPwd = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,"1010");preparedStatement.setString(2,"123456");

这里我们传入的sql语句中先不传值,而是用英文的?代替,叫做占位符,

在下边用preparedStatement的(set+数据类型)方法去给占位符赋值,先说明第几个占位符,再写值为多少。

他就会利用预编译将几个值分别去验证,而不是将整个语句打包去执行。

import java.sql.*;//利用 prepareStatement获取Statement可以预编译,防止sql注入public class Demo4 {public static void main(String[] args) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {Class.forName("com.mysql.jdbc.Driver");connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool","root","root");System.out.println("连接成功");String sql = "select * from student WHERE studentNo = ? AND loginPwd = ?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,"1010");preparedStatement.setString(2,"123456");resultSet = preparedStatement.executeQuery();while (resultSet.next()){System.out.println(resultSet.getInt("studentno")+"---"+resultSet.getString("studentname"));}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {try {if (resultSet != null){resultSet.close();}if (preparedStatement != null){preparedStatement.close();}if (connection != null){connection.close();}} catch (SQLException e) {e.printStackTrace();}}}

上面我们讲了用java连接mysql数据库后进行查询、更新数据的方法,但是用着不是很方便,而且我们Java讲究数据作为对象去使用。我们只是查到数据、更新数据,而没有把它弄成一个对象去操作他,没什么意义。所以,我写了下面的工具类,可以查数据、更新数据、把数据封装为一个类,然后去操作他。

import mons.beanutils.BeanUtils;import java.lang.reflect.InvocationTargetException;import java.sql.*;import java.util.ArrayList;import java.util.List;public class BaseDao {private static Connection connection = null;private static PreparedStatement preparedStatement = null;private static ResultSet resultSet = null;static {try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}public static void getConnection() throws SQLException {connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myschool", "root", "root");}public static int executeUpdate(Object[] objects, String sql) {int row = 0;try {getConnection();connection.setAutoCommit(false);preparedStatement = connection.prepareStatement(sql);if (objects != null) {for (int i = 0; i < objects.length; i++) {preparedStatement.setObject(i + 1, objects[i]);}}row = preparedStatement.executeUpdate();} catch (SQLException e) {e.printStackTrace();try {connection.rollback();} catch (SQLException ex) {ex.printStackTrace();}} finally {try {mit();connection.setAutoCommit(true);} catch (SQLException e) {e.printStackTrace();}closeAll();}return row;}public static ResultSet executeQuery(Object[] objects,String sql){try {getConnection();preparedStatement = connection.prepareStatement(sql);if (null != objects){for (int i = 0; i < objects.length; i++) {preparedStatement.setObject(i+1,objects[i]);}}resultSet = preparedStatement.executeQuery();} catch (SQLException e) {e.printStackTrace();}return resultSet;}public static <T> List<T> executeQuery2(Object[] objects,String sql,Class<T> tClass){List<T> list = new ArrayList<>();try {getConnection();preparedStatement = connection.prepareStatement(sql);if (null != objects){for (int i = 0; i < objects.length; i++) {preparedStatement.setObject(i+1,objects[i]);}}resultSet = preparedStatement.executeQuery();//创建集合 获取此 ResultSet 对象的列的编号、类型和属性。// 返回:此 ResultSet 对象的列的描述ResultSetMetaData metaData = resultSet.getMetaData();while (resultSet.next()){T obj = tClass.newInstance();for (int i = 0; i < metaData.getColumnCount(); i++) {// 获取列名 根据下标(从1开始)String colName = metaData.getColumnName(i+1);// 根据列名 获取 值Object value = resultSet.getObject(colName);//利用BeanUtils工具栏,创建对象BeanUtils.setProperty(obj,colName,value);}//将组装后的结果 保存到list中list.add(obj);}} catch (SQLException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} finally {closeAll();}return list;}public static void closeAll() {try {if(null != resultSet)resultSet.close();if(null != preparedStatement)preparedStatement.close();if(null != connection)connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}

我们利用数据库中的属性名、值去包装类主要是利用BeanUtils工具类,他也需要导jar包。commons-beanutils-1.9.3 jar

再来一个测试类测一下工具是否好用:

import org.westos.demo.BaseDao;import org.westos.entity.Student;import java.util.List;public class Test {public static void main(String[] args) {String sql = "select * from student WHERE studentNo = ? AND loginPwd = ? ";Object[] objects = {1011,"123456"};List<Student> studentList = BaseDao.executeQuery2(objects,sql,Student.class);for (Student student : studentList) {System.out.println(student.getStudentname());}}}

我们可以看到,有了工具类后,我们只需要输入sql语句以及条件值就可以,他会创建好对象给我们,我们有一个集合去收就可以。再取数据用就可以后用我们java熟悉的get/set方法就ok。

我之前遇到包装对象出错问题,你要先确定你的属性名、数据类型和你的数据库中是一致的,然后还是出错可能因为beanutils1.9.3的包太高级,利用Fasthashmap创建对象,有的Java版本低可能会失败,所以需要找1.8的beanutils包就可以了。

好了,本次分享就到这里,希望对你有帮助,有问题请批评指正,谢谢!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。