JDBC
JDBC(java DataBase Connectivity)是java与数据库连接的纽带。JDBC封装了java与数据库通信的细节。程序员只需要通过JDBC API就可以与数据库服务器通信。
优点:
1.简化代码
2.使java代码不依赖具体数据库服务器。
JDBC API位于java.sql(大部分)和javax.sql(高级特性)包中。
JDBC的实现
JDBC的实现包括三个部分
1.JDBC驱动管理器:java.sql.DriverManger类,由Oracle公司实现,负责注册特定JDBC驱动器,以及根据特定驱动器建立与数据库的连接。
2.JDBC驱动器API:由Oracle公司制定,其中最主要的接口是java.sql.Driver接口。
3.JDBC驱动器,由数据库供应商,或者其他第三方工具提供商创建,也成为JDBC驱动程序。JDBC驱动器实现了JDBC驱动器API负责与与特定数据库连接。
JDBC API:java程序通过它来访问各种数据库。
JDBC驱动器 API:具体的JDBC驱动器需要实现它(java.sql.Driver)
因此实际上java程序与数据库服务器的连接是由JDBC驱动器完成的。
桥梁设计模式
DriverManager类运用桥梁设计模式,是java程序与各种JDBC驱动器连接的桥梁。
应用程序只和JDBC API打交道,JDBC API依赖DriverManager类来管理JDBC驱动器。
java.sql包中的接口和类
JDBC API主要在java.sql包中,主要有
1.Driver接口:驱动器
2.DriverManager类:驱动管理器
3.Connection接口:表示数据库连接
4.Statement接口:负责执行SQL语句
5.PreparedStatement接口:负责执行预准备的SQL语句
6.CallableStatement接口:负责执行SQL存储过程。
7.ResultSet接口:表示SQL查询语句返回的结果集。
DRiverManager类方法
Connection接口方法
Statement接口
PrepareStatement接口方法
PrepareStatement是statement的子接口,statement执行的sql语句参数都是固定的。而prepareStatement的参数可以动态修改。每次通过statement执行sql语句都要重新编译。而prepareStatement只需编译一次,然后可以多次执行。
例子
PreparedStatement
PreparedStatement preparedStatement = connection.prepareStatement("select id,username,? from user where id = ?");
//第一个?是password
preparedStatement.setString(1,"password");
//第二个?是10
preparedStatement.setInt(2,2);
Statement
Statement statement = connection.createStatement();
statement.execute("select * from user where id = 10");
ResultSet接口的方法
ResultSet接口表示select查询语句得到的结果集。
while (resultSet.next()){
//根据索引
System.out.println(resultSet.getString(1));
//根据字段名
System.out.println(resultSet.getString("username"));
}
访问数据库程序的步骤
1.加载JDBC驱动器
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
2.注册数据库驱动器
DriverManager.registerDriver((Driver) aClass.newInstance());
这一步实际上并不是必须的
因为在com.mysql.cj.jdbc.Driver内部有这么一段静态代码
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
他实际上会在加载的时候就自己把自己注册了
3.与数据库建立连接
String url = "jdbc:mysql://localhost:3306/db1";
Connection connection = DriverManager.getConnection(url,"root","root");
url的格式
jdbc:[数据库名]:[数据库服务器IP]:[端口号]/[数据库名]?[默认配置]
完整例子
//1.加载并注册驱动
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
//DriverManager.registerDriver((Driver) aClass.newInstance());
//2.与数据库建立连接
String url = "jdbc:mysql://localhost:3306/db1";
Connection connection = DriverManager.getConnection(url,"root","root");
//3.用PreparedStatement
PreparedStatement preparedStatement = connection.prepareStatement("select id,username,? from user where id = ?");
//第一个?是password
preparedStatement.setString(1,"password");
//第二个?是10
preparedStatement.setInt(2,2);
preparedStatement.execute();
//获取ResultSet对象
ResultSet resultSet1 = preparedStatement.getResultSet();
while (resultSet1.next()){
//根据索引
System.out.println(resultSet1.getInt(1));
//根据字段名
System.out.println(resultSet1.getString("username"));
//根据索引
System.out.println(resultSet1.getString(3));
}
//3.用statement
Statement statement = connection.createStatement();
statement.execute("select id,username,password from user where id = 9");
//获取ResultSet对象
ResultSet resultSet = statement.getResultSet();
while (resultSet.next()){
//根据索引
System.out.println(resultSet.getInt(1));
//根据字段名
System.out.println(resultSet.getString("username"));
//根据索引
System.out.println(resultSet.getString(3));
}
事务处理
所谓事务,就是多条SQL语句组合而成的。这些SQL语句要么都成功完成,要么都失败。也就是说即使有一个SQL语句执行出现错误,这个事务中的所有SQL都将失效
在Connection接口中提供了三个控制事务的方法
1.serAutoCommit(boolean autoCommit);设置是否自动提交事务。默认情况下为true。也就是说每条SQL语句执行成功后自动提交,失败则自动回滚。
2.commit();提交事务
3.rollback():回滚事务
例子
//1.加载并注册驱动
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
//DriverManager.registerDriver((Driver) aClass.newInstance());
//2.与数据库建立连接
String url = "jdbc:mysql://localhost:3306/db1";
Connection connection = DriverManager.getConnection(url,"root","root");
//禁止自动提交事务
connection.setAutoCommit(false);
Statement statement1 = connection.createStatement();
try{
statement1.executeUpdate("update user set password = 'heh213e1' where id = 2");
statement1.executeUpdate("update user set password = heh213e1 where id = 2");
connection.commit();
}catch (SQLException e){
//事务回滚
connection.rollback();
}
配置数据源
context.xml
<?xml version="1.0" encode="UTF-8" ?>
<Context>
<!-- T9.0 将resource复制到tomcat/config/context的Context中-->
<Resource
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/db1"
username="root"
password="root"
maxActive="50"
maxIdle="20"
name="ds"
auth="Container"
maxWait="10000"
type="javax.sql.DataSource"/>
</Context>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<resource-ref>
<description>DB Connection</description>
<res-ref-name>ds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
@WebServlet("/test3")
public class Test3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Connection connection =null;
try {
InitialContext context = new InitialContext();
DataSource ds = (DataSource) context.lookup("java:comp/env/ds");
connection = ds.getConnection();
Statement statement = connection.createStatement();
statement.execute("select id,username.password from user ");
ResultSet resultSet = statement.getResultSet();
while(resultSet.next()){
System.out.println(resultSet.getInt(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
}
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
可滚动的结果级
//创建一个可以生成可以滚动的结果集的statemen
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);