zoukankan      html  css  js  c++  java
  • java核心技术第四篇之JDBC第二篇

    01.JDBC连接池_连接池的概念:
    1).什么是连接池:对于多用户程序,为每个用户单独创建一个Connection,会使程序降低效率。这时我们可以创建一个"容器",
    这个容器中,先缓存一些Connection对象,有用户请求,就从池中取出一个Connection对象,当用户使用完毕,
    再将这个Connection放回到容器中,这个容器就叫:连接池。
    2).连接池的作用:先期缓存一些Connection对象,并对这些Connection进行反复的使用,回收,而不需要为每个用户单独创建Connection
    对象,从而可以提高程序的运行效率。
    3).很多的第三方厂商提供了连接池的实现,Sun公司提出,所有厂商的连接池必须实现:javax.sql.DataSource(接口)
    1).DBCP连接池:Apache公司的,commons项目组的成员,免费开源的。Tomcat内部使用的就是这个连接池。
    2).C3P0连接池【重要掌握】:开源免费的。整体性能要好于DBCP连接池。Spring、Hibernate框架内部使用这个连接池。
    02.JDBC连接池_DBCP连接池的使用:
    1).将DBCP的所需jar包复制到项目目录下,并且添加构建路径:
    commons-dbcp-1.4.jar
    commons-pool-1.6.jar
    2).复制DBCP的配置文件(dbcpcongif.properties)到项目的src目录下;
    (注意:要会修改配置文件中的四个必须的配置项--driverClassName、url、username、password)


    /*
    dbcpcongif.properties(配置文件)

    #连接设置--必须设置的
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/hei66_day21
    username=root
    password=1233

    #可选设置
    #<!-- 初始化连接 -->
    initialSize=10

    #最大连接数量
    maxActive=50

    #<!-- 最大空闲连接 -->
    maxIdle=20

    #<!-- 最小空闲连接 -->
    minIdle=5

    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000


    #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
    #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
    connectionProperties=useUnicode=true;characterEncoding=gbk

    #指定由连接池所创建的连接的自动提交(auto-commit)状态。
    defaultAutoCommit=true

    #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
    #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_UNCOMMITTED

    */

    /*

    3).使用连接池:
    1).读取配置文件信息:
    Properties pro = new Properties();
    pro.load(当前类名.class.getClassLoader().getResourceAsStream("配置文件的名"));//运行时会默认从bin目录下查找资源文件
    2).创建连接池对象
    BasicDataSource dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(pro);
    3).从连接池中获取Connection对象:
    Connection conn = dataSource.getConnection();
    4).发送SQL语句
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from products");
    while(rs.next()){
    System.out.println(rs.getInt("pid") + " " + rs.getString("pname"));
    }
    rs.close();
    stmt.close();
    conn.close();//不是关闭,是回收
    注意:配置文件中的四项必须配置项中的"键名"不要更改,是固定的名字,由DBCP内部读取。

    //DBCP连接池的使用
    public class Demo {
    public static void main(String[] args) throws Exception {
    //1.读取配置文件
    Properties pro = new Properties();
    pro.load(Demo.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));//在src(bin)下找配置文件
    //2.创建连接池对象
    BasicDataSource dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(pro);
    //3.从连接池中获取连接对象
    Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from products");
    while(rs.next()){
    System.out.println(rs.getInt("pid") + " " + rs.getString("pname"));
    }
    rs.close();
    stmt.close();
    conn.close();
    }
    }




    03.JDBC连接池_C3P0连接池的使用:
    1).将第三方所需的jar包复制到项目目录下:
    c3p0-0.9.2-pre5.jar
    mchange-commons-java-0.2.3.jar
    2).将c3p0-cinfig.xml配置文件复制到src目录下:文件名不要改,而且必须在src下,C3P0内部会自动去找
    (大家要会修改c3p0-config.xml中的四个必须项的配置:driverClass、jdbcUrl、user、password)

    */

    /*
    c3p0-cinfig.xml配置文件
    <c3p0-config>
    <!-- 默认配置,如果没有指定则使用这个配置 -->
    <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day31</property>
    <property name="user">root</property>
    <property name="password">root</property>
    <property name="checkoutTimeout">30000</property>
    <property name="idleConnectionTestPeriod">30</property>
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
    <property name="maxStatements">200</property>
    <user-overrides user="test-user">
    <property name="maxPoolSize">10</property>
    <property name="minPoolSize">1</property>
    <property name="maxStatements">0</property>
    </user-overrides>
    </default-config>

    <!-- 命名的配置 -->
    <named-config name="baidu">
    <!-- 连接数据库的4项基本参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day30_db</property>
    <property name="user">root</property>
    <property name="password">123</property>
    <!-- 如果池中数据连接不够时一次增长多少个 -->
    <property name="acquireIncrement">5</property>
    <!-- 初始化连接数 -->
    <property name="initialPoolSize">20</property>
    <!-- 最小连接数 -->
    <property name="minPoolSize">10</property>
    <!-- 最大连接数 -->
    <property name="maxPoolSize">40</property>
    <!-- -JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量 -->
    <property name="maxStatements">0</property>
    <!-- 连接池内单个连接所拥有的最大缓存statements数 -->
    <property name="maxStatementsPerConnection">5</property>
    </named-config>
    <!-- 命名的配置 -->
    <named-config name="heima">
    <!-- 连接数据库的4项基本参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day25_db</property>
    <property name="user">root</property>
    <property name="password">123</property>
    <!-- 如果池中数据连接不够时一次增长多少个 -->
    <property name="acquireIncrement">5</property>
    <!-- 初始化连接数 -->
    <property name="initialPoolSize">20</property>
    <!-- 最小连接受 -->
    <property name="minPoolSize">10</property>
    <!-- 最大连接数 -->
    <property name="maxPoolSize">40</property>
    <!-- -JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量 -->
    <property name="maxStatements">0</property>
    <!-- 连接池内单个连接所拥有的最大缓存statements数 -->
    <property name="maxStatementsPerConnection">5</property>
    </named-config>
    </c3p0-config>
    */

    /*

    3).使用连接池:
    1).创建连接池对象:
    ComboPooledDataSource dataSource = new ComboPooledDataSource();//寻找配置文件中的默认配置
    或者
    ComboPooledDataSource dataSource = new ComboPooledDataSource("baidu");//寻找配置文件中的命名配置
    2).获取连接对象:
    Connection conn = dataSource.getConnection();
    3).发送SQL语句:
    ....
    conn.close();//不是关闭,是回收
    大家要掌握:
    1.jar包位置,添加构建路径;
    2.c3p0-config.xml文件的位置,内部的必须项的四项的修改:driverClass、jdbcUrl、user、password
    3.ComboPooledDataSource的创建的两种方式;
    4.以及后面要讲的DBUtils工具类;

    //C3P0连接池的使用
    public class Demo {
    public static void main(String[] args) throws Exception {
    //1.创建C3P0的连接池对象
    // ComboPooledDataSource dataSource = new ComboPooledDataSource();//寻找配置文件中的默认配置
    ComboPooledDataSource dataSource = new ComboPooledDataSource("baidu");//寻找配置文件中的命名配置
    //2.获取连接对象
    Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from products");
    while(rs.next()){
    System.out.println(rs.getInt("pid") + " " + rs.getString("pname"));
    }
    rs.close();
    stmt.close();
    conn.close();
    }
    }

    ------------------------------------------------------------------------------------------------------------
    04.DBUtils工具包_什么是DBUtils:
    1.DBUtils工具包:它是数据库相关操作的工具包,内部封装了一些对数据库操作的一些相关方法,以及自动封装结果集的相关方法。
    使用它可以简化我们的数据库开发的代码。
    它是Apache的项目,免费开源的。

    05.DBUtils工具包_自己使用JavaBean封装结果集:

    JavaBean就是一个类,在开发中常用于封装数据。具有如下特性
    1.需要实现接口:java.io.Serializable ,通常偷懒省略了。
    2.提供私有字段:private 类型 字段名;
    3.提供getter/setter方法:
    4.提供无参构造

    ......
    //遍历结果集
    while(rs.next()){//遍历,封装的过程比较繁琐,DBUtils工具包就可以很方便的封装JavaBean
    Products pro = new Products();
    pro.setPid(rs.getInt("pid"));
    pro.setPname(rs.getString("pname"));
    pro.setPrice(rs.getInt("price"));
    pro.setFlag(rs.getInt("flag"));
    pro.setCategory_id(rs.getInt("category_id"));

    //将对象添加到集合中
    proList.add(pro);
    }
    .....

    //使用JavaBean封装结果集
    public class Demo {
    public static void main(String[] args) throws Exception {
    //1.创建一个C3P0连接池对象
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    //2.获取连接对象
    Connection conn = dataSource.getConnection();

    //3.执行查询
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from products");
    //定义集合
    List<Products> proList = new ArrayList<>();
    //遍历结果集
    while(rs.next()){
    Products pro = new Products();
    pro.setPid(rs.getInt("pid"));
    pro.setPname(rs.getString("pname"));
    pro.setPrice(rs.getInt("price"));
    pro.setFlag(rs.getInt("flag"));
    pro.setCategory_id(rs.getInt("category_id"));

    //将对象添加到集合中
    proList.add(pro);
    }
    //释放资源
    rs.close();
    stmt.close();
    conn.close();

    //遍历集合
    for(Products p : proList){
    System.out.println(p);
    }

    }
    }


    06.DBUtils工具包_DBUtils核心类
    1).QueryRunner类:主要用于执行SQL语句;
    2).ResultSetHandler接口 :有很多的子类,每种子类都表示一种封装结果集的方式。
    3).DBUtils工具类:提供了一些跟事务处理相关的方法。
    注意:DBUtils工具包,它内部不提供数据库的连接。它只负责发送SQL语句,执行SQL语句,封装结果集。
    我们可以提供"连接池"对象,给QueryRunner使用。
    07.DBUtils工具包_基本使用:
    1).复制jar包到项目目录下;
    commons-dbutils-1.4.jar
    2).由于它需要C3P0连接池,所以要将这个连接池配置好。
    3).使用QueryRunner执行SQL语句:
    //1.添加
    public void save() throws Exception{
    //1.创建一个QueryRunner对象--使用连接池创建
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--添加
    String sql = "insert into products values(?,?,?,?,?)";
    int row = qr.update(sql, 12,"索尼电视",8000,1,1);
    System.out.println("添加影响的行数:" + row);
    }

    //2.修改
    public void update() throws Exception{
    //1.创建QueryRunner对象
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--修改
    String sql = "update products set pname = ?,price = ?,flag = ?,category_id = ? where pid = ?";
    int row = qr.update(sql,"索尼电视2",8002,0,3,12);
    System.out.println("修改影响的行数:" + row);
    }
    //3.删除
    @Test
    public void delete() throws Exception{
    //1.创建QueryRunner对象
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--删除
    String sql = "delete from products where pid = ?";
    int row = qr.update(sql,12);
    System.out.println("删除影响的行数:" + row);
    }
    08.DBUtils工具包_ResultSetHandler标记各种结果集【重点掌握】:
    1).Object[] ArrayHandler : 用于查询一条记录,如果有多条,将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
    如果没有查询结果,返回的是:空数组(0长度数组),不是空指针
    String sql = "select * from products where category_id = 20";
    Object[] objArray = qr.query(sql, new ArrayHandler());
    for(Object o : objArray){
    System.out.println(o);
    }
    2).List<Object[]> ArrayListHandler:用于查询多条记录。将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
    String sql = "select * from products";
    List<Object[]> objList = qr.query(sql, new ArrayListHandler());
    for(Object[] objArray : objList){//遍历行
    for(Object o : objArray){//遍历列
    System.out.print(o + " ");
    }
    System.out.println();
    }
    3).某个JavaBean BeanHandler:用于查询一条记录,将结果集中第一条记录封装到一个指定的javaBean中。
    String sql = "select * from products where pid = 1";
    Products pro = qr.query(sql, new BeanHandler<Products>(Products.class));
    System.out.println(pro);
    4).List<某个JavaBean> BeanListHandler:用于查询多条记录 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
    String sql = "select * from products";
    List<Products> proList = qr.query(sql, new BeanListHandler<Products>(Products.class));
    for(Products p : proList){
    System.out.println(p);
    }
    5).List<Object> ColumnListHandler:查询某个列的数据,将结果集中指定的列的字段值,封装到一个List集合中
    String sql = "select pname from products";
    List<Object> objList = qr.query(sql, new ColumnListHandler());
    for(Object o : objList){
    System.out.println(o);
    }
    6).Map<Object,Map<String,Object>> KeyedHandler:查询多条记录。将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。
    String sql = "select * from products";
    Map<Object, Map<String, Object>> map = qr.query(sql, new KeyedHandler());
    Set<Object> keys = map.keySet();
    for(Object k : keys){
    System.out.println(k);
    Map<String,Object> map2 = map.get(k);
    Set<String> keys2 = map2.keySet();
    for(String k2 : keys2){
    System.out.println(" " + k2 + " -- " + map2.get(k2));
    }
    }
    7).Map<String,Object> MapHandler:用于查询一条记录。将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值
    String sql = "select * from products where pid = 1";
    Map<String, Object> map = qr.query(sql, new MapHandler());
    Set<String> keys = map.keySet();
    for(String k : keys){
    System.out.println("键:" + k + " 值:" + map.get(k));
    }
    8).List<Map<String,Object> MapListHandler:用于查询多条记录。将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。
    String sql = "select * from products";
    List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
    for(Map<String,Object> map : mapList){
    Set<String> keys = map.keySet();
    for(String k : keys){
    System.out.println("键:" + k + " 值:" + map.get(k));
    }
    System.out.println("--------------------------------");
    }
    9).Object ScalarHandler:它是用于单个数据。例如select count(*) from 表操作。
    String sql = "select sum(price) from products";
    Object result = qr.query(sql, new ScalarHandler());
    System.out.println("结果:" + result);

    //DBUtils的基本使用
    public class Demo {
    //1.添加
    public void save() throws Exception{
    //1.创建一个QueryRunner对象--使用连接池创建
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--添加
    String sql = "insert into products values(?,?,?,?,?)";
    int row = qr.update(sql, 12,"索尼电视",8000,1,1);
    System.out.println("添加影响的行数:" + row);
    }

    //2.修改
    public void update() throws Exception{
    //1.创建QueryRunner对象
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--修改
    String sql = "update products set pname = ?,price = ?,flag = ?,category_id = ? where pid = ?";
    int row = qr.update(sql,"索尼电视2",8002,0,3,12);
    System.out.println("修改影响的行数:" + row);
    }
    //3.删除
    public void delete() throws Exception{
    //1.创建QueryRunner对象
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--删除
    String sql = "delete from products where pid = ?";
    int row = qr.update(sql,12);
    System.out.println("删除影响的行数:" + row);
    }

    //4.查询
    @Test
    public void select() throws Exception{
    //1.创建QueryRunner对象
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--查询
    //1).ArrayHandler:将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
    /*String sql = "select * from products where category_id = 20";
    Object[] objArray = qr.query(sql, new ArrayHandler());
    for(Object o : objArray){
    System.out.println(o);
    }*/

    //2).List<Object[]> ArrayListHandler:用于查询多条记录。将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
    /*String sql = "select * from products";
    List<Object[]> objList = qr.query(sql, new ArrayListHandler());
    for(Object[] objArray : objList){//遍历行
    for(Object o : objArray){//遍历列
    System.out.print(o + " ");
    }
    System.out.println();
    }
    */
    //3).BeanHandler:将结果集中第一条记录封装到一个指定的javaBean中。
    /*String sql = "select * from products where pid = 1";
    Products pro = qr.query(sql, new BeanHandler<Products>(Products.class));
    System.out.println(pro);*/
    //4).BeanListHandler:将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
    /*String sql = "select * from products";
    List<Products> proList = qr.query(sql, new BeanListHandler<Products>(Products.class));
    for(Products p : proList){
    System.out.println(p);
    }*/

    //5).ColumnListHandler:查询某个列的数据,将结果集中指定的列的字段值,封装到一个List集合中
    /*String sql = "select pname from products";
    List<Object> objList = qr.query(sql, new ColumnListHandler());
    for(Object o : objList){
    System.out.println(o);
    }
    */
    //6).KeyedHandler:将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。
    /*String sql = "select * from products";
    Map<Object, Map<String, Object>> map = qr.query(sql, new KeyedHandler());
    Set<Object> keys = map.keySet();
    for(Object k : keys){
    System.out.println(k);
    Map<String,Object> map2 = map.get(k);
    Set<String> keys2 = map2.keySet();
    for(String k2 : keys2){
    System.out.println(" " + k2 + " -- " + map2.get(k2));
    }
    }*/

    //7).MapHandler 将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值
    /*String sql = "select * from products where pid = 1";
    Map<String, Object> map = qr.query(sql, new MapHandler());
    Set<String> keys = map.keySet();
    for(String k : keys){
    System.out.println("键:" + k + " 值:" + map.get(k));
    }*/

    //8).MapListHandler 将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。
    /*String sql = "select * from products";
    List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
    for(Map<String,Object> map : mapList){
    Set<String> keys = map.keySet();
    for(String k : keys){
    System.out.println("键:" + k + " 值:" + map.get(k));
    }
    System.out.println("--------------------------------");
    }
    */
    //9).ScalarHandler 它是用于单个数据。例如select count(*) from 表操作。
    String sql = "select sum(price) from products";
    Object result = qr.query(sql, new ScalarHandler());
    System.out.println("结果:" + result);
    }
    }

    09.DBUtils工具包_QueryRunner的CRUD方法:
    见demo05

    //自定义工具类实现CRUD;
    public class JDBCUtils {
    private static ComboPooledDataSource dataSource = new ComboPooledDataSource();

    public static DataSource getDataSource(){
    return dataSource;
    }
    }

    //自定义工具类实现CRUD (每个都有两种方法)
    public class Demo4 {

    //1.添加
    @Test
    public void save() throws Exception {
    //1.创建一个 QueryRunner对象--使用连接池创建
    //核心类
    //QueryRunner qr = new QueryRunner(new ComboPooledDataSource());

    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--添加
    //String sql = "insert into car values(?,?,?,?,?)";
    String sql = "insert into car (id,cname) values (?,?)";
    //3.参数
    Object[] params = {14,"捷达"};
    //int update = qr.update(sql,11,"朗逸","大众","德国",14);
    int update = qr.update(sql,params);
    System.out.println("添加影响的行数:" + update);
    }

    //2.修改
    @Test
    public void update() throws Exception {
    //1.创建QueryRunner对象
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    //2.执行SQL语句--修改
    String sql = "update car set cname = ?,company = ?,grade = ?,price = ? where id = ?";
    //3.参数
    Object[] params = {"索纳塔","大众","德国",10,14};
    int update = qr.update(sql, params);
    //int update = qr.update(sql,"宝来","大众","德国",13,11);
    System.out.println("修改影响的行数:" + update);
    }

    //3.删除
    @Test
    public void delete() throws Exception {
    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    //2.sql
    String sql = "delete from car where id = ?";
    //3.参数
    Object[] parms = {10};
    int update = qr.update(sql,parms);
    //int update = qr.update(sql,14);
    System.out.println("删除影响的行数:" + update);
    }

    //4.通过ID查询
    @Test
    public void findById() throws Exception {
    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "select * from car where id = ?";
    //3.参数
    Object[] parms = {8};
    Products update = qr.query(sql, new BeanHandler<Products>(Products.class),parms);
    //Products query = qr.query(sql, new BeanHandler<Products>(Products.class),9);
    System.out.println(update);
    }
    //5.查询所有
    @Test
    public void findAll() throws Exception {
    /*QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "select * from car";
    List<Products> query = qr.query(sql, new BeanListHandler<Products>(Products.class));
    for (Products products : query) {
    System.out.println(products);
    }*/
    QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "select * from car";
    Object[] parms = {};
    List<Products> query = qr.query(sql, new BeanListHandler<Products>(Products.class),parms);
    for (Products products : query) {
    System.out.println(products);
    }
    }

    //6.查询总记录
    @Test
    public void count() throws Exception {
    /*QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "select avg(price) from car";
    Object query = qr.query(sql, new ScalarHandler());
    System.out.println(query);*/
    QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
    String sql = "select count(*) from car";
    Object[] parms = {};
    Object query = qr.query(sql, new ScalarHandler(),parms);
    System.out.println(query);
    }


    }


    10.通过ResultSet获取列头信息:
    ResultSet rs = stmt.executeQuery("select * from products");
    ResultSetMetaData metaData = rs.getMetaData();//获取列的信息对象
    int count = metaData.getColumnCount();//获取列的数量
    System.out.println("列数:" + count);
    for(int i = 1 ; i <= count ; i++){
    System.out.println("列名:" + metaData.getColumnName(i));//获取指定索引的列名。索引值从1开始
    }

    //通过ResultSet获取列头信息
    public class Demo {
    public static void main(String[] args) throws Exception {
    Connection conn = JDBCUtils.getDataSource().getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from products");
    ResultSetMetaData metaData = rs.getMetaData();
    int count = metaData.getColumnCount();
    System.out.println("列数:" + count);
    for(int i = 1 ; i <= count ; i++){
    System.out.println("列名:" + metaData.getColumnName(i));
    }
    }
    }


    =============================================================================================================
    学习目标总结:
    目标:能够理解连接池的原理
    1.连接池就是一个存储了一些Connection对象的容器。可以先期缓存一些Connection对象,当用户使用时取出,当用户使用完毕时回收。
    可以对这些Connection对象进行反复的重用,达到提高程序运行效率的目的。

    目标:能够使用DBCP连接池
    1.复制2个jar包;
    2.复制配置文件到src目录下。



    3.创建连接池:
    1).读取配置文件:
    Properties pro = new Properties();
    pro.load(当前类名.class.getClassLoader().getResourceAsStream("配置文件名"));
    2).通过工厂类获取连接池对象
    BasicDataSource dataSource = (BasicDataSource)BasicDataSourceFactory.createDataSource(pro);
    3).获取Connection对象
    Connection conn = dataSource.getConncetion();
    ...
    conn.close();//不是关闭,是回收
    目标:能够使用C3P0连接池
    1.复制2个jar包;
    2.复制配置文件c3p0-config.xml到src目录下;
    3.创建连接池对象:
    1).创建连接池对象
    ComboPooledDataSource dataSource = new ComboPooledDataSource();//读取默认配置
    //或者
    ComboPooledDataSource dataSource = new ComboPooledDataSource("baidu");//读取命名配置
    2).获取连接:
    Connection conn = dataSource.getConnection();
    ...
    conn.close();//不是关闭,是回收
    目标:能够理解DBUtils工具类
    1.对JDBC进行了封装,用于执行增删改查等SQL语句(主要用于查询--可以自动封装结果集)
    目标:能够应用QueryRunner类
    1.创建对象:
    QueryRunner qr = new QueryRunner(连接池对象);

    2.发送SQL语句:
    1).public int update(String sql,Object ... params):用于执行添加、修改、删除语句的。
    2).public T query(String sql,ResultSetHandler<T> rsh,Object ... params):用于执行查询语句的。
    目标:能够应用ResultSetHandler接口
    1.Object[] ArrayHandler:用于查询一条记录;封装第一条记录
    2.List<Object[]> ArrayListHandler:用于查询多条记录的。
    3.某个Bean类型 BeanHandler : 查询一条,并自动封装JavaBean。
    4.List<Bean类型> BeanListHandler:查询多条。
    5.List<Object> ColumnListHandler : 查询某列的数据。
    6.Map<Object , Map<String,Object>> KeyedHandler : 查询多条记录。
    7.Map<String,Object> MapHandler : 查询一条记录;
    8.List<Map<String,Object>> MapListHandler :查询多条记录
    9.Object ScalarHandler : 查询聚合结果。单个数据

    //DBCPUtiles工具类:

    public class Utils_DBCP {
    private static DataSource ds;
    static{
    Properties p = new Properties();
    try{
    p.load(Utils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));
    ds = BasicDataSourceFactory.createDataSource(p);
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    public static Connection getConnection(){
    try{
    return ds.getConnection();
    }catch(SQLException e){
    throw new RuntimeException("创建连接连接失败!");
    }
    }
    }

    dbcpconfig.properties文件内容:
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/test
    password=root
    username=root
    上面的配置文件中的内容编写的依据是什么?源代码!!!!

    测试代码:
    package DBCPUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import org.junit.Test;
    public class Test001 {
    @Test
    public void demo01(){
    //添加:向分类表中添加数据
    Connection conn = null;
    PreparedStatement psmt = null;
    ResultSet rs = null;
    try {
    //1 获得连接
    conn = Utils_DBCP.getConnection();
    //2 处理sql语句
    String sql = "insert into category(cid,cname) values(?,?)";
    //3获得预处理对象
    psmt = conn.prepareStatement(sql);
    //4设置实际参数
    psmt.setString(1,"c009");
    psmt.setString(2,"预处理12");
    //5执行
    int r = psmt.executeUpdate();
    System.out.println(r);
    } catch (Exception e) {
    throw new RuntimeException(e);
    } finally{
    //6释放资源
    //JdbcUtils.closeResource(conn, psmt, rs);
    }
    }
    }

    //示例代码
    @Test
    public void method(){
    try {
    //获取QueryRunner对象
    QueryRunner qr = new QueryRunner();
    //执行SQL语句
    String sql = "SELECT * FROM zhangwu";
    Object[] params = {};
    Connection conn = JDBCUtils.getConnection();
    Object[] objArray = qr.query(conn, sql, new ArrayHandler(), params);
    //结果集的处理
    System.out.println( Arrays.toString(objArray) );

    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }

    示例代码:
    @Test
    public void method(){
    try {
    //获取QueryRunner对象
    QueryRunner qr = new QueryRunner();
    //执行SQL语句
    String sql = "SELECT * FROM zhangwu WHERE money>?";
    Object[] params = {2000};
    Connection conn = JDBCUtils.getConnection();
    List<Object[]> list = qr.query(conn, sql, new ArrayListHandler(), params);
    //结果集的处理
    for (Object[] objArray : list) {
    System.out.println( Arrays.toString(objArray) );
    }

    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }

    ColumnListHandler什么意思?怎么使用?必须保留一份操作代码!
    示例代码:

    @Test
    public void method(){
    try {
    //获取QueryRunner对象
    QueryRunner qr = new QueryRunner();
    //执行SQL语句
    String sql = "SELECT name FROM zhangwu WHERE money>?";
    Object[] params = {2000};
    Connection conn = JDBCUtils.getConnection();
    List<String> list = qr.query(conn, sql, new ColumnListHandler<String>(), params);
    //结果集的处理
    for (String str : list) {
    System.out.println(str);
    }

    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }

  • 相关阅读:
    python3给socket模块设置代理
    yield、greenlet与协程gevent
    线程池
    并发通信、生产者与消费者模型
    多进程和多线程
    非阻塞套接字与IO多路复用
    14.python模块之subprocess
    判断页面是否滑到底部
    @vue/cli 3.x 版本配置productionGzip提高性能
    vue跳转到指定位置
  • 原文地址:https://www.cnblogs.com/haizai/p/11260048.html
Copyright © 2011-2022 走看看