JDBC
前言
最近看了点视频有点感悟,写出来,省的以后忘了
我们先来介绍一下JDBC
Java数据库连接,(Java DataBase Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
说白了JDBC就是sun公司(被oracle收购的那个)为Java开发者使用数据库提供了统一的编程接口,它由一组Java类和接口组成。是Java程序与数据库通信的标准API。JDBC API使得开发人员可以使用纯Java的方式来连接数据库,并执行操作。
有了这个JDBC接口我们就可以直接调用JDBC接口然后各个数据库厂商提供JDBC接口的的实现(也就是驱动)来操作各种不同的数据库了,而不是像之前那样,单独连接各个数据库。
p话太多容易挨揍。进入主题
获取连接
首先我们先把数据库的驱动的jar包添加到类路径
idea的添加方式
File -> Project Structure (Ctrl + Shift + Alt + S)
之后单击 Modules —> Dependencies-- -> “+”-- -> “Jars or directories”
选择硬盘上的jar包
Apply -> OK
Eclipse
在java项目根目录新建lib文件夹,把需要的jar包复制到此文件夹中
选中对应的jar包,右击 —>Build Path —> Add to Build Path
如果还是不行的话右击项目—>properties—>Java Build Path—>add JARs—>选中你的jar包—>ok
如果还不行,你来打我。
没导入进来的话会报错ClassNotFoundException
进入正式环节
如果想操作数据库我们得先获取一个和数据库的连接
url = "jdbc:mysql://localhost:3306/test";
/*URL的标准由三部分组成,各部分间用冒号分隔。
jdbc:子协议:子名称
子协议:子协议用于标识一个数据库驱动程序
子名称:一种标识数据库的方法。子名称可以依不同的子协议而变化,用子名称的目的是为了定位数据库提供足够的信息。包含主机名(对应服务端的ip地址),端口号,数据库名。*/
String user = "root";//user就是数据库用户名。
String password = "123456";//这就是你数据库的密码。
String driverName = "com.mysql.jdbc.Driver";//这是你数据库驱动的位置。
public void getConnection() {
try {
//1.数据库连接的4个基本要素:
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "123456";
String driverName = "com.mysql.jdbc.Driver";
//2.加载驱动 ()
Class.forName(driverName);
//Driver driver = (Driver) clazz.newInstance();
//3.注册驱动。。可省略
//DriverManager.registerDriver(driver);
//3.获取连接
Connection conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
}
//3.注册驱动。。可省略
//DriverManager.registerDriver(driver);
之所以把那个驱动给注释掉了是因为在DriverManager的源码中已经存在静态代码块,实现了驱动的注册。
这已经是一个可以获取到连接的类了。
接下来我们可以稍微优化一下,一般情况下都会选择用引用外部properties文件来设置这个用户名和密码之类的,便于维护,再加上每次写代码之前如果都要获取这个连接的话会造成大量代码重复,我们就直接封装成一个静态方法,什么时候用什么时候直接调一下就好了。
@Test
public static Connection getConnection(){
Connection conn = null;
try{
//1.加载配置文件
InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties pros = new Properties();
pros.load(is);
//2.读取配置信息
String user = pros.getProperty("user");
String password = pros.getProperty("password");
String url = pros.getProperty("url");
String driverClass = pros.getProperty("driverClass");
//3.加载驱动
Class.forName(driverClass);
//4.获取连接
conn = DriverManager.getConnection(url,user,password);
}catch (Exception e) {
e.printStackTrace();
}
return conn;
}
jdbc.propeities文件的内容
user=root
password=123456
url=jdbc:mysql://localhost:3306/test
driverClass=com.mysql.jdbc.Driver
这里我就不解释了,你要是看不懂,我觉得你应该再回过头看看JAVA基础里面的反射和MAP集合。
操作数据库
一切准备工作就绪,接下来就是操作数据库的时候了。
操作数据库有两种方式
1.Statement
2.PreparedStatement
这俩都是接口,PreparedStatement还是Statement的子接口,不过我们一般都选择用第二个。
原因如下
1是Statement太麻烦了,它使用字符拼接的方式拼接sql,
2是不能防止sql注入,SQL注入可是个大麻烦啊,万一被别人悄悄咪咪的溜进你的数据库你岂不是不完蛋了。
那我们就写一下第二种吧,第一种反正不好用,这叫去其糟糠,取其精华。
写个增加跟查询吧
public void addCourse(String courseName){
String sql = "insert into t_course(course_name) values(?)";
Connection conn = null;
PreparedStatement pstmt = null;
try{
conn = DbUtil.getConnection();
pstmt = (PreparedStatement) conn.prepareStatement(sql);
pstmt.setString(1, courseName); //给占位符赋值
pstmt.executeUpdate(); //执行
}catch(SQLException e){
e.printStackTrace();
}
finally{
DbUtil.close(pstmt);
DbUtil.close(conn); //必须关闭
}
}
查询就相对来说难一点,当然只是相对来说
public <T> T getInstance(Class<T> clazz, String sql, Object... args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//获取数据库连接
conn = JDBCUtils.getConnection();
// 预编译sql语句,得到PreparedStatement对象
ps = conn.prepareStatement(sql);
//填充占位符
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
//执行executeQuery(),得到结果集:ResultSet
rs = ps.executeQuery();
//得到结果集的元数据:ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();
//通过ResultSetMetaData得到columnCount,columnLabel;通过ResultSet得到列值,columnCount即为属性的数量
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
T t = clazz.newInstance();
for (int i = 0; i < columnCount; i++) {// 遍历每一个列
// 先把列的值获取到
Object columnVal = rs.getObject(i + 1);
// 获取列的别名:列的别名,使用类的属性名充当
String columnLabel = rsmd.getColumnLabel(i + 1);
//使用反射,给对象的相应属性赋值
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnVal);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭资源
DbUtil.close(pstmt);
DbUtil.close(conn);
DbUtil.close(rs);
}
return null;
}
那些什么DBUtils什么的我就不写了,因为我也不咋会
还有那些调用存储过程啦,什么函数啦,什么事务啦,日后再搞
然后就没什么可以写的了,还是祝大家莫要秃头