四.c3p0连接池
3>. c3p0:数据库连接池技术
c3p0 基本使用
步骤:
1. 导入jar包 (两个+一个sql) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
* 不要忘记导入数据库驱动jar包
2. 定义配置文件:
* 名称: c3p0.properties 或者 c3p0-config.xml [ 必须是这两个固定的名称之一 ]
* 路径:直接将文件放在src目录下即可
3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
4. 获取连接: getConnection
<c3p0-config> <!-- 使用默认的配置读取连接池对象 --> <default-config> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest</property> <property name="user">root</property> <property name="password">root</property> <!-- 连接池参数 --> <!--initialPoolSize:初始化申请的链接数量--> <property name="initialPoolSize">5</property> <!--maxPoolSize:最大的连接数量--> <property name="maxPoolSize">10</property> <!--checkoutTimeout:超时时间--> <property name="checkoutTimeout">3000</property> </default-config> <named-config name="otherc3p0"> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest</property> <property name="user">root</property> <property name="password">root</property> <!-- 连接池参数 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">8</property> <property name="checkoutTimeout">1000</property> </named-config> </c3p0-config>
指定参数的连接
五. Druid连接池
4>. druid数据库连接池
Druid数据库连接池实现技术,由阿里巴巴提供的
步骤:
1.导入jar包 druid-1.0.9.jar
2. 定义配置文件:
* 是properties形式的
* 可以叫任意名称,可以放在任意目录下
3. 加载配置文件。Properties
4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
5. 获取连接:getConnection
* 代码:
//3.加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream(“druid.properties”);
pro.load(is);
//4.获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5.获取连接
Connection conn = ds.getConnection();
driverClassName=com.mysql.jdbc.Driver
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/db3 username=root password=root initialSize=5 maxActive=10 maxWait=3000
六. Druid工具类
5>. 工具类 [ 重点掌握 ]
# druid.properties driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcTest username=root password=root # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000
public class JDBCUtils { //1.定义成员变量 DataSource private static DataSource ds; static { try { //1.加载配置文件 Properties prop=new Properties(); prop.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.获取DataSource ds= DruidDataSourceFactory.createDataSource(prop); } 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(); } } } /* * 释放资源: 查看 * */ 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(); } } } /* * 获取连接池方法 * 得到数据源,为Spring的JdbcTemplate做铺垫 * */ public static DataSource getDataSource(){ return ds; } }
//使用新的工具类 public class DruidDemo { public static void main(String[] args){ /* * 完成一个添加的操作 * */ //1.获取连接 Connection conn = null; PreparedStatement pstmt=null; try { conn = JDBCUtils.getConnection(); System.out.println(conn); //2.定义sql String sql="insert into account values (null ,?,?)"; //3.获取pstmt对象 pstmt=conn.prepareStatement(sql); //4. 给?赋值 pstmt.setString(1,"小智"); pstmt.setDouble(2,2000); //5. 执行sql int i = pstmt.executeUpdate(); System.out.println(i); } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(pstmt,conn); } } }
七. Spring JdbcTemplate
Spring JDBC
Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
①.update( ):执行DML语句。增、删、改语句
②. queryForMap( ):查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合
注意:这个方法查询的结果集长度只能是1
③. queryForList():查询结果将结果集封装为list集合
注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
④.query(String sql,new RowMapper<类型>(){})
⑤.query(Sting sql,new BeanPropertyRowMapper<类型>(类.class)):一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装
⑥.queryForObject(String sql,new BeanPropertyRowMapper<类名字>(类名字.class),arg.....)
注意:上面quertyForObject查询出来的结果如果为空,则会抛出异常,一般会用try-catche进行处理
queryForObject(String sql,类.class):查询结果,将结果封装为对象(一般用于聚合函数的查询)
# 修改account表中的一条记录 public class jdbcTemplateDemo { private static DataSource ds; static{ try { Properties prop=new Properties(); prop.load(jdbcTemplateDemo.class.getClassLoader().getResourceAsStream("jdbc.properties")); ds= DruidDataSourceFactory.createDataSource(prop); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { //1.导入jar包 //2.创建JDBCTemplate对象 JdbcTemplate jdbcTemplate=new JdbcTemplate(getDataSource()); //3.调用方法 String sql="update account set money=500 where id=?"; int count=jdbcTemplate.update(sql,1); } public static DataSource getDataSource(){ return ds; } }
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>() { //每查询一个对象都会创建一个mapRow方法 @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); } }
练习 [ 重点掌握 ]
注意:运用JdbcTemplate进行查询的时候,都要在query 中传入对象
create table if not exists stutb(
name varchar(225),
age int,
sex char,
department varchar(225),
score int);
第二题:分析以下需求,并用代码实现
模拟数据备份,已知项目根路径下有如下学生名单stus.txt,内容如下:
张三丰-103-男-iOS就业班-100
李峰-23-男-iOS基础班-90
张飞-36-男-javaEE基础班-40
田甜-23-女-UI基础班-80
李根-40-男-javaEE就业班-9
朱迪-18-女-javaEE基础班-100
注意:数据分别代表 : 姓名 年龄 性别 班级 分数
将该文件中的内容写入到studb库stutb表中,该表结构是
连接数据库完成以下操作 1.利用JDBC连接studb数据库 2.利用JDBC删除studb库stutb表中的所有信息,然后读取项目根路径下的stus.txt文件,将文件内容插入到stutb表中(利用JDBC) 3.利用JDBC查询出基础班在读的男学员的所有信息按成绩的降序输出到控制台上(利用JDBC) 4.利用JDBC将李根的年龄改为20,班级改为javaEE基础班(利用JDBC)
public class day09 { private static JdbcTemplate template=new JdbcTemplate(JDBCTools.getDataSource()); @Test public void fun1()throws Exception{ //1.利用JDBC连接studb数据库 Connection connection = JDBCTools.getConnection(); System.out.println(connection); } @Test public void fun2()throws Exception{ //1.利用JDBC删除studb库stutb表中的所有信息, // 然后读取项目根路径下的stus.txt文件, // 将文件内容插入到stutb表中(利用JDBC) String sql="delete from stutb"; int update = template.update(sql); //将数据写到表中 String sql2="insert into stutb values(?,?,?,?,?)"; BufferedReader fr=new BufferedReader(new FileReader("a.txt")); String line; while((line=fr.readLine())!=null){ //如果给?赋值的数据是一个数组,那么直接写数组的名称 String[]str=line.split("-"); template.update(sql2,str); } } @Test public void fun3()throws Exception{ //3.利用JDBC查询出基础班在读的男学员的 // 所有信息按成绩的降序输出到控制台上(利用JDBC) String sql="select * from stutb where sex=? and department like ? order by score desc"; //方法一:queryForList List<Map<String, Object>> lists = template.queryForList(sql, "男", "%基础班%"); for(Map<String,Object> list:lists){ System.out.println(list); } //方法二 : query() List<Studb> list = template.query(sql, new BeanPropertyRowMapper<Studb>(Studb.class),"男","%基础班%"); for (Studb studb : list) { System.out.println(studb); } //方法三 : 原始方法连接得到结果集 /* Connection conn = JDBCTools.getConnection(); PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1,"男"); pstm.setString(2,"男"); ResultSet rs = pstm.executeQuery(); while(rs.next()){ System.out.println(rs.getString("name")+" "+rs.getInt("score")); }*/ } @Test public void fun4(){ //4.利用JDBC将李根的年龄改为20,班级改为javaEE基础班(利用JDBC) String sql="update stutb set age=?,department=? where name=?"; template.update(sql,20,"javaEE基础班","李根"); } }