JDBC基础

JDBC

在任何语言中关于数据库方面的操作都是必须的,也是重要的,今天我们学习一下JDBC的相关操作;

首先是不可缺少的JDBC要素

  1. 连接,你必须先要和数据库建立连接,这样的话,你就肯定要加载一个数据库的驱动;
  2. sql语句,你得有操作啊,还是数据库懂得;
  3. 然后很显然,你不能让一个连接和sql语句直接发生关系吧,所以出现了PreparedStatement;
  4. 还有的话,就是你要是有结果的,得有地方存,所以就有了结果集;
1
2
3
4
5
6
7
8
9
10
11
12
try {
String sql = " select * from users";
Connection connection = JDBCUtils.getConnection(); //连接
PreparedStatement ps = connection.prepareStatement(sql);//有这么一个对象,在连接的基础上执行了sql语句,就是他了
ResultSet resultSet = ps.getResultSet(); //取出结果集;
while (resultSet.next())
{
}
} catch (SQLException e) {
e.printStackTrace();
}

JDBC 驱动加载

这样的话,JDBC基础坑就讲完了;但是有好玩的;你驱动是怎么加载的?连接是啥时候释放的呢?
这个就要依靠一个特别的类了
通过static方法,使得类装载时直接装载驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class JDBCUtils {
private static String drivername; //驱动名称
private static String url; //地址
private static String username; //用户名
private static String password; //密码;
private static String whatdriver; //是啥驱动呢?
/*
私有构造方法,不可实例化
*/
private JDBCUtils() {
}
/*
类加载后执行。且执行一次,
加载配置文件
*/
static
{
InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
try {
properties.load(inputStream);
drivername = properties.getProperty("drivername");
url =properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
}
/*
建立数据库连接;
*/
public static Connection getConnection()
{
Connection connection = null;
try {
Class.forName(drivername);
connection = DriverManager.getConnection(url,username,password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
/*
释放数据库连接;
*/
public static void free(ResultSet resultSet, PreparedStatement preparedStatement,Connection connection)
{
try {
if (resultSet!=null)
{
resultSet.close();
}
if (preparedStatement!=null)
{
preparedStatement.close();
}
if (connection!=null)
{
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

工厂模式

然后我们又想到说数据库操作不能只对于一种数据啊,那必然得有不一样的地方吧;所以这里我们加入了工厂模式。动态加载相关数据的实例;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class DaoFactory {
private static String classname = null;
private static Properties properties = null;
private DaoFactory() {
/*
不可实例化
*/
}
/*
工厂加载配置文件
*/
static {
InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("Daoconfig.properties");
properties = new Properties();
try {
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/*
进行类的实例化
*/
public static Object newIntance(String name)
{
try {
classname = properties.getProperty(name);
return Class.forName(classname).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}

配置文件+反射

然后我们发现 Daoconfig.properties 是个啥,没错,他就是配置文件了。也就是说我们直接更改配置文件整个项目的类就可能完全不同,这就需要理解反射机制,就是在程序运行中动态加载类,然后产生实例化;这是非常厉害的;就是说jvm一直活着,我们改改配置文件,就完全不一样了;

工厂实例化的代码

1
2
3
4
5
6
7
UserDao userDao = null;
@Before
public void setUp() throws Exception {
//向下转型
userDao = (UserDao) DaoFactory.newIntance("UserDao");
}

题外话:

1.equals如果不重写的话和==是完全一样的,因为他的内部代码是这样的:

1
2
3
public boolean equals(Object obj) {
return (this == obj);
}

其实就是==嘛,对比的就是内存地址是不是一样的;