C3p0/元数据/内省-Bean/自定义查询封装类/查询/分页

c3p0连接池(C3p0连接池,只有当用户获取连接时,才会包装Connection。)

第一步:导入c3p0
第二步:在classpath目录下,创建一个c3p0-config.xml
第三步:创建工厂类获取这个连接
package cn.itcast.utils;
import java.sql.Connection;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class DataSourceUtils {
    private static DataSource ds;
    static{
        ds = //默认的读取c3p0-config.xml中默认配置
                new ComboPooledDataSource();
    }
    public static DataSource getDatasSource(){
        return ds;
    }
    public static Connection getConn(){
        Connection con = null;
        try{
            con = ds.getConnection();//每一次从ds中获取一个新的连接
        }catch(Exception e){
            e.printStackTrace();
        }
        return con;
    }
}

ComboPooledDataSource有三个构造:

没有参数的.

接收一个boolean

默认的情况下,为true,即所有connection.autoCommit属性为true.

在一个c3p0-config.xml文件中中,可以配置多种连接。 除了默认连接,其他都叫命名的连接。通过<named-config name=”xxxx”/>

ds = new ComboPooledDataSource("db909");

元(神)数据分析

元数据,是指仅拥有Connection一个对象的情况下,分析得出数据库的所有信息。
DataBaseMetadate  - 说明数据库的信息。
ResultSetMetadate - 说明数据结果的类型信息的。核心。
如果要进行元数据分析,就必须要使用statement,preparedstatement.

1、用databasemetadate分析数据库的数据
package cn.mata;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import cn.utils.DataSourceUtils;

public class Mata {
    @Test
    public void dbm() throws Exception {
        Connection con=DataSourceUtils.getConn();
        DatabaseMetaData dm=con.getMetaData();
        ResultSet rs=dm.getCatalogs();
        while(rs.next()){
            String name=rs.getString("TABLE_CAT");
            System.err.println(name);
        }
        
        System.err.println("==========================");
        String dbName=dm.getDatabaseProductName();
        System.err.println(dbName);//....
        
        System.err.println("有多少表。。");
        ResultSet rs2=dm.getTables("contacts", "contacts", null, new String[]{"TABLE"});
        
        while(rs2.next()){
            String name=rs2.getString("TABLE_NAME");
            System.err.println(name);
        }
    }
}
2、用ResultSetMetadate分析结果集

此类是用来分析查询的结果集:分析有几个列,列名,列的类型是什么?

    @Test
    public void rsDataMata() throws Exception {
        Connection con = DataSourceUtils.getConn();

        Statement st = con.createStatement();
        st.execute("use sakila");

        String sql = "select * from actor";
        ResultSet rs = st.executeQuery(sql);

        ResultSetMetaData rsmd = rs.getMetaData();

        int cols = rsmd.getColumnCount();
        System.err.println(cols);

        List<String> colsName = new ArrayList<String>();
        for (int i = 0; i < cols; i++) {
            String colName = rsmd.getColumnName(i + 1);
            System.err.println(colName);
            colsName.add(colName);
        }

        // 获取数据
        while (rs.next()) {
            for (String col : colsName) {
                String val = rs.getString(col);
                System.err.println(val);
                
            }
            System.err.println("----");
        }
        con.close();

    }
3、将某个数据库的表全部导出到excel中.
第一步:如何用POI操作Excel

1:某个数数据库有多少表,表名是什么?
DataBaseMetadate.getMetadate().getTables(null,null,null,new String[]{Table})--excel的文件名称。
2:对每一个表进行select * 操作--每一个sheet的名称。
3:分析表结构,rs.getMetadate();ResultSetMedated
4:多个列,列名是什么--字段名就是sheet的第一行信息。
5:获取每一行的数据--放到sheet第一行以后。

package cn.excel;

import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.junit.Test;

import cn.utils.DataSourceUtils;

public class ExcelDemo {

    @Test
    public void createXls() throws Exception{
        //声明一个工作薄
        HSSFWorkbook wb = new HSSFWorkbook();
       //声明表
        HSSFSheet sheet = wb.createSheet("第一个表");
        //声明行
        HSSFRow row = sheet.createRow(7);
        //声明列
        HSSFCell cel = row.createCell(3);
        //写入数据
        cel.setCellValue("你也好");
        
        
        FileOutputStream fileOut = new FileOutputStream("d:/b.xls");
        wb.write(fileOut);
        fileOut.close();
    }
    @Test
    public void export() throws Exception {
        // 声明需要导出的数据库
        String dbName = "contacts";
        // 声明book
        HSSFWorkbook book = new HSSFWorkbook();
        // 获取Connection,获取db的元数据
        Connection con = DataSourceUtils.getConn();
        // 声明statemen
        Statement st = con.createStatement();
        // st.execute("use "+dbName);
        DatabaseMetaData dmd = con.getMetaData();
        // 获取数据库有多少表
        ResultSet rs = dmd.getTables(dbName, dbName, null,
                new String[] { "TABLE" });
        // 获取所有表名 - 就是一个sheet
        List<String> tables = new ArrayList<String>();
        while (rs.next()) {
            String tableName = rs.getString("TABLE_NAME");
            tables.add(tableName);
        }
        for (String tableName : tables) {
            HSSFSheet sheet = book.createSheet(tableName);
            // 声明sql
            String sql = "select * from " + dbName + "." + tableName;
            // 查询数据
            rs = st.executeQuery(sql);
            // 根据查询的结果,分析结果集的元数据
            ResultSetMetaData rsmd = rs.getMetaData();
            // 获取这个查询有多少行
            int cols = rsmd.getColumnCount();
            // 获取所有列名
            // 创建第一行
            HSSFRow row = sheet.createRow(0);
            for (int i = 0; i < cols; i++) {
                String colName = rsmd.getColumnName(i + 1);
                // 创建一个新的列
                HSSFCell cell = row.createCell(i);
                // 写入列名
                cell.setCellValue(colName);
            }
            // 遍历数据
            int index = 1;
            while (rs.next()) {
                row = sheet.createRow(index++);
                // 声明列
                for (int i = 0; i < cols; i++) {
                    String val = rs.getString(i + 1);
                    // 声明列
                    HSSFCell cel = row.createCell(i);
                    // 放数据
                    cel.setCellValue(val);
                }
            }
        }
        con.close();
        book.write(new FileOutputStream("d:/" + dbName + ".xls"));
    }

}
4.将查询的结果封装成List<Map>
package cn.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;
public class ListMap {
    DataSource ds;

    public ListMap() {
    }

    public ListMap(DataSource ds) {
        this.ds = ds;
    }

    public List<Map<String, Object>> queryList(String sql) {
        // 封装数据
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Connection con = null;
        try {
            con = ds.getConnection();
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(sql);
            // 分析数据集
            ResultSetMetaData rsmd = rs.getMetaData();
            // 获取列
            int cols = rsmd.getColumnCount();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 0; i < cols; i++) {
                    String colName = rsmd.getColumnName(i + 1);
                    Object val = rs.getObject(i + 1);
                    map.put(colName, val);
                }
                list.add(map);
            }
        } catch (Exception e) {
            throw new RuntimeException();
        } finally {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
}
用回调函数实现数据的动态封装

回调是指在执行时,具体的封装处理工用由第三方的类来实现。回调一般由两部分组成:
1:调用类 - QueryRunner。实例类
2:回调规范 – ResultSetHandler。一般是一个接口。
3:回调规范定义回调方法且这个方法由调用类调用。

1、以下是基本的回调:
package cn.callback;

public class callbackDemo {
    public static void main(String[] args) {
        Runner run  =new Runner();
        run.query("sql",new Runhandler(){
            @Override
            public void handler(){
                System.err.println("handler");
            }
        });
        System.err.println("over");
    }
}
/**
 * @author sunhan
 *定义调用类
 */
class Runner {
    public void query(String string, Runhandler runhandler) {
        runhandler.handler();
    }
}
/**
 * @author sunhan
 *定义调用规范
 */

interface Runhandler{
    void handler();
}
2、以下是小测试:

面试题:关于一个线程问题:如何输出aabb

package cn.demo;

public class ThreadDemo {

    public static void main(String[] args) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                System.err.print("aa");
            }
        }) {
            public void run() {
                System.err.print("bb");
            }
        }.start();
    }
}

面试题,如何不改变list 的情况下 得到如下输出:

aaaclass java.lang.String
999class java.lang.Integer

public void Test() {
        List<String> list = new ArrayList<String>();
        list.add("aaa");
         list.add(999);
        for (Object o : list) {
            System.err.println(o + "" + o.getClass());
        }
    }
@org.junit.Test
    public void Test() {
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        add(list, 99);
        for (Object o : list) {
            System.err.println(o + "" + o.getClass());
        }
    }

    public void add(List aa, Object oo) {
        aa.add(oo);
    }

    @org.junit.Test
    public void Test2() {
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        List list2 = list;
        list2.add(999);
        for (Object o : list) {
            System.err.println(o + "" + o.getClass());
        }
    }

    @org.junit.Test
    public void Test3() throws Exception {
        List<String> list = new ArrayList<String>();
        list.add("aaa");
        list.getClass().getMethod("add", Object.class).invoke(list, 999);
        for (Object o : list) {
            System.err.println(o + "" + o.getClass());
        }
    }
3、调回调可以返回数据
package cn.callback;

public class callbackDemo {
    public static void main(String[] args) {
        Runner run  =new Runner();
        run.query("sql",new Runhandler(){
            @Override
            public void handler(String str) {
                System.err.println("handler"+str);
            }
        
        });
        System.err.println("over");
    }
}

/**
 * @author sunhan 定义调用类
 */
class Runner {
    public void query(String sql, Runhandler runhandler) {
        runhandler.handler(sql);
    }
}

/**
 * @author sunhan 定义调用规范
 */

interface Runhandler {
    void handler(String str);
}
4、让回调可以返回任意的数据
package cn.callback;

public class callbackDemo {
    public static void main(String[] args) {
        Runner run = new Runner();
        run.query("sql", new Runhandler<String>() {

            @Override
            public String handler(String str) {
                System.err.println("haha"+str);
                return null;
            }

            
        });
        System.err.println("over");
    }
}

/**
 * @author sunhan 定义调用类
 */
class Runner {
    public <T> T query(String sql, Runhandler<T> runhandler) {
        return runhandler.handler(sql);

    }
}

/**
 * @author sunhan 定义调用规范
 */

interface Runhandler<T> {
    T handler(String str);
}

 

5、回调在QueryRunner中的应用

第一步:实现一个调用类:

/**
     * 有回调的查询
     */
    public <T> T query(String sql, MyHandler<T> mh) {
        T t = null;
        // 声明conn
        Connection con = null;
        try {
            con = ds.getConnection();
            // 执行查询
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(sql);
            // 让回调去执行数据封装
            t = mh.handler(rs);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return t;
    }

第二步:定义回调规范

package cn.utils;
import java.sql.ResultSet;
/**
 * 接收rs结果集
 * @author Administrator
 *
 * @param <T>
 */
public interface MyHandler<T> {
    T handler(ResultSet rs);
}

第三步:实现一个回调

package cn.utils;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

public class MyBeanListHandler<T> implements MyHandler<List<T>> {
    private Class<T> cls;

    public MyBeanListHandler(Class<T> cls) {
        this.cls = cls;
    }

    public List<T> handler(ResultSet rs) {
        List<T> list = new ArrayList<T>();
        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            int cols = rsmd.getColumnCount();
            while (rs.next()) {
                T t = cls.newInstance();
                // 获取列名
                for (int i = 0; i < cols; i++) {
                    String colName = rsmd.getColumnName(i + 1);
                    String methodName = "set"
                            + colName.substring(0, 1).toUpperCase()
                            + colName.substring(1).toLowerCase();
                    // 获取类型
                    String javaType = rsmd.getColumnClassName(i + 1);// ="java.lang.String";
                    try {
                        Method mm = cls.getMethod(methodName,
                                Class.forName(javaType));
                        Object val = rs.getObject(i + 1);
                        mm.invoke(t, val);
                    } catch (Exception e) {
                    }
                }
                list.add(t);
            }
        } catch (Exception e) {
        }
        return list;
    }
}

第四步:测试:

@Test
    public void myutils3(){
        QueryRunner run = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from users";
        List<User> cs = 
                run.query(sql,new MyBeanListHandler<User>(User.class));
        for(User c:cs){
            System.err.println(">>:"+c);
        }
    }
5、在dbutils中处理事务

事务是指用户的一次操作。这一次操作有可能是一个表,也有可能是多个表,也有可能是对一个表的多次操作。
只要是:
1:对数据数据库进行多次操作。
2:多个表,还是一个表的多次update,detelete,inset都应该开始一个事务。
如果仅做一次与数据库的操作。即只执行一个sql语句,则可以不用开事务。
如果仅做select 则没有必要开事务。事务是指用户的一次操作,这一次操作,只能有一个结果,要不然就全部成功,要不然就全部不成功。
如果需要在dbutils中管理事务。则用户必须自己传递并控制connection。

@Test
        public void tx1() throws Exception {
            QueryRunner run = new QueryRunner(DataSourceUtils.getDataSource());
            Connection con = DataSourceUtils.getConn();
            try {
                String sql = "insert into users values('U008','AA','AA')";
                // 设置事务的开始标记
                con.setAutoCommit(false);
                run.update(con, sql);
                String sql2 = "insert into users values('U009,'AA','AA')";
                run.update(con, sql2);
                // 提交
                con.commit();
            } catch (Exception e) {
                System.err.println("出错了");
                con.rollback();
            } finally {
                con.close();
            }
        }
6、不确定条件的查询
// 不确定条件的查询
        @Test
        public void query1() throws Exception {
            QueryRunner run = new QueryRunner(DataSourceUtils.getDataSource());
            Contact c = new Contact();
            // c.setId("C001");
            c.setName("王'");
            c.setSex("1");
            c.setTel("123");
            c.setAddr("中国");
            c.setAge(55);
            String sql = "select * from contacts where 1=1";
            List<Object> params = new ArrayList<Object>();
            if (c.getId() != null) {
                sql += " and id=?";
                params.add(c.getId());
            }
            if (c.getSex() != null) {
                sql = sql + " and sex=?";
                params.add(c.getSex());
            }
            if (c.getName() != null) {
                sql += " and name like ?";
                params.add("%" + c.getName() + "%");
            }
            if (c.getAddr() != null) {
                sql += " and addr like ?";
                params.add("%" + c.getAddr() + "%");
            }
            if (c.getTel() != null) {
                sql += " and tel like ?";
                params.add("%" + c.getTel() + "%");
            }
            if (c.getAge() != null) {
                sql += " and age=?";
                params.add(c.getAge());
            }
            System.err.println(">>>>>>:" + sql);
            System.err.println(params);
            List<Contact> cs = run.query(sql, new BeanListHandler<Contact>(
                    Contact.class), params.toArray());
            for (Contact cc : cs) {
                System.err.println(cc);
            }

        }

转载于:https://www.cnblogs.com/sunhan/p/3542133.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值