一、JDBC讲解
1.1 JDBC的概念
JDBC(JAVA DASTABASE CONNECTION)是java提供的链接数据库的应用程序,使用java代码进行向数据库的服务端发送sql指令,并且完成事务操作的功能。
图示
1.2 JDBC主要类的介绍
-
Driver:JDBC的数据库驱动,表示选择哪个数据库进行连接操作。获取Driver使用的是ManagerDriver。
-
Connection:JDBC获取链接的对象,表示已经链接上之后获取的对象,获取链接由驱动管理完成,ManagerDriver.getConnection();该对象表示数据库的链接。
-
Statement:用来发送需要执行的SQL指令,并调用调用方法进行执行SQL指令,由Connection对象获取Statement对象,调用的是createStatement();方法进行获取对象。
-
PreparedStatement:是statement类的子类,比起statement更加优化,可以实现预编译对象。建议开发的时候使用该对象替换Satement对象。由Connection对象获取,调用PrepareStatement()方法获取。
涉及的方法:
1)execute():将SQL指令执行,不推荐使用,不区分是增、删、改还是查询。
2)executeQuery():将查询的SQL指令执行,当SQL用于查询的时候,使用该方法,返回值为ResultSet
3)executeUpdate():将增、删、改的SQL指令执行,当SQL用于修改数据的时候使用该方法,返回值为int,表示修改的行数。
-
ResultSet:表示执行完SQL指令后,获得的结果集存放的集合。
1.3 入门程序
/*
* DJBC的入门程序
*/
public class Demo1 {
/*
* 主函数
*/
public static void main(String[] args) {
try {
//1、注册驱动:将JDBC的应用程序关联起来加载,需要用到反射
Class.forName("com.mysql.jdbc.Driver");
/*2、获取链接:
* url:表示链接数据库的url地址,链接本机为:jdbc:mysql://127.0.0.1:3306/数据库名
* urse:数据库的用户名,一般自己的为root
* password:数据库的密码
*/
String url = "jdbc:mysql://127.0.0.1/db_school";
String user = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, user, password);
//3、获取可以发送sql指令的对象
Statement st = conn.createStatement();
//4、编写sql语句,并执行
String sql = "select * from t_student";
ResultSet rs = st.executeQuery(sql);
//5、通过结果集获取数据,编辑结果集ResultSet
while(rs.next()) {
//获取结果集中的数据
//getInt(int columnIndex):取出结果中的第几列,不推荐
//getInt(String columnLabel):取出字段名相同的数据,推荐方式
int id = rs.getInt("s_id");
System.out.println("id = "+id);
String name = rs.getString("s_name");
System.out.println("name = "+name);
}
//6、关闭资源,3个,先开的后关
rs.close();
st.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.4 JDBC的示例代码
-
新增数据
/** * * @ClassName: InsertDemo * @Description: JDBC新增的代码 * @author Alon * @date 2020年12月29日 上午11:15:56 */ public class InsertDemo { public static void main(String[] args) { try { //1、加载驱动 Class.forName("com.mysql.jdbc.Driver"); //在url里面需要处理编码集,不处理会出现乱码问题 String url = "jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8"; String user = "root"; String password = "root"; //2、获取链接 Connection conn = DriverManager.getConnection(url, user, password); //3、创建执行sql的对象,推荐使用预编译的对象,如果使用预编译对象,那么可以使用填充方式将参数填入 String sql = "insert into t_student(s_name,s_age,s_sex) value(?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); //将?占位符替换 ps.setString(1, "李四"); ps.setInt(2, 20); ps.setString(3, "保密"); //4、执行sql int row = ps.executeUpdate(); System.out.println(row); //5、关闭资源 ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
-
修改数据
/** * * @ClassName: UpdateDemo * @Description: 更新数据的demo * @author Alon * @date 2020年12月29日 上午11:27:41 */ public class UpdateDemo { public static void main(String[] args) { try { //1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2、获取链接 String url = "jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8"; String user = "root"; String password = "root"; Connection conn = DriverManager.getConnection(url, user, password); //3、获取预编译对象 String sql = "update t_student set s_name = ? where s_id = ?"; PreparedStatement ps = conn.prepareStatement(sql); //替换占位符 ps.setString(1, "李华"); ps.setInt(2, 1); //4、执行sql语句 int row = ps.executeUpdate(); System.out.println(row); //5、关闭资源 ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
-
删除数据
/** * * @ClassName: DeleteDemo * @Description: 删除数据的demo * @author Alon * @date 2020年12月29日 上午11:33:05 */ public class DeleteDemo { public static void main(String[] args) { try { //1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2、获取链接 String url = "jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8"; String user = "root"; String password = "root"; Connection conn = DriverManager.getConnection(url, user, password); //3、获取预编译对象 String sql = "delete from t_student where s_id = ?"; PreparedStatement ps = conn.prepareStatement(sql); //替换占位符 ps.setInt(1, 2); //4、执行sql指令 int row = ps.executeUpdate(); System.out.println(row); //关闭资源 ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
-
查询语句
/** * * @ClassName: QueryDemo * @Description: 查询的demo * @author Alon * @date 2020年12月29日 上午11:37:15 */ public class QueryDemo { public static void main(String[] args) { try { //1、注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2、获取链接: String url = "jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8"; String user = "root"; String password = "root"; Connection conn = DriverManager.getConnection(url, user, password); //3、获取预编译对象 String sql = "select * from t_student where s_id = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 1); //4、执行sql ResultSet rs = ps.executeQuery(); while(rs.next()) { //获取值 int sId = rs.getInt("s_id"); String sName = rs.getString("s_name"); int sAge = rs.getInt("s_age"); String sSex = rs.getString("s_sex"); System.out.println("编号:"+sId+",姓名:"+sName+",年龄:"+sAge+",性别:"+sSex); } //关闭资源 rs.close(); ps.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } }
1.5 封装JDBC方法
- 可以将注册驱动放到工具类中
2)可以将连接的方法放到工具类中
3)可以将关闭资源的方法放到工具类中,关闭资源有两种情况,因此最好使用重载。
/**
*
* @ClassName: JDBCUtils
* @Description: JDBC的工具类
* @author Alon
* @date 2020年12月29日 下午2:16:08
*/
public class JDBCUtils {
//将参数定义
private static final String driver = "com.mysql.jdbc.Driver";
private static final String url = "jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8";
private static final String user = "root";
private static final String password = "root";
//静态代码块进行注册驱动
static {
try {
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//提供一个公共的获取链接的方法
public static Connection getConn() {
//声明一个链接
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
*
* @Title: close
* @Description: 关闭资源
* @param @param conn 链接
* @param @param ps 预编译对象
* @return void
* @throws
*/
public static void close(Connection conn,PreparedStatement ps) {
try {
if(ps != null) {
ps.close();
}
if(conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
*
* @Title: close
* @Description: 关闭资源,三种参数的重载形式
* @param @param conn 链接对象
* @param @param ps 预编译对象
* @param @param rs 结果集对象
* @return void
* @throws
*/
public static void close(Connection conn,PreparedStatement ps,ResultSet rs) {
try {
if(rs != null) {
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
close(conn,ps);
}
}
1.6 深度分装JDBC
-
创建配置文件db.properties,要放在src目录下
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8 user=root password=root
-
思维:解决硬编码的问题,将参数用配置文件进行配置。
/** * * @ClassName: JDBCUtils2 * @Description: 深度封装JDBC * @author Alon * @date 2020年12月29日 下午3:21:27 */ public class JDBCUtils2 { //声明四个变量 private static String driver; private static String url; private static String user; private static String password; //使用静态代码块完成注册驱动以及读取properties文件内容。并将值读取后赋值给变量 static { try { //读取properties文件 //获取流 InputStream in = JDBCUtils2.class.getClassLoader().getResourceAsStream("db.properties"); //创建Properties对象,该对象专门用来读取.properties类型的文件。 Properties prop = new Properties(); //将读取到文件的输入流加载到prop对象中 prop.load(in); //获取值 driver = prop.getProperty("driver"); url = prop.getProperty("url"); user = prop.getProperty("user"); password = prop.getProperty("password"); //注册驱动 Class.forName(driver); } catch (Exception e) { e.printStackTrace(); } } /** * * @Title: getConn * @Description: 获取链接 * @param @return * @return Connection 返回链接对象 * @throws */ public static Connection getConn() { try { return DriverManager.getConnection(url, user, password); } catch (Exception e) { e.printStackTrace(); } return null; } /** * * @Title: close * @Description: 关闭资源 * @param @param conn * @param @param ps * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps) { try { if(ps != null) { ps.close(); } if(conn != null) { conn.close(); } } catch (Exception e) { e.printStackTrace(); } } /** * * @Title: close * @Description: 关闭资源,重载形式 * @param @param conn * @param @param ps * @param @param rs * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps,ResultSet rs) { try { if(rs != null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } close(conn,ps); } }
1.7c3p0连接池
-
配置文件及参数,名字必须是c3p0-config.xml,而且要放在src目录下
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <!--mysql数据库连接的各项参数--> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_school?useUnicode=true&characterEncoding=utf-8</property> <property name="user">root</property> <property name="password">root</property> <!--配置数据库连接池的初始连接数、最小链接数、获取连接数、最大连接数、最大空闲时间--> <property name="initialPoolSize">10</property> <property name="minPoolSize">10</property> <property name="acquireIncrement">5</property> <property name="maxPoolSize">100</property> <property name="maxIdleTime">30</property> </default-config> </c3p0-config>
-
java代码
/** * * @ClassName: C3P0Utils * @Description:c3p0连接池的工具类 * @author Alon * @date 2020年12月29日 下午4:39:46 */ public class C3P0Utils { //声明并创建一个数据源 //实际上ComboPooledDataSource()有参数,如果在配置文件中是default-config则不需要写名称 //如果在配置文件中,不是default-config,则需要写名称 private static DataSource dataSource = new ComboPooledDataSource("mysql-config"); public static Connection getConn() { try { return dataSource.getConnection(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * * @Title: close * @Description: 关闭资源 * @param @param conn 数据库链接 * @param @param ps 预编译对象 * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps) { try { if(ps != null) { ps.close(); } if(conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * * @Title: close * @Description: 关闭资源,三种参数的重载形式 * @param @param conn 链接对象 * @param @param ps 预编译对象 * @param @param rs 结果集对象 * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps,ResultSet rs) { try { if(rs != null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } close(conn,ps); } }
1.8 Druid连接池
-
目前市场主流的连接池
-
db.properties配置文件
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1/db_school?useUnicode=true&characterEncoding=utf-8 username=root password=root initialSize=10 maxActive=300 maxWait=60000
-
java文件
/** * * @ClassName: DruidUtils * @Description: Druid连接池的工具类 * @author Alon * @date 2020年12月29日 下午5:15:13 */ public class DruidUtils { private static DataSource dataSource; //声明一个连接池对象 static { try { InputStream in = DruidUtils.class.getClassLoader().getResourceAsStream("db.properties"); Properties prop = new Properties(); prop.load(in); dataSource = DruidDataSourceFactory.createDataSource(prop); } catch (Exception e) { e.printStackTrace(); } } /** * * @Title: getConn * @Description: 获取链接 * @param @return * @return Connection * @throws */ public static Connection getConn() { try { return dataSource.getConnection(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * * @Title: close * @Description: 关闭资源 * @param @param conn 数据库链接 * @param @param ps 预编译对象 * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps) { try { if(ps != null) { ps.close(); } if(conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * * @Title: close * @Description: 关闭资源,三种参数的重载形式 * @param @param conn 链接对象 * @param @param ps 预编译对象 * @param @param rs 结果集对象 * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps,ResultSet rs) { try { if(rs != null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } close(conn,ps); } } } catch (SQLException e) { e.printStackTrace(); } } /** * * @Title: close * @Description: 关闭资源,三种参数的重载形式 * @param @param conn 链接对象 * @param @param ps 预编译对象 * @param @param rs 结果集对象 * @return void * @throws */ public static void close(Connection conn,PreparedStatement ps,ResultSet rs) { try { if(rs != null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } close(conn,ps); } }