上两周学习回顾

小结

上两周主要围绕快速构造100万数据库测试数据的方法学习了jdbc相关技术,和通过反射技术实现copy对象,下面总结下编程思路

一、jdbc相关~

  • 1、获取连接
  • 2、插入单条数据
  • 3、循环100万次

主要用到以下类

  • java.sql.Connection
  • java.sql.DriverManager
  • java.sql.PreparedStatement
  • java.sql.SQLException
  • java.util.UUID

由于多次插入数据需多次建立与数据库连接,数据库会扛不住,后续学习了连接池技术以c3p0连接池技术为例进行了实践

用到的包:

   <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>

封装的连接池对象

public class JDBCUtils {

    //获得c3p0连接池对象
    private static ComboPooledDataSource ds = new ComboPooledDataSource();

    /**
     * 获得数据库连接对象
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 获得c3p0对象
     * @return
     */
    public static DataSource getDataSource(){
        return ds;
    }

    public static void closeDB(Connection conn, PreparedStatement ps, ResultSet rs){

            try {
                if (rs!=null){
                    rs.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (ps!=null){
                        ps.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    if (conn!=null){
                        try {
                            conn.close();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
    }

    public static void closeDB(PreparedStatement ps,Connection conn){
        if (ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                if (conn!=null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("----------"+JDBCUtils.getDataSource());
    }
}

对数据库连接使用了连接池技术进行优化后续学习了线程池技术进行了进一步优化,分别学习了几种常用的线程池技术

  • 1、newCachedThreadPool
  • 2、newFixedThreadPool
  • 3、newSingleThreadExecutor
  • 4、newScheduleThreadPool

以下代码简单展示了几种常用线程池技术的用法:

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        /**
         * 常用的几种线程池
         * 1、newCachedThreadPool
         * 2、newFixedThreadPool
         * 3、newSingleThreadExecutor
         * 4、newScheduleThreadPool
         */

        //线程池池子大小 最大 65536,适合短任务
//        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

        //固定大小
//        ExecutorService cachedThreadPool = Executors.newFixedThreadPool(3);

        //单个  先进先出队列(保证顺序)
        ExecutorService cachedThreadPool = Executors.newSingleThreadExecutor();
        for (int i=0;i<10;i++){
            final int index = i;
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"  "+index);
                }
            });
        }
        cachedThreadPool.shutdown();


        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.schedule(new Runnable() {
            public void run() {
                System.out.println("1111111");
            }
        },1, TimeUnit.HOURS);
    }
}

优化后最终代码

public class AddDataToDB {
    private static Connection getConn(){
        String driver = "com.mysql.jdbc.Driver";//加载驱动到系统环境
        String url = "jdbc:mysql://118.24.13.38:3306/Interface_wj?useSSL=false";
        String username = "xxxx";
        String password = "xxxx";
        Connection conn = null;
        try {
            Class.forName(driver); //加载驱动到系统环境
            conn = (Connection) DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;

//        try {
//            return JDBCUtils.getConnection();
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//        return null;
    }

    public static int insert(String userid,String username,String password) {
        Connection conn = getConn();
        int i = 0;
        String sql = "insert into t_user (userid,username,password) values(?,?,?)";
        PreparedStatement pstmt;
        try {
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1, userid);
            pstmt.setString(2, username);
            pstmt.setString(3, password);
            i = pstmt.executeUpdate();
            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }

    public static int deleteDB(){
        Connection conn = getConn();
        int i=0;
        String sql = "DELETE from t_user;";
        PreparedStatement pstmt;
        try {
            pstmt = conn.prepareStatement(sql);
            i=pstmt.executeUpdate();
            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return i;
    }
/*  数据库线程结合
    瓶颈:每次插入数据时都会不停的创建和数据库的链接,数据库会扛不住----->连接池优化
    */
    static class DBThread extends Thread{
        int begin;
        int end;

        public DBThread(int begin, int end) {
            this.begin = begin;
            this.end = end;
        }

        @Override
        public void run() {
            for (int i = 0;i<begin;i++){
                System.out.println(Thread.currentThread().getName()+"  "+i);
                AddDataToDB.insert(UUID.randomUUID().toString(),"testname"+i+"","test"+i);
            }

        }
    }

    public static void main(String[] args) {
//        int reulst = AddDataToDB.insert("123","test111","test111");

        deleteDB();
        int allcount = 10000;
        int pagesize = 1001;
        int allpage = allcount%pagesize==0?allcount/pagesize:(allcount/pagesize+1);
        System.out.println(allpage);

        ExecutorService cachedThreadPool = Executors.newFixedThreadPool(10);

        for (int i = 0;i<allpage;i++){
            int begin = i*pagesize;
            int end = (i+1)*pagesize;
            if(end>allcount){
                end=allcount;
            }
            System.out.println("begin  "+begin+"  end  "+end);
//            new DBThread(begin,end).start();
            cachedThreadPool.execute(new DBThread(begin,end));
        }
        cachedThreadPool.shutdown();
//        for(int i=0;i<100000;i++){
//            String uid =UUID.randomUUID().toString();
//            int reulst = AddDataToDB.insert(uid,"testname"+i+"","test"+i);
//            System.out.println("reulst " + i);
//        }
    }
}

二、反射技术

用到的包

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>

主要用到的类

java.lang.reflect.Field;
java.lang.reflect.InvocationTargetException;
java.lang.reflect.Method;

基础入门

public class TestClass {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {

        Class clazz = Class.forName("reflect.Person");
        //拿到class后,变为对象
        Object object = clazz.newInstance();
        System.out.println(object);

        Person object2 = (Person) Class.forName("reflect.Person").newInstance();
        System.out.println(" 对象判断 "+(object instanceof Person));

        //获取反射类的属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field f:fields){
            System.out.println(f);
        }

        //获取反射类的方法
        Method[] methods = clazz.getMethods();
        for (Method method:methods){
            System.out.println(method);
        }

        //通过反射类的属性,动态给对象复制
        Field field = clazz.getDeclaredField("age");
        field.setAccessible(true);
        field.set(object,20);
        System.out.println(object);

        //通过反射类的方法,动态给对象复制
        Method method = clazz.getMethod("setName", String.class);
        method.invoke(object,"zhangsan");
        System.out.println(object);

    }
}

通过基础入门了解基本原理后,新建构造person对象,实践通过反射技术进行对象copy
Person.java

public class Person {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat(){
        System.out.println("大米");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person);

        System.out.println(new Person("zhangsan",22));
        System.out.println(new Person("zhangsan2",25));
    }
    
}

通过反射copy对象
TestCopy.java

public class TestCopy {
    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, InstantiationException {
        Person person1 = new Person("zhangsan",20);
        Person person2 = new Person();
        //        copy(person1,person2);

        BeanUtils.copyProperties(person2,person1);
        System.out.println(person2);

        BeanUtils.setProperty(person2,"name","111");
        System.out.println(person2);

        MethodUtils.invokeMethod(person2,"setName","hahah");
        System.out.println(person2);

        person1 = ConstructorUtils.invokeConstructor(reflect.Person.class, new Object[]{"zhangsantest",20});
        System.out.println(person1);

        Map<String,Object>map = new HashMap<String, Object>();
        map.put("name","test1");
        map.put("age","30");
        BeanUtils.copyProperties(person2,map);

        System.out.println(person1);
        System.out.println(person2);
    }

    public static void copy(Object from,Object to) throws IllegalAccessException, NoSuchFieldException {
        Class clz1 = from.getClass();
        Class clz2 = to.getClass();
        clz1.getDeclaredFields();
        Field[] clzfs = clz1.getDeclaredFields();
        for (Field field:clzfs){
            String name = field.getName();
            field.setAccessible(true);
            Object fvalue = field.get(from);
            //赋值
            Field field2 = clz2.getDeclaredField(field.getName());
            field2.setAccessible(true);
            field.set(to,fvalue);
        }
    }
}

代码地址:https://github.com/HopeWing1286/MyMavenTest.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值