浅谈synchronized
JDBC是SUN公司提供的一套用于数据库操作的接口,Java程序员只需要面向这套接口编程即可。不同的数据库厂商,需要针对这套接口,提供不同实现。
使用JDBC的好处:1、程序员不需要关注不同数据库的细节。2、编写的代码具有更好的移植性。
下面是JDBC技术的两种实现方式,这篇文章先只介绍JDBC的手动实现,下一篇文章将介绍使用数据库连接池技术,也就是右边的路线。
零:首先要将对应的数据库的驱动导入到项目中。
一、获取连接
获取连接需要四个信息,分别是:对应数据库的驱动(这里以MySQL数据库为例)、url、用户名、密码。
但是我们一般不直接使用Driver,而是用DriverManager替换Driver来进行驱动的注册、加载、获取连接。
我们将获取连接所需要的四个信息放在properties文件中。
这是properties文件的代码,driverClass是对应的数据库的驱动;url的写法:jdbc:mysql:是协议,localhost:这里是ip地址,3306是对应的端口号,test是要操作的数据库的库名称。
driverClass=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test
user=root password=1234
接下来就是获取连接的的代码:(这里我将关闭资源、关闭连接的代码写在了一起,作为工具类使用,况且后面也会使用到)
OpenResty学习指南(一)
package jdbc_1; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JDBCUtils { /* * 获取数据库的连接 */
public static Connection getConnection() throws Exception { //1.读取配置文件
Properties pros = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); pros.load(is); String driverClass = pros.getProperty("driverClass"); String url = pros.getProperty("url"); String user = pros.getProperty("user"); String password = pros.getProperty("password"); //2.使用反射获取Driver的实现类对象
Class clazz = Class.forName(driverClass); Driver driver = (Driver) clazz.newInstance(); //3.利用DriverManager注册驱动
DriverManager.registerDriver(driver); //4.利用DriverManager获取连接
Connection conn = DriverManager.getConnection(url, user, password); return conn; } /* * 关闭资源操作 * conn是关闭的连接 * ps是要关闭的PreparedStatement,增删改查都用得到 * rs是要关闭的ResultSet,查询的操作才用得到 */
public static void closeResource(Connection conn,Statement ps,ResultSet rs) { try { if(ps != null) { ps.close(); } }catch(SQLException e) { e.printStackTrace(); } try { if(conn != null) { conn.close(); } }catch(SQLException e) { e.printStackTrace(); }
try { if(rs != null) { rs.close(); } }catch (SQLException e) { e.printStackTrace(); } } }
二、使用PreparedStatement实现增删改、查操作
注:这里我将增删改放在一起,查单独放在一边,因为查需要返回值,而增删改可以不需要返回值。
使用PreparedStatement的好处:解决了Statement的拼接、sql注入、无法操作Blob型数据的问题,还进行更高效的批量操作。
注意:以下的增删改查操作我都是放在JDBCUtils类里面的,作为工具使用
/* *通用的增删改操作 *sql中的占位符的个数应该与可变形参的长度相同! */
public static void update(String sql,Object...args) { //1.获取数据库连接
Connection conn = null; //2.预编译sql语句,返回PreparedStatement的实例
PreparedStatement ps = null; try { conn = JDBCUtils.getConnection(); ps = conn.prepareStatement(sql); //3.填充占位符
for(int i = 0; i < args.length; i++) { ps.setObject(i+1, args[i]); //MySQL数据库中是从1开始计数的
} //4.执行
ps.execute(); } catch (Exception e) { e.printStackTrace(); }finally { //5.关闭资源,关闭连接
JDBCUtils.closeResource(conn, ps, null); } }
接下来是通用的查询操作:
/* * 针对于不同的表的通用的查询操作,查询一条或多条记录 * 第一个参数为需要从数据库表中得到的一条数据所创建的类 * 第二个参数为查询操作的sql语句 * 第三个参数用来填充占位符 */
public static <T> List<T> getForList(Class<T> clazz,String sql,Object...args) { Connection conn = null ; PreparedStatement ps = null; ResultSet rs = null; try { //1.获取连接
conn = JDBCUtils.getConnection(); //2.预编译的sql语句,获取PreparedStatement对象
ps = conn.prepareStatement(sql); //3.填充占位符
for(int i = 0; i < args.length; i++) { ps.setObject(i+1, args[i]); } //4.获取结果集
rs = ps.executeQuery(); //5.获取结果集元数据
ResultSetMetaData rsmd = rs.getMetaData(); //6.获取列数
int columnCount = rsmd.getColumnCount(); //7.创建集合对象
ArrayList<T> list = new ArrayList<T>(); while(rs.next()) { //8.通过获取类的实例
T t = clazz.newInstance(); for(int i = 0 ; i < columnCount; i++) { //9.获取列值
Object columnValue = rs.getObject(i+1); //10.获取列的别名
String columnLabel = rsmd.getColumnLabel(i+1); //11.给每个列的别名赋予对应的列值,使用反射
Field field = clazz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t, columnValue); } //12.将得到的对象添加进list中
list.add(t); } return list; } catch (Exception e) { e.printStackTrace(); }finally { //13.关闭资源
JDBCUtils.closeResource(conn, ps, rs); } return null; }
三、关闭资源和关闭连接
代码在获取连接的代码中
以上就是本期的全部代码了,第二次写,在尽力美化排版。
欢迎大家阅后和我交流,当然学渣能力有限,代码和知识点可能有错误,也欢迎大家告诉我!
Docker Swarm 从入门到放弃