主要步骤: 1.注册驱动 2.创建连接 3.操作数据 4.输出结果集 5.释放资源
A.单纯的数据库连接代码
import java.sql.*; public class MySqltest { public static void main(Stringargs[])throwsSQLException,ClassNotFoundException { String Url="jdbc:mysql://127.0.0.1:3306/test"; String User="root"; String Password="root"; //1.加载驱动程序 Class.forName("com.mysql.jdbc.Driver"); //2.获得数据库链接 Connection con=DriverManager.getConnection(Url,User,Password); //3.通过数据库的连接操作数据库,实现增删改查(使用Statement类) Statement st=con.createStatement(); ResultSet rs=st.executeQuery("select * from user "); //4.处理数据库的返回结果(使用ResultSet类) while (rs.next()) { System.out.println("username"+rs.getString("name")); } //关闭资源 ,后创建的先关闭 rs.close(); st.close(); con.close(); } }解释一下用到的类
Statement适合用于查询数据。st.executeQuery(sql) preparedStatement适合增删改数据,防止注入攻击. ResultSet是执行后返回的结果集类
pstmt=conn.prepareStatement("insert into student values(?,?,? )"); pstmt.setString(1, “小明"); pstmt.setInt(2, 27); pstmt.setFloat(3, 85); pstmt.executeUpdate();B.升级版的JDBC代码(配置文件jdbc.properties)
使用 eclipse 在 src 目录下创建 jdbc.properties 文件,写入健值对:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/store user=root password=root package com.test.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ResourceBundle; public final class JDBCUtilsPlus { private static final String DRIVER; private static final String URL; private static final String USER; private static final String PASSWORD; private JDBCUtilsPlus(){} static { ResourceBundle bundle = ResourceBundle.getBundle("jdbc"); DRIVER = bundle.getString("driver"); URL = bundle.getString("url"); USER = bundle.getString("user"); PASSWORD = bundle.getString("password"); /** * 驱动注册 */ try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { throw new ExceptionInInitializerError(e); } } /** * 获取 Connetion * @return * @throws SQLException */ public static Connection getConnection() throws SQLException{ return DriverManager.getConnection(URL, USER, PASSWORD); } /** * 释放资源 * @param conn * @param st * @param rs */ public static void colseResource(Connection conn,Statement st,ResultSet rs) { closeResultSet(rs); closeStatement(st); closeConnection(conn); } /** * 释放连接 Connection * @param conn */ public static void closeConnection(Connection conn) { if(conn !=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } //等待垃圾回收 conn = null; } /** * 释放语句执行者 Statement * @param st */ public static void closeStatement(Statement st) { if(st !=null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } //等待垃圾回收 st = null; } /** * 释放结果集 ResultSet * @param rs */ public static void closeResultSet(ResultSet rs) { if(rs !=null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } //等待垃圾回收 rs = null; } }测试使用工具类
package com.test.jdbcTest; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.junit.Test; import com.test.utils.JDBCUtils; import com.test.utils.JDBCUtilsPlus; public class JdbcTest { @Test public void select() { Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { // 获取连接 conn = JDBCUtilsPlus.getConnection(); // 编写sql String sql = "select * from category"; // 创建语句执行者 st= conn.prepareStatement(sql); rs = st.executeQuery(); while(rs.next()) { System.out.println(rs.getString(1)+"..."+rs.getString(2)); } } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtilsPlus.colseResource(conn, st, rs); } } }背景 :又提到池的概念,与线程池的概念相似,创建多个连接放入池中,被人调用后归还。详细不想介绍了,可以查看我以前的多线程的那篇文章。
A.使用c3p0连接池 1.导入jar包(两个)mchange-commons-java-0.2.15.jar,c3p0-0.9.5.2.jar。以后学了maven就可以不用自己找jar包导入了。 2.定义配置文件c3p0-config.xml或者c3p0.properties 3.创建核心对象,数据库连接池对象,CombopooledDataSource 4.获取连接:getConnection
在src下创建c3p0-config.xml
<c3p0-config> <default-config> <!-- 连接参数--> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql:///day01</property> <property name="user">root</property> <property name="password">root</property> <!-- 连接池参数--> <!-- 初始化申请的连接数量--> <property name="initialPoolSize">5</property> <!-- 最大的连接数量--> <property name="maxPoolSize">10</property> <!-- 超时时间--> <property name="checkoutTimeout">3000</property> </default-config> </c3p0-config>JDBCUtils工具类模板
package com.wang.utils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JDBCUtils { static ComboPooledDataSource dataSource = null; static { dataSource = new ComboPooledDataSource(); } public static DataSource getDataSource() { return dataSource; } /** * 获取连接对象 * @return * @throws SQLException */ public static Connection getConn() throws SQLException { return dataSource.getConnection(); } /** * 释放资源 * @param conn * @param st * @param rs */ public static void release(Connection conn, Statement st, ResultSet rs) { closeRs(rs); closeSt(st); closeConn(conn); } public static void release(Connection conn, Statement st) { closeSt(st); closeConn(conn); } private static void closeRs(ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } finally { rs = null; } } private static void closeSt(Statement st) { try { if (st != null) { st.close(); } } catch (SQLException e) { e.printStackTrace(); } finally { st = null; } } private static void closeConn(Connection conn) { try { if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } finally { conn = null; } } }检测代码
package com.wang.daoImpl; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import com.wang.dao.UserDao; import com.wang.utils.JDBCUtils; public class UserDaoImpl implements UserDao{ public void showAll() { Connection conn = null; Statement st = null; ResultSet rs = null; try { //1.连接对象 conn = JDBCUtils.getConn(); //2.获取Statement对象,该对象主要跟sql语句进行操作CRUD st = conn.createStatement(); //3.执行sql语句,返回结果集合 rs = st.executeQuery("select * from t_user"); //4.输出结果集合 while(rs.next()) { String password = rs.getString("password"); String name = rs.getString("username"); int id = rs.getInt("id"); System.out.println("id="+id+"name="+name+"password="+password); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { JDBCUtils.release(conn,st,rs); } } }B.使用druid连接池(阿里巴巴提供,是最优秀的连接池之一)
1.导入依赖(导入jar包)druid-1.0.9.jar 2.配置文件druid.properties 3.获取 数据库连接池对象:通过工厂来获取 DruidDataSourceFactory 4.获取连接:getConnection
配置文件druid.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/db username=root password=123456 # 初始化连接数 initialSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000 //1.导入jar包 //2.定义配置文件 Properties properties = new Properties(); //3.加载配置文件 properties.load(DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties")); //4.创建连接池对象 DataSource ds = DruidDataSourceFactory.createDataSource(properties); //5.获取连接 Connection conn = ds.getConnection();具体的工具类,使用方法和c3p0相似。
C.Spring JDBC
Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发 步骤:导入jar包
创建JdbcTemplate对象。依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(ds);调用JdbcTemplate的方法来完成CRUD的操作
update():执行DML语句。增、删、改语句queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合 注意:这个方法查询的结果集长度只能是1 queryForList():查询结果将结果集封装为list集合 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中 query():查询结果,将结果封装为JavaBean对象 query的参数:RowMapper 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装new BeanPropertyRowMapper<类型>(类型.class) queryForObject:查询结果,将结果封装为对象 一般用于聚合函数的查询练习:
需求: 修改1号数据的 salary 为 10000添加一条记录删除刚才添加的记录查询id为1的记录,将其封装为Map集合查询所有记录,将其封装为List查询所有记录,将其封装为Emp对象的List集合查询总记录数 import cn.itcast.domain.Emp; import cn.itcast.utils.JDBCUtils; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; public class JdbcTemplateDemo2 { //Junit单元测试,可以让方法独立执行 //1. 获取JDBCTemplate对象 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /** * 1. 修改1号数据的 salary 为 10000 */ @Test public void test1(){ //2. 定义sql String sql = "update emp set salary = 10000 where id = 1001"; //3. 执行sql int count = template.update(sql); System.out.println(count); } /** * 2. 添加一条记录 */ @Test public void test2(){ String sql = "insert into emp(id,ename,dept_id) values(?,?,?)"; int count = template.update(sql, 1015, "郭靖", 10); System.out.println(count); } /** * 3.删除刚才添加的记录 */ @Test public void test3(){ String sql = "delete from emp where id = ?"; int count = template.update(sql, 1015); System.out.println(count); } /** * 4.查询id为1001的记录,将其封装为Map集合 * 注意:这个方法查询的结果集长度只能是1 */ @Test public void test4(){ String sql = "select * from emp where id = ? or id = ?"; Map<String, Object> map = template.queryForMap(sql, 1001,1002); System.out.println(map); //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20} } /** * 5. 查询所有记录,将其封装为List */ @Test public void test5(){ String sql = "select * from emp"; List<Map<String, Object>> list = template.queryForList(sql); for (Map<String, Object> stringObjectMap : list) { System.out.println(stringObjectMap); } } /** * 6. 查询所有记录,将其封装为Emp对象的List集合 */ @Test public void test6(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new RowMapper<Emp>() { @Override public Emp mapRow(ResultSet rs, int i) throws SQLException { Emp emp = new Emp(); int id = rs.getInt("id"); String ename = rs.getString("ename"); int job_id = rs.getInt("job_id"); int mgr = rs.getInt("mgr"); Date joindate = rs.getDate("joindate"); double salary = rs.getDouble("salary"); double bonus = rs.getDouble("bonus"); int dept_id = rs.getInt("dept_id"); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); emp.setMgr(mgr); emp.setJoindate(joindate); emp.setSalary(salary); emp.setBonus(bonus); emp.setDept_id(dept_id); return emp; } }); for (Emp emp : list) { System.out.println(emp); } } /** * 6. 查询所有记录,将其封装为Emp对象的List集合 */ @Test public void test6_2(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class)); for (Emp emp : list) { System.out.println(emp); } } /** * 7. 查询总记录数 */ @Test public void test7(){ String sql = "select count(id) from emp"; Long total = template.queryForObject(sql, Long.class); System.out.println(total); } }JDBCUtils
package cn.itcast.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /** * Druid连接池的工具类 */ public class JDBCUtils { //1.定义成员变量 DataSource private static DataSource ds ; static{ try { //1.加载配置文件 Properties pro = new Properties(); pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.获取DataSource ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /** * 释放资源 */ public static void close(Statement stmt,Connection conn){ /* if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } }*/ close(null,stmt,conn); } public static void close(ResultSet rs , Statement stmt, Connection conn){ if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } } } /** * 获取连接池方法 */ public static DataSource getDataSource(){ return ds; } }