步骤
- 注册驱动
- 创建连接
- 创建sql预执行对象
- 创建sql语句
- 执行sql语句
- 获取结果集解析封装
- 关闭资源
步骤详解
1. 注册驱动
常用的有3种方式:
1) 直接注册驱动:
DriverManager.registerDriver(com.mysql.jdbc.Driver);这种方式要求程序首先要引入驱动包,否则无法通过编译。而且它可能会造成DriverManager中产生两个一样的驱动,并对具体的驱动类产生依赖,所以不推荐使用。
2) 键值对方式:
System.setProperty(“jdbc.drivers”,”com.mysql.jdbc.Driver”);同时注册多个驱动则用冒号隔开。这种方式如果事先不引入驱动包的情况下能通过编译(因为操作的都为字符串,运行时肯定不行啦),所以虽然不会对具体的驱动类产生依赖,但注册不太方便,所以很少使用。
3) Class.forName方式(类似反射):
Class.forName(“com.mysql.jdbc.Driver”); Class.forName函数的作用是根据类的名字将类装载到虚拟机中(并未实例化);这种方式也不会对具体的驱动类产生依赖,而且使用很方便,所以推荐使用。
2. 建立连接
Connection conn=DriverManager.getConnection(url,uid,pwd);
url格式:JDBC:子协议:子名称//主机名:端口/数据库名?key=value&…
例如:jdbc:mysql://localhost:8086/jdbc;uid和pwd也可以用key=value的方式告诉数据库。
其它参数:如,userUnicode=true&characterEncoding=gbk
3. 创建执行sql语句的对象
这里有两个对象可以使用:Statement、PreparedStatement对象
一般来说有参数的sql操作都用PreparedStatement对象,因为它有防止sql注入等优点。两者的区别这里不多介绍,创建语句:(假设conn为数据库连接对象)
Statement st=conn.createStatement();
PreparedStatement ps=conn.prepareStatement(strSql);
可以看出在创建PreparedStatement对象时即需要指明要执行的sql语句,因为它会对sql语句进行预处理,例如进行一些防止sql注入的字符过滤等;而Statement则在执行sql动作时才指明sql语句。
4. 执行语句(CURD)
查询:st.executeQuery(strSql);或者ps. executeQuery();
非查询(增、删、改):st.executeUpdate(strSql);或ps.executeUpdate();
5. 处理执行结果
查询:返回值用ResultSet接收,例:ResultSet rs=st.executeQuery(strsql)
非查询(增、删、改):返回值为int
6. 释放资源
依次释放ResultSet、Statement(或PreparedStatement)、Connection对象,释放顺序与创建顺序相反(类似“栈”结构)。
注意,Connection是非常稀有的资源,用完必须马上释放,它的使用原则是尽量晚的创建,尽量早的释放,以减少占用资源的时间。
示例
public static void test() throws ClassNotFoundException, SQLException{
/*1.注册驱动(3种方法),依赖于驱动jar包的存在,否则无法通过编译
DriverManager.registerDriver(new com.mysql.jdbc.Driver());*/
//方法2:System.setProperties("jdbc.drivers","com.mysql.jdbc.Driver");
//方法3:*****推荐使用******
Class.forName("com.mysql.jdbc.Driver");
//2.建立连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:8086/jdbc","zhipeng","123456");
//3.创建语句执行对象
java.sql.Statement st=conn.createStatement();//使用Statement对象
//4.执行语句
ResultSet rs=st.executeQuery("select * from T_User");
//5.处理结果
while(rs.next()){
System.out.print(rs.getObject(1)+"\t"+rs.getObject(2)+"\t"+rs.getObject(3)+"\t");
}
//6.释放资源,资源rs、st、conn的释放顺序与创建顺序相反
rs.close();
st.close();
conn.close();
}
连接池操作
作用
1.消除频繁建立连接所需的负载
2.是用于管理数据库连接的管理对象
3.提供可共享,安全的连接
JdbcUtils
public class JDBCUtils {
private static DataSource ds;
private static String url;
private static String username;
private static String password;
private static String diver;
static {
Properties pro = new Properties();
InputStream in = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
try {
pro.load(in);
} catch (IOException e) {
e.printStackTrace();
}
try {
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDatasource(){
return ds;
}
// 4. 定义得到连接对象的方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
// 5.定义关闭资源的方法
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
// 6.重载关闭方法
public static void close(Connection conn, Statement stmt) {
close(conn, stmt, null);
}
}
JdbcTemplate
public class RouteImgImp implements RouteImgDao {
JdbcTemplate templete = new JdbcTemplate(JDBCUtils.getDatasource());
@Override
public List<RouteImg> findById(int rid) {
String sql = "select * from tab_route_img where rid = ? ";
List<RouteImg> routeImgs = templete.query(sql,new BeanPropertyRowMapper<RouteImg>(RouteImg.class),rid);
return routeImgs;
}
}
参考原文链接:https://blog.csdn.net/wang379275614/article/details/23393335