JDBC:java数据库连接

Jdbc是一种用于执行sql语句的JavaAPI,由一组用java语言编写的类和接口组成。它可以未多种关系数据库提供同一访问,java数据库连接体系结构是用于java应用程序连接数据库的标准方法。JDBC对java程序员来说是API,作为API,JDBC为程序开发提供了标准的接口。

优点:

1.面向对象,可以将通常用的jdbc数据库连接封装成一个类,在适用时直接调用。

2.可移植性,Jdbc支持不同的关系数据库,所以可以适用同一个应用程序支持多个数据源访问,只要加载相应的驱动器即可。

实现步骤:

1.把驱动加载到内存中,在java程序中加载驱动:mysql驱动类名称com.mysql.jdbc.Driver

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

2.创建数据连接对象,通过Drivermanager类创建数据连接对象connection。url写法:jdbc:mysql://ip地址:端口号/要连接的库名,如果在实现后无法向数据库中插入中文,可以在url后设置编码:useUnicode=true&characterEncoding=UTF8

Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/user","jf","121");

3.创建statement语句对象,通过连接connection对象的createStatement()方法创建语句对象,语句对象作用:把sql语句发送到对应的数据库服务器中。

Statement statement = connection.createStatement();

4.调用Statement对象相关操作执行sql语句,通过execute方法对数据库实现更新数据(增删改)。

此方法有一个int类型返回值(数据库受影响行数)

statement.executeUpdate("insert into user values(1,"user1")");

/*
     * statement.execuUpdate()是有返回值 int类型(数据库更新受影响的行数可以对此进行判断)
     * 例:
     * int a = statement.execuUpdate("update user set id = 1 where name = '王老五'");
     * if(a>=0){
     * System.out.println("数据库更新完成");
     * }
     */

5.查询数据库信息,查询结果会得到ResultSet对象,Resultset表示执行查询数据库后返回数据的集合。resultset对象具有指向当前数据的指针,通过该对象的next()方法,使得指针指向下一行,然后将数据以列号或字段名取出,如果next()方法返回nul,则表示下一行中没有数据存在。

ResultSet resultset = statement.executeQuery("select * from user");

//使用指针,拿到所有数据

while(resultset.next()){

/*

ResultSet既然用于缝扎胡歌你执行结果,那么该对象提供的都使用了获取数据的get方法。

获取任意类型数据(万物皆可字符串)

---getObject(Integer index) 根据角标获取

---getObject(String name) 根据字段名获取

获取指定数据类型

---getInt(int index) 

---getStrin(String name)

获取某一列(未知某一列名字

---getInt(6)

)

*/

String name = resultset.getString("name");
String gennder = resultset.getString("gennder");
String adress = resultset.getString("adress");
String chenghu = resultset.getString("chenghu");
int pm = resultset.getInt("pm");

System.out.println(gennder+" "+chenghu+" "+name+" "+adress+" "+pm);

}

5.关闭数据连接(释放资源)使用完数据库或者不需要访问数据库时,通过connection的close()方法及时关闭数据库连接

result.close();

statement.close();

以上完成了java连接数据库并实现了更新和查询数据的操作,仔细分析语句对象Statement后不难发现,这样直接去执行我们的语句,换句话说,也就是在我们的mysql中的系列注释依然是生效的,那么就会有如下问题:

在一张user表中,给定需求,查询name = "王老五"并且addres="北京"的人,

//创建name字段,age字段模拟从前台接收到的数据

String name = null;

String addres = null;

/*

正确数据

*/

name = "王老五";

addres = "北京";

/**

错误数据

*/

name = "王老五 or  '1'='1' --";

addres = "北京";

String sq1 = "select * from table_xinxi" +
            " where name = '"+name+"'and addres= '"+addres+"' ";

ResultSet resultset1 = statement.executeQuery("select * from user");

//对于正确或错误数据都是可以执行的,但后者sql注入问题,显然是不安全的,为了解决这种问题,我们选用预处理语句对象preparedstatement

预处理语句对象PrepareedStatement

PrepareedStatement由方法1preparedStatement创建,此对象用于发送一个或多个输入参数(IN参数)的sql语句。此对象有用一组方法是用于设置IN参数的值,在执行语句时这些IN参数被送到数据库中。PreparedStatement的实例扩展了Statement,因此它们都包括了Statement的方法,但比Statement对象的效率更高,因为它已被预编译过并存放以供使用。

与数据库建立连接后,编写sql语句不需要再拼接字段,而是使用占位符"?"的形式

String sql = "select * from user where name = ? and addres like ?";

为了避免sql注入的问题,不再创建Statement对象,而是通过preparedStatement方法创建预处理语句对象。

PreparedStatement preparedStatement = connection.preparedStatement(sql);

给sql语句中占位符赋值,需要调用preparedStatment对象的set方法,需要传入两个参(index,str),index表示占位符"?"所在的位置,而str表示str所在位置的内容。

preparedStatement.setString(1,"王老五");

preparedStatement.setString(2,"北京");

因为它已被预编译过并存放以供使用,所以在查询时,不需要再将sql语句传入execute方法中,

ResultSet resultSet  = preparedStatement.executeQuery();

while(resultSet.next()){

String name = resultSet.getString("name");

String addres = resultSet.getString("addres");

System.out.println(name+addres);

}

//切记关流

result.close();

statement.close();

以上虽然可以安全的实现功能,但访问效率比较缓慢,因为每次访问都需要建立连接,而连接池可以极大的改善java应用性能,将驱动和一些必要信息放到连接池中,需要时从池子里拿,减少了资源的使用。提升了效率。

连接池

连接池主要优点:

1.减少连接创建时间。2.简化的编程模式。3.受控的资源使用。

使用步骤

1.初始化连接池,此处使用的是C3P0连接池

ComboPooledDataSource cpd = new ComboPooledDataSource();

2.绑定四大参数,将参数放到连接池中

cpdsetDriverClass("com.mysql.jdbc.Driver");
cpd.setJdbcUrl("jdbc:mysql://localhost:3306/stu");
cpd.setUser("jf");
cpd.setPassword("121");

3.通过连接池获取Connection连接

Connection connection = cpd.getConnection();

4.创建预处理语句对象,编写sql

String sql = "insert into user values (0,?)";

PreparedStatement ps= connection.prepareStatement(sql);

5.给sql语句中占位符赋值

ps.setString(1,'小王');

6.执行sql

int index = ps.executeUpdate();

7.关流

ps.close();

connection.colse();

连接池加快了访问效率,但我们可以做更多的事,比如事务

事务

我们都知道,在数据库中(mysql)有关事务的语句

查看自动提交状态                    select @@autocommit;(show variables like '%autocommit%';)    
关闭自动提交状态                    set autocommit = 0;
打开自动提交状态                    set autocommit = 1;
保存回滚点                          savepoint s1(标识点);
回滚到指定的标识点                  rollback to s1;
删除事物标识点                      release savepoint s1;

同样的,Jdbc处理事务通过关闭连接的的自动提交实现的

connection.setAutoCommit(false);

接下来通过实例展示一下

在程序运行之前数据库中对应的表

package Jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Savepoint;

/**
 * 
 * @author ljf
 *事务由一个或多个这样的语句组成:这些语句已被执行、完成并被提交或还原
 *当调用方法commit或rollback时,当前事务即结束,另一个事务随即开始。
 *如果禁用自动提交模式,事务将要等到commit或rollback方法被显示调用时才结束
 *
 *
 */
public class Jdbc_shiwu {
	public static void main(String[] args) throws Exception {
		Class.forName("com.mysql.jdbc.Driver");
		String url = "jdbc:mysql://localhost:3306/stu";
		String user = "root";
		String password = "020703";
		Connection connection = DriverManager.getConnection(url,user,password);
		//Jdbc处理事务通过关闭连接的自动提交实现
		connection.setAutoCommit(false);//false表示关闭自动提交
		//通过对数据的更新操作查看事务
		
		
		String sql1 = "insert into table_xinxi values(0,'事务——增','hello')";
		//创建预处理语句对象
		PreparedStatement preparedstatement1 = connection.prepareStatement(sql1);
		//设置第一个回滚点
		Savepoint savepoint1 = connection.setSavepoint();
		preparedstatement1.executeUpdate();
		
		
		String sql2 = "delete from table_xinxi where id = 40";
		PreparedStatement preparedstatement2 = connection.prepareStatement(sql2);
		Savepoint savepoint2 = connection.setSavepoint();
		preparedstatement2.executeUpdate();
		
		String sql3 = "update table_xinxi set name = '事务——改' where id = 42";
		PreparedStatement preparedstatement3 = connection.prepareStatement(sql3);
		Savepoint savepoint3 = connection.setSavepoint();
		preparedstatement3.executeUpdate();
		
		/*
		 * 提交 
		 * connection.commit();
		 * 
		 */
		/*
		 * 回滚全部
		 * connection.rollback();
		 */
		/*
		 * 回滚部分
		 * connection.rollback(savepoint);
		 */
		//提交
		connection.commit();
		//释放资源
		preparedstatement3.close();
		preparedstatement2.close();
		preparedstatement1.close();
		connection.close();
		System.out.println("晚上好");
	}

}

在将程序中的提交事务注释后运行

 最后将程序中写入connection.commit()后

  事务由一个或多个这样的语句组成:这些语句已被执行、完成并被提交或还原
 当调用方法commit或rollback时,当前事务即结束,另一个事务随即开始。
 如果禁用自动提交模式,事务将要等到commit或rollback方法被显示调用时才结束

不难发现,在实际中用到的不止一个库,或数据库的user和password更改后,那对应的程序将无法使用,如果依然想继续使用,只能够来修改源码,然而我们要尽量避免修改已经写好的代码,此时就需要我们将可能修改的参数写到代码的外部,换句话说,就是需要一个配置文件,让Jdbc来读取我们的配置文件,这样符合我们的原则,维护也会变得简单。

配置文件

在项目中创建配置文件(后缀txt或者properties),在配置文件中给出参数对应的映射关系:名字 = 参数值 ,均为字符串,不需要添加双引号

文件名:jdbcConnection

后缀:txt

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/stu
user = jf
pass = 121

//创建输入流,读取配置文件
InputStream is = new FileInputStream("jdbcConnection.txt");
//创建properties读取配置文件内容
Properties pro = new Properties();
//调用properties的load方法加载
pro.load(is);
//获取配置文件中外部参数
String dirver = pro.getProperty("driver");
String url = pro.getProperty("url");
String user = pro.getProperty("user");
String pass = pro.getProperty("pass");

获取到参数后的操作就一样了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值