前言:
现在对于数据库的连接,为了解耦合,各种架构对数据库的链接部分都有一些封装,让开发人员更加容易的编写代码,但是要是将原来没有架构封装的数据库弄明白也是相当重要的!接下来和我一探究竟吧!
之前学C#的时候,也有数据库的连接,java和C#的原理是一样的,当时也有过深入的研究,感兴趣的朋友也可以去看看.接下来不如正题,开始JDBC学习!
1.JDBC是个什么东西呢:
连接数据库的,它其实是官方定义的一套操作所有的关系型数据库的规则,那么就是接口了,这个和servelet的原理是一样的.为了让各个浏览器兼容,servelet出现了,定义了一套规则. 数据库也是一样,我们所熟知的关系型数据库有mysql,SQL server, Oracle,DB2等等。各个数据库连接的方式都不一样,我们程序员不可能连接mysql数据库对应一套编码,连接sql server在进行一套编码吧,so,JDBC的出现解决了这个问题,各个数据库的厂商去实现这套接口,提供数据库的驱动的jar包。而我们用这套接口进行编程,真正执行的代码是驱动jar包中的实现类。
如下图:Application为应用程序 调用接口,下边是各个驱动,然后是各个数据库
2.JDBC快速入门的一个小demo
demo存在的意义是为了下面解释与数据库连接相关的对象.
(1)导入驱动jar包
(2)代码:
public class JdbcDemo1 {
public static void main(String[] args) throws Exception {
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象
// Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "123456");
//如果是本机,且端口为3306,可简写成下面的方式:
Connection conn = DriverManager.getConnection("jdbc:mysql:///db3", "root", "123456");
//3.定义sql语句
String sql = "update account set money = 2000 where id = 1";
//4.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//5.执行sql
int count = stmt.executeUpdate(sql);
//6.处理结果
System.out.println(count);
//7.释放资源
stmt.close();
conn.close();
}
}
3.JDBC的5大对象
(1)上面导图上的知识,从很多地方都能看见,咱们就不详细的说了,直接往深里搞。
首先我们想要通过代码连接到数据库,一般得有驱动的东西,其中DriverManager为驱动管理对象,可是我们从上面的代码并没有看到通过DriverManager这个东西来注册驱动啊,只是有了一句 Class.forName(“com.mysql.jdbc.Driver”);其实这句话就已经注册了,这句话的意思就是说加载到了内存,加载到了内存说明了一个什么问题呢,那就是静态代码块中的代码会一同跟着执行,(大家如果有对静态代码块不知道的欢迎在底下留言,我会抽空写篇堆栈那方面的博客的啊)接下来在源码com.mysql.jdbc.Driver类中存在静态代码块,如下
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
大家看到了DriverManager.registerDriver这句代码了吧,这就是在注册驱动!应用程序就知道了要用mysql数据库驱动的jar包。
Connection conn = DriverManager.getConnection(“jdbc:mysql:///db3”, “root”, “123456”);这句话得到了一个数据库的连接对象conn,此时这个对象有一个createStatement()的方法,将一个能够执行sql对象的statement对象创造出来。
(2)Statement和PreparedStatement对象
我们以后会经常用到PreparedStatement对象,因为它是预编译sql,为什么我们要用预编译的sql呢,不仅仅说是防止注册,其实它的最大的作用是能提高效率,这个在
JDBC:深入理解PrearedStatement和Statement 这篇博文解释的超级清楚,非常建议感兴趣的朋友可以好好看看。下面是封装的比较规范的代码,作为参考!
4.JDBC工具类
(1)jdbc.properties文件
url=jdbc:mysql:///eesy
user=root
password=123456
driver=com.mysql.jdbc.Driver
(2)JDBCUtils类中代码
private static String url;
private static String user;
private static String password;
private static String driver;
// 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块
static {
try {
//1.创建Properties集合类
Properties properties = new Properties();
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
//上面散步就是获得了jdbc.properties文件的绝对路径
//2加载文件
properties.load(new FileReader(path));
//3获取数据
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
driver = properties.getProperty("driver");
// 4 注册驱动
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/*
* 获取连接
* 连接对象
* */
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
/*
* 释放资源
* 连接对象
* */
public static void close(Statement statement, Connection connection) {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
用PreparedStatement对象的步骤
//连接数据库判断是否登录成功
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
//1.获取连接
try {
conn = JDBCUtils.getConnection();
//2.定义sql
String sql = "select * from user where username = ? and password = ?";
//3.获取执行sql的对象
pstmt = conn.prepareStatement(sql);
//给?赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
//4.执行查询,不需要传递sql
rs = pstmt.executeQuery();
//5.判断
/* if(rs.next()){//如果有下一行,则返回true
return true;
}else{
return false;
}*/
return rs.next();//如果有下一行,则返回true
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(rs,pstmt,conn);
}
return false;
}