构建器&反射&JDBC

来源:互联网 发布:指标选股软件 编辑:程序博客网 时间:2024/05/03 15:57

构建者模式(多可选参数)&静态工厂&单例设计模式

一个营养产品类,该类含有两个必选参数和许多可选参数,代表了该营养产品的营养成分

package xiaobai;public class NutritionFacts{    private final int servingSize;    private final int servings;    private final int calories;    private final int fat;    private final int sodium;    private final int carbohydrate;    public static class Builder{// Builder内部类,用来创建返回对象        // Required parameters,必选参数        private final int servingSize;        private final int servings;        // Optional parameters - initialized to default values,可选参数        private int calories = 0;        private int fat = 0;        private int carbohydrate = 0;        private int sodium = 0;        public Builder(int servingSize,int servings){            this.servingSize = servingSize;            this.servings = servings;        }// 每个设置参数的方法返回this,构建器        public Builder calories(int val){            calories = val;            return this;        }        public Builder fat(int val){            fat = val;            return this;        }        public Builder carbohydrate(int val){            carbohydrate = val;            return this;        }        public Builder sodium(int val){            sodium = val;            return this;        }        public NutritionFacts build(){// 返回类的对象            return new NutritionFacts(this);        }    }// 内部类结束    private NutritionFacts(Builder builder){// 单例设计模式-构造器私有化,静态工厂返回对象        servingSize = builder.servingSize;        servings = builder.servings;        calories = builder.calories;        fat = builder.fat;        sodium = builder.sodium;         carbohydrate = builder.carbohydrate;    }}

创建对象时的代码:

package xiaobai;import xiaobai.NutritionFacts;public class Test {    public static void main(String[] args) {        NutritionFacts cocaCola = new NutritionFacts.Builder(240,8)                .carbohydrate(100).sodium(35).carbohydrate(27).build();    }}

使用构建者模式在遇到有多个可选参数的类时,可以极大的简化代码,同时可以在创建对象时使代码更加的清晰易懂。而单例设计模式私有化构造器,可以保证在一定情况下在所有的区域内只能存在一个该类的对象,本例中的对象不是唯一的。


数组和List的相互转换

  • 一维数组与一维集合的转换
// 一维数组 转 一维集合String[] strArr1 = {"one","two","three","four"};List<String> list = Arrays.asList(strArr);// 一维集合 转 一维数组String[] strArr2 = list.toArray(new String[]{});
  • 二维数组与二维集合的转换
// 二维数组 转 二维集合String[][] strArr2 = {    {"one","two","three","four"},    {"one","two","three","four"},    {"one","two","three","four"}};// 对象创建使用多态,但泛型必须一致,左右都为List<String>List<List<String>> list = new ArrayList<List<String>>();for(int i=0;i<strArr2.length;i++){    list.add(array2List(strArr2[i]));// 调用下面的方法}// 完成一维数组转一维集合的功能public static List<String> array2List(String[] strArr){    List<String> list = Arrays.asList(strArr);    return list;}

泛型

给一个类或方法一个动态的参数类型,这样可以加强我们代码的复用性,一个类可以应用在所有类的情况,同时在使用时不会产生由于类型不明导致的编译错误。

// 泛型类public class GenericClass<E> {    private E e;    public E getE(){        return e;    }    public void setE(E e){        this.e = e;    }    public static void main(String[] args) {        GenericClass<String> gc = new GenericClass<String>();        gc.setE("abc");        System.out.println(gc.getE());    }}// 泛型方法:修饰符和方法的返回值类型之间加泛型public class GenericClass{public <E> void swap(E e1,E e2){    System.out.println(e1 + ":" + e2);    E temp = e1;    e1 = e2;    e2 = temp;    System.out.println(e1 + ":" + e2);}public static void main(String[] args) {    GenericClass gc = new GenericClass();    gc.swap("one", "two");    gc.swap(1, 2);}}

枚举

一个类中只有固定的几个该类的对象,如一个季节类中只有春、夏、秋、冬四个对象。此时就可以用枚举代替类,使代码简单清晰。如果不使用枚举,就需要使用单例模式,私有化构造器,然后将本类的对象作为本类的静态属性。

// 交通信号灯类,只有红、绿、黄三个对象,就可以写为一个枚举。如果正常创建类public enum LightEnum{// 提供固定的几个本类对象作为该类的静态属性    public static final LightEnum RED = new LightEnum();    public static final LightEnum GREEN = new LightEnum();    public static final LightEnum YELLOW = new LightEnum();    private LightEnum(){// 私有化构造器        super();    }}

写为一个枚举如下:

public enum LightEnum {    RED,GREEN,YELLOW;// 三个本类的对象}// 测试类public class TestEnum {    public static void main(String[] args) {        LightEnum le1 = LightEnum.RED;        LightEnum le2 = LightEnum.GREEN;        LightEnum le3 = LightEnum.YELLOW;        System.out.println(le1);        LightEnum[] leArr = LightEnum.values();// 返回枚举的所有对象        System.out.println(Arrays.toString(leArr));    }}

反射

在Java中,万物皆对象。那么我们将所有的类视为一个特殊的类的对象,每新建一个类就是给这个特殊类新建了一个对象。或我们起一个别名叫初代,而我们通常使用的类全部都是初代的对象,这个初代在Java官方给出的就是类Class。像String,Math,Object等都是初代的一个对象。而通过初代的方法来反向获取一个类和这个类中的属性、方法的过程就叫做反射。

  • 获取Class对象的方法
// 1、包名.类名  数据库驱动加载  框架中(从xml配置文件中根据类名称获取类对象,执行类的方法)Class c1 = Class.forName("cn.ucai.day26.Person");// 2、多用于传参Class c2 = Person.class;// 3、通过类的对象的方法返回一个Class对象Person p = new Person();Class c3 = p.getClass();
  • 通过反射获取类的所有方法 并可以执行方法
private static void showMethods(Class c) throws Exception{    // 获得所有的方法(修饰符、返回值类型、方法名、参数、抛出的异常)    Method[] methodArr = c.getDeclaredMethods();    for(Method method : methodArr){            System.out.print(Modifier.toString(method.getModifiers())+" ");            System.out.print(method.getReturnType().getSimpleName()+" ");// 返回值类型            System.out.print(method.getName()+" ");            Class[] paArr = method.getParameterTypes();// 得到方法的参数类型            System.out.print(Arrays.toString(paArr)+" ");            Class[] excArr = method.getExceptionTypes();            System.out.println(Arrays.toString(excArr));        }        // 获得指定的方法  如何执行指定的方法        Method method = c.getDeclaredMethod("setName",new Class[]{String.class});        Person p = (Person) c.newInstance();// 调用Person的无参构造,创建Person对象        //method.setAccessible(true);使方法可见,打破了封装性        // 执行这个方法        method.invoke(p,"张三");// p.setName("张三");        Method methodGetName = c.getDeclaredMethod("getName");        String s = (String) methodGetName.invoke(p);// String s = p.getName();        System.out.println(s);// 张三    }
  • 通过反射获取类的所有字段 并可以给字段赋值
private static void showFields(Class c) throws Exception{    Field[] fieldArr = c.getDeclaredFields();    for(Field field : fieldArr){        System.out.print(Modifier.toString(field.getModifiers())+" ");        // java.lang.String ==> String        System.out.print(field.getType().getSimpleName()+" ");        System.out.println(field.getName());    }    // 获得指定的属性     Field field = c.getDeclaredField("name");    Person p = (Person) c.newInstance();// Person p = new Person();    field.setAccessible(true);    field.set(p, "张三");// p.setName("张三");    System.out.println(p);}
  • 通过反射获取类的所有构造方法 并执行构造方法创建对象
private static void showConstructors(Class c) throws Exception{    // 取得所有的构造方法    Constructor[] conArr = c.getDeclaredConstructors();    for(Constructor con:conArr){        // 取得构造方法的修饰符        int modi = con.getModifiers();        String strModi =Modifier.toString(modi);// 对应数字转为了public 、private 等        System.out.print(strModi+" ");        System.out.print(con.getName()+" ");        // 得到参数的类型        Class[] claArr = con.getParameterTypes();// String.class int.class Class对象        System.out.print(Arrays.toString(claArr)+" ");        // 得到异常的类型        Class[] excArr = con.getExceptionTypes();// Exception.class NullPointerException.class        System.out.println(Arrays.toString(excArr));    }    // 根据Class对象获得指定某个类的指定参数的构造方法并执行去创建对象    Constructor cons =             c.getDeclaredConstructor(new Class[]{String.class,int.class});    cons.setAccessible(true);// 破坏类的封装性    Object o = cons.newInstance("张三",20);// new Person("张三",20);    System.out.println(o.toString());}
  • 假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个 程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个 程序员所写的类的时候,来完成自身代码的编译。例如Tomcat中的代码就是采用了反射机制,我们在配置文件时采用了一下方式:
  <servlet>    <servlet-name>Hello</servlet-name>    <servlet-class>cn.ucai.servlet.HelloServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>Hello</servlet-name>    <url-pattern>/hello</url-pattern>  </servlet-mapping>// HelloServlet类中doGet方法被调用在Tomcat的代码中:Class c = Class.forName("cn.ucai.servlet.HelloServlet");HttpServlet hs = c.newInstance();hs.doGet();

MySQL数据库

cmd窗口对于数据库的几个简单操作指令:
show databases;–查看全部数据库
use 数据库名;–使用某指定数据库
select * from 表名;–查看某数据表中的全部数据

下面是我目前使用的MySql数据库的下载连接:
mysql-5.5.48
下面是安装教程:
mysql安装教程
mysql数据库实现了很强大的数据库功能,但是操作只能在cmd窗口用命令行操作,有时非常不易操作,下面是一个mysql界面化的软件下载,下载完成后直接快速安装就可以:
Navicat_Premium_11.0.10
最后是一个Navicat_Premium的破解工具:
PatchNavicat


JDBC(Java Database Connection)

  • 什么是JDBC:JDBC是我们代码与数据库相关联使用的语言

  • 使用代码完成数据的访问与操作
    1.加载驱动
    2.连接数据库
    3.得到操作数据库的类
    4.使用该类操作数据库
    5.得到查询结果集
    6.遍历结果集
    7.断开连接

  • 在Eclipse相应工程src文件夹下创建一个配置文件jdbc.properties

jdbcDriver=com.mysql.jdbc.DriverjdbcUrl=jdbc:mysql:/localhost:3306/xiaobai?user=root&password=root// xiaobai是要访问的数据库名,user、password是数据库的登录用户名和密码
  • 获得配置文件中的值
public class PropertiesUtil {    /**     * 通过指定的key,取得properties文件中指定的value值     * @param key     * @param proName 要访问的文件名     * @return     */    public static String getValue(String key, String proName){        String value = null;        Properties p = new Properties();        String path = PropertiesUtil.class.getResource("/").getPath();        try {            // 指定p所表示的properties            p.load(new FileInputStream(new File(path,proName)));            value = p.getProperty(key);        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return value;    }}
  • 创建一个工具类
/** * 数据库操作的工具类: * 1、完成数据库的连接 * 2、完成数据库的关闭 */public class DBUtils {    /**     * 完成数据库的连接     * @return 数据库连接Connection对象     */    public static Connection getConnection(){        Connection conn = null;        try {            Class.forName(PropertiesUtil.getValue("jdbcDriver", "jdbc.properties"));            conn = DriverManager                    .getConnection(PropertiesUtil.getValue("jdbcUrl", "jdbc.properties"));        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (SQLException e) {            e.printStackTrace();        }        return conn;    }    /**     * 关闭全部内容     * @param conn     * @param st     * @param rs     */    public static void closeAll(Connection conn,Statement st,ResultSet rs){        if (rs != null) {            try {                rs.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (st != null) {            try {                st.close();            } catch (SQLException e) {                e.printStackTrace();            }        }        if (conn != null) {            try {                conn.close();            } catch (SQLException e) {                e.printStackTrace();            }        }    }}
  • 访问数据库
public static List<Student> getAll() {        List<Student> list = new ArrayList<Student>();        Connection conn = null;        Statement st = null;        ResultSet rs = null;        try {            // 获取连接            conn = DBUtils.getConnection();            // 得到操作数据库的类的对象            st = conn.createStatement();            // 通过executeQuery,执行查询的sql语句,数据库中要存在该表            rs = st.executeQuery("select * from t_student");            // 遍历结果集            // rs.next();// 相当于Iterator中的hasNext()和next()            while (rs.next()) {                // 根据字段,取数据                int id = rs.getInt("sid");                String name = rs.getString("name");                int age = rs.getInt("age");                // 实体类,对应t_student数据表中的各列,一个对象代表数据库中一行数据                Student student = new Student(id, name, age);                list.add(student);            }        } catch (SQLException e) {            e.printStackTrace();        } finally {        // 关闭内容            DBUtils.closeAll(conn, st, rs);        }        return list;    }
0 0
原创粉丝点击