• 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);
                }
    
            }
  • 相关阅读:
    建立一个简单的通讯录
    建立一个图书管理系统(oc)
    OC 学习第六天(敲代码时遇到的一些错误)
    Serv-U FTP Server 15.1.2学习笔记
    Myeclipse&Tomcat中遇到的部分问题---其一
    MySQL存储过程和函数(三)
    MySQL存储过程和函数(二)
    MySQL存储过程和函数(一)
    mybatis拦截器分页
    Java--最大子序列和实现
  • 原文地址:https://www.cnblogs.com/sunhan/p/3542133.html
Copyright © 2020-2023  润新知