增强for循环、自动拆装箱、类型安全的枚举、静态导入、可变参数、泛型、注解。
-
- for循环
见集合之迭代器部分。
Integer类注意事项
Integer类有一个缓存,会缓存介于-128~127之间的整数。所以:
Integer in1 = new Integer(127); Integer in2 = new Integer(127); System.out.println(in1 == in2);//false Integer in3 = 127; Integer in4 = 127; System.out.println(in3 == in4);//true Integer in5 = 128; Integer in6 = 128; System.out.println(in5 == in6);//false |
可变参数使方法可接收可变数目的参数,语法是在参数类型后接三个点(...)。
可变参数最多只能定义一个,且必须是方法声明中的最后一个参数。
调用时可传入离散参数或参数数组,也可以不传参数(不要传null)。
public class Demo { public static void main(String[] args) { System.out.println(sum(1)); System.out.println(sum(new int[] { 1 })); System.out.println(sum(1, 2)); System.out.println(sum(new int[] { 1, 2 })); System.out.println(sum(1, 2, 3)); System.out.println(sum(new int[] { 1, 2, 3 })); } public static int sum(int... nums) { int sum = 0; for (int num : nums) { sum += num; } return sum; } } |
-
- Enum)
枚举常用于限定参数的选择范围,或者限定实例数量。
关键词enum的使用方法类似于class和interface。
所有枚举类型都继承自类 java.lang.Enum<E extends Enum<E>> 。
枚举中的每个例都在枚举中指定,默认都是常量(public static final)。枚举的实例数在编译期确定,运行期无法再创建实例。
enum Color { Red, Green, Yellow } public class ColorTest { public static void trafficLight(Color color) { switch (color) { case Red: System.out.println("红灯停!"); break; case Green: System.out.println("绿灯行!"); break; case Yellow: System.out.println("黄灯看着办!"); break; } } public static void enumCompareTo(Color color) { System.out.println(color); for (Color c : Color.values()) { System.out.println(color.compareTo(c));//比较枚举的位置,在目标枚举前为负,后为正,相同为0 } } public static void main(String[] args) { Color myColor = Color.Red; System.out.println(myColor); for (Color color : Color.values()) { System.out.println(color); System.out.printf("%d, %s, %n", color.ordinal(), color);//带序数输出 } trafficLight(Color.Yellow); enumCompareTo(Color.valueOf("Red")); } } |
带参数的枚举:若无无参构造方法,枚举值须提供构造参数
public enum Coin { penny("林肯"), nickel("杰斐逊"), dime("罗斯福"), quarter("华盛顿");//若无无参构造方法,枚举值须提供构造参数 private String value; public String getValue() { return value; } Coin(String value) { this.value = value; } public static void main(String[] args) { Coin coin = Coin.quarter; System.out.println(coin);//quarter System.out.println(coin.getValue());//华盛顿 Coin[] values = Coin.values();//获取所有枚举实例到枚举数组 for (Coin eachCoin : values) { System.out.println(eachCoin); } } } |
枚举应用:访问权限控制
enum AccessRight { MANAGER, DEPARTMENT, EMPLOYEE } public class AccessController { public static boolean checkRight(AccessRight accessRight) { switch (accessRight) { case MANAGER: return true; default: return false; } } public static void main(String[] args) { AccessRight valueOf = AccessRight.valueOf("MANAGER"); System.out.println(checkRight(valueOf)); } } |
EnumSet类用法示例
import java.util.ArrayList; import java.util.EnumSet; import java.util.List; enum FontConstant { Plain, Bold, Italic } public class EnumSetDemo { /** * 遍历枚举集 */ public static void showEnumSet(EnumSet<FontConstant> es) { for (FontConstant fc : es) { System.out.println(fc); } } public static void main(String[] args) { EnumSet<FontConstant> of = EnumSet.of(FontConstant.Plain, FontConstant.Bold);//创建包含指定枚举值的枚举集 showEnumSet(of); System.out.println("---------------"); showEnumSet(EnumSet.complementOf(of));//打印补集 System.out.println("---------------"); EnumSet<FontConstant> noneOf = EnumSet.noneOf(FontConstant.class);//创建空指定枚举类型的空枚举集 noneOf.add(FontConstant.Plain); noneOf.add(FontConstant.Bold); showEnumSet(noneOf); System.out.println("---------------"); List<FontConstant> list = new ArrayList<FontConstant>(); list.add(FontConstant.Plain); list.add(FontConstant.Bold); EnumSet<FontConstant> copyOf = EnumSet.copyOf(list);//创建一个从指定 collection 初始化的枚举 set。 showEnumSet(copyOf); } } |
EnumMap类用法示例
package com.tongwx.two; import java.util.EnumMap; import java.util.Map; enum Hobby { EAT, DRINK, FUCK, GAMBLE } public class EnumMapDemo { public static void main(String[] args) { Map<Hobby, String> map = new EnumMap<Hobby, String>(Hobby.class); map.put(Hobby.EAT, "美食"); map.put(Hobby.DRINK, "美酒"); map.put(Hobby.FUCK, "交友"); map.put(Hobby.GAMBLE, "竞技"); for (Hobby h : map.keySet()) { System.out.println(h + " : " + map.get(h)); } System.out.println("----------------"); for (Hobby h : Hobby.values()) { System.out.println(h + " : " + map.get(h)); } } } |
静态导入他包他类的静态成员变量和静态方法,然后直接用。(不宜多用,可读性差!)
package com.tongwx.one; //不同包 public class Static { public static String str = "静态成员变量"; public static void method() { System.out.println("静态方法"); } } | package com.tongwx.two; //导入不同包 import static com.tongwx.one.Static.method;//导入他包他类的静态成员变量 import static com.tongwx.one.Static.str;//导入他包他类的静态方法 public class StaticImport { public static void main(String[] args) { System.out.println(str);//使用静态导入的成员变量 method();//使用静态导入的方法 } } |
-
- (Generic)
在jdk5.0后出现了泛型:泛型就是将变量类型参数化。
例如:通过<>来指定容器中元素的类型。
集合类<类类型> 变量名 = new 集合类<类类型>();
注意点:
1. 声明好泛型类型之后,集合中只能存放特定类型元素。
2. 泛型类型必须是引用类型,基本类型须转成包装类。
3. 使用泛型后取出元素不需要类型转换。
泛型方法
函数上的泛型定义:当函数中使用了一个不明确的数据类型,那么在函数上就可以进行泛型的定义。
泛型的声明:在返回值类型前面声明。
泛型的定义;可定义参数类型、变量类型或返回值类型。
确定时机:泛型方法在调用方法时确定类型。
格式:
public <泛型的声明> 泛型定义返回值类型 函数名(泛型定义参数类型 变量名){}
例:public <T, J, K> T getData(T data, J j, K k) { return data;}
泛型类
当一个类中有多个函数声明了泛型,那么该泛型的声明可以声明在类上。
确定时机:泛型类在创建类对象时确定类型。
格式:
修饰符 class 类名<泛型>{}
注意:
1.静态方法不可以使用类中定义的泛型,因为类中的泛型需要在对象初始化时指定具体的类型,而静态优先于对象存在。如果静态函数需要使用泛型,就在该静态函数上独立声明,声明要写在static后,返回值类型之前。
2.创建对象时可以不指定泛型的具体类型,默认是Object,
3.可以同时在类上和该类的方法上声明泛型。
泛型继承
public class Demo { public static void main(String[] args) { Father<String> f1 = new Father<String>("jack"); System.out.println(f1.getT());//jack Father<Integer> f2 = new Father<Integer>(20); System.out.println(f2.getT());//20 } } class Father<T> { private T t; public Father() {} public Father(T t) {this.t = t;} public T getT() {return t;} public void setT(T t) {this.t = t;} } //子类指定具体的类型 class Son1 extends Father<String>{} //子类也使用泛型 class Son2<T> extends Father<T>{} //错误写法,父类上定义有泛型需要进行处理 // //子类增加泛型 class Son3<T, T2> extends Father<T>{增加T2的getter和setter,增加全参构造方法} |
泛型实现
public class Demo { public static void main(String[] args) { MyInter my = new MyInter(); my.print("只能传字符串"); MyInter2<String> my2 = new MyInter2<String>(); my.print("泛型"); } } interface Inter<T> { void print(T t); } //实现类指定具体的类型 class MyInter implements Inter<String> { public void print(String t) { System.out.println("myprint:" + t); } } // 实现类也使用泛型 class MyInter2<T> implements Inter<T> { public void print(T t) { System.out.println("myprint:" + t); } } |
泛型通配符:?
public class Demo9 { public static void main(String[] args) { //将集合的泛型设置为Object类型 ArrayList<Object> arr = new ArrayList<Object>(); arr.add(new Object()); arr.add("String"); print1(arr); print2(arr); //将集合的泛型设置为String类型,是Object子类 HashSet<String> hs = new HashSet<String>(); hs.add("hello"); hs.add("jack"); //print1方法只接受元素类型为Object的集合,编译不通过 // //print2使用泛型通配符,编译通过。 print2(hs); } //限定泛型类型 public static void print1(Collection<Object> coll) { Iterator<Object> it = coll.iterator(); while (it.hasNext()) { Object next = it.next(); System.out.println(next); } } //使用泛型通配符:? public static void print2(Collection<?> coll) { Iterator<?> it = coll.iterator(); while (it.hasNext()) { Object next = it.next(); System.out.println(next); } } } |
限定泛型范围
定义类时限定泛型范围:
public class Generic<T extends OtherClassOrInterface>
使用类时限定泛型范围:
public void show(List<? extends Number> list){}
? extends E: 接收E类型或者E的子类型/实现类型。(限定通配符的上边界)
? super E: 接收E类型或者E的父类型/接口类型。(限定通配符的下边界)
<?> 是 <? extends Object> 的简写
正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
/* * 在声明类时不限定泛型范围,在使用类时限定泛型范围 */ public class GenericTest<T> { private T foo; public T getFoo() { return foo; } public void setFoo(T foo) { this.foo = foo; } } | /* * 在声明类时限定泛型范围(限定ListGenericFoo类的泛型范围:T extends List) * 在使用类时限定泛型范围(限定List接口的泛型范围:? extends Number) */ public class ListGenericFoo<T extends List<? extends Number>> { private T[] fooArray; public T[] getFooArray() { return fooArray; } public void setFooArray(T[] fooArray) { this.fooArray = fooArray; } } |
public class Test { public static void main(String[] args) { /* * 在声明类时不限定泛型范围,在使用类时限定泛型范围 */ GenericTest<? extends List<? extends Number>> gt1 = new GenericTest<ArrayList<? extends Number>>(); GenericTest<? extends List<? super Integer>> gt2 = new GenericTest<LinkedList<? super Integer>>(); /* * 在声明类时限定泛型范围,在使用类时指定范围内的泛型 */ ListGenericFoo<ArrayList<Integer>> foo1 = new ListGenericFoo<ArrayList<Integer>>(); ListGenericFoo<LinkedList<Byte>> foo2 = new ListGenericFoo<LinkedList<Byte>>(); } } |
限定上界(UpperBound)和下界(LowerBound()的问题:PECS原则:
如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer-Extends)
如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer-Super)
如果既要存又要取,那么就不要使用任何通配符。
public void testUpperBound(List<? extends Number> list) { Number n = list.get(0); // OK Object o = list.get(0); // OK // 编译器不知道list是Number的哪个子类,因此阻止向集合中加入或修改任何子类、本类和超类(null除外) // 事实上,不能够往一个使用了? extends的数据结构里写入任何的值(只读,类似生产者,只提供数据)
list.add(null); // OK list.remove(0); // OK } |
public void testLowerBound(List<? super Number> list) { // 编译器不知道list是Number的哪个超类,因此读取元素时只能返回Object类(须强转成目标类型) Object o = list.get(0); // OK Number n = (Number) list.get(0); // 须强转成目标类型 // 编译器不知道list是Number的哪个超类,因此阻止向集合中加入或修改任何超类
list.add(new Integer(0)); // OK list.add(new Long(0)); // OK } |
泛型的泛型
package com.tongwx.one; public class WrapperFoo<T> { private GenericFoo<T> foo; public GenericFoo<T> getFoo() { return foo; } public void setFoo(GenericFoo<T> foo) { this.foo = foo; } public static void main(String[] args) { GenericFoo<Integer> foo = new GenericFoo<Integer>();//新建泛型 foo.setFoo(1);//将1存入泛型 WrapperFoo<Integer> wrapper = new WrapperFoo<Integer>();//新建泛型的泛型 wrapper.setFoo(foo);//将泛型存入泛型的泛型 GenericFoo<Integer> foo2 = wrapper.getFoo();//从泛型的泛型中取出泛型 Integer in = foo2.getFoo();//从泛型中取出1 System.out.println(in); } } class GenericFoo<T> { private T foo; public T getFoo() { return foo; } public void setFoo(T foo) { this.foo = foo; } } |
模拟ArrayList泛型
package com.tongwx.one; public class SimpleCollection<T> { private T[] objArr; private int index; public SimpleCollection() { objArr = (T[]) new Object[10]; } public SimpleCollection(int capacity) { objArr = (T[]) new Object[capacity]; } public void add(T t) { objArr[index++] = t; } public int getlLength() { return this.index; } public T get(int i) { return objArr[i]; } public static void main(String[] args) { SimpleCollection<Integer> sc = new SimpleCollection<Integer>(); for (int i = 0; i < 10; i++) { sc.add(i); } for (int i = 0; i < 10; i++) { System.out.println(sc.get(i)); } } } |
总结:
JDK5中的泛型允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定
注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
泛型的基本术语,以ArrayList<E>为例:<>读作typeof
ArrayList<E>中的E称为类型参数变量
ArrayList<Integer>中的Integer称为实际类型参数
整个称为ArrayList<E>泛型类型
整个ArrayList<Integer>称为参数化的类型(ParameterizedType)
-
- Annotation)
Marker annotation
常用内置注解
@Override 重写
@Deprecated 不建议使用
@SuppressWarnings("值") 抑制警告(写在类或方法上,对该类或方法起作用)(多个参数的语法:({"值1", "值2"}))
@SuppressWarnings("unchecked") 抑制未检查警告
@SuppressWarnings("deprecation") 抑制不建议使用警告
常用注解的注解(元注解)
@Retention(RetentionPolicy.SOURCE) 指定注解的保留策略(保留在源文件中)
@Retention(RetentionPolicy.CLASS) 指定注解的保留策略(保留在源文件中、class文件中)(默认)
@Retention(RetentionPolicy.RUNTIME) 指定注解的保留策略(保留在源文件中、class文件中、运行时中)
@Target(ElementType.METHOD) 指定注解的使用区域(此例为限定方法中使用,其他例略)
…… ……
@Documented 指定生成文档时该注解内容也加入文档
@Inherited 指定注释类型被自动继承
自定义注解
注意:
1)当我们使用 @注解名 定义一个注解时,该注解隐式继承了 java.lang.annotation.Annotation 接口;
2)当我们使用 interface 接口名 extends Annotation 定义一个接口时,虽然该接口继承了 Annotation 接口,但它仍然是接口而不是注解;
3)Annotation本身是接口而不是注解。
以上三点和枚举类似。
代码示例:
package com.tongwx.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //注解的注解:指定注解的保留策略为保留在源文件中 @Retention(RetentionPolicy.SOURCE) @interface MyAnnotation1 {//没有属性的注解 } //注解的注解:指定注解的保留策略为保留在源文件中、class文件中)(默认) @Retention(RetentionPolicy.CLASS) @interface MyAnnotation2 {//带一个属性的注解 String name(); } //注解的注解:指定注解的保留策略为保留在源文件中、class文件中、运行时中 @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation3 {//带默认属性值的注解 String name() default "hello"; } //注解的注解:指定注解的使用区域。有以下ElementType枚举值: //ANNOTATION_TYPE、CONSTRUCTOR、FIELD、LOCAL_VARIABLE、METHOD、PACKAGE、PARAMETER、TYPE @Target(ElementType.METHOD) @interface MyAnnotation4 {//带一个value属性的注解 String value(); } //注解的注解:指定生成文档时该注解内容也加入文档 @Documented @interface MyAnnotation5 {//带多个属性的注解 String name(); String value(); } //注解的注解:指定注释类型被自动继承 @Inherited @interface MyAnnotation6 {//带数组和枚举属性的注解 String[] name(); MyEnum myEnum(); } public class TestMyAnnotation { @MyAnnotation1 //没有属性的注解 @MyAnnotation2(name = "hello") //带一个属性的注解 @MyAnnotation3() //带默认属性值的注解:保持默认值则不写属性,否则写 属性="新值" @MyAnnotation4("hello") //只带一个value属性的注解:可省略value属性名 @MyAnnotation5(value = "hello", name = "world") //带多个属性的注解:不能省略属性名 @MyAnnotation6(name = { "How", "do", "you", "do" }, myEnum = MyEnum.Hello) //带数组和枚举属性的注解 public static void main(String[] args) { } } enum MyEnum { Hello, World } |
反射读取注解信息
前提条件:@Retention(RetentionPolicy.RUNTIME)
代码示例:
package com.tongwx.annotation; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; public class AnnotationReflectionDemo { public static void main(String[] args) throws NoSuchMethodException, SecurityException { Class<MyClass> myClassType = MyClass.class;//获取类的Class对象 Method outputMethod = myClassType.getDeclaredMethod("output", new Class[] {});//获取方法 if (outputMethod.isAnnotationPresent(MyAnnotation.class)) {//如果方法存在注解 MyAnnotation myAnnotation = outputMethod.getDeclaredAnnotation(MyAnnotation.class);//获取方法上指定类型的注解 System.out.println("country=" + myAnnotation.country() + ", " + "capital=" + myAnnotation.capital());//获取注解属性 } Annotation[] declaredAnnotations = outputMethod.getDeclaredAnnotations();//获取方法上的所有注解,无则返回空数组 for (Annotation annotation : declaredAnnotations) { //@SuppressWarnings不会打印,因其@Retention(RetentionPolicy.SOURCE)不是RUNTIME System.out.println(annotation.annotationType().getSimpleName()); } } } @Retention(RetentionPolicy.RUNTIME)//反射读取注解的前提 @interface MyAnnotation { String country() default "China"; String capital(); } @MyAnnotation(country = "USA", capital = "Washington, D.C.") class MyClass { @MyAnnotation(country = "Russia", capital = "Moscow") @Deprecated @SuppressWarnings("unchecked") public void System.out.println("output something!"); } } |
package com.tongwx.common_code; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 表的注解 */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)//保证反射可用 public @interface Table { String name();//数据的表名 } | package com.tongwx.common_code; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 字段的注解 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) //保证反射可用 public @interface Column { String name();//字段名称 } |
package com.tongwx.common_code; @Table(name = "student_list") public class Student { @Column(name = "s_id") private int id; @Column(name = "s_name") private String name; @Column(name = "s_age") private int age; 省略getter、setter和toString方法 } | package com.tongwx.common_code; @Table(name = "teacher_list") public class Teacher { @Column(name = "t_id") private int id; @Column(name = "t_name") private String name; @Column(name = "t_age") private int age; 省略getter、setter和toString方法 } |
package com.tongwx.common_code; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.handlers.BeanHandler; /** * 基础dao */ public class BaseDao<T> { //具体的dao上面的泛型类型 private Class targetClass; //表名 private String tableName; public BaseDao(){ /** * 需要解决的问题: * 1) 得到具体的业务dao运行过程中的泛型具体类型(Student/Teacher),可以封装ResultSet * 2) 得到泛型具有类型名称 ,就是表名 */ //1)this : 代表当前运行的dao对象 //System.out.println(this.getClass()); //2)this.getClass(): 代表当前运行dao对象的Class对象 Class clazz = this.getClass(); //public class TeacherDao extends BaseDao<Teacher> //3)clazz.getGenericSuperclass(): 得到当前dao对象的父类(参数化类型) Type type = clazz.getGenericSuperclass(); // BaseDao<Teacher> //4)把父类的类型强转成子类(参数化类型: ParameterizedType) ParameterizedType param = ( ParameterizedType)type; // BaseDao<Teacher> //5)param.getActualTypeArguments():得到参数化类型 上面的泛型类型列表 Type[] types = param.getActualTypeArguments(); // <Teacher> //6)取出泛型类型列表中的第一个泛型类型 Type target = types[0]; // Teacher //7)强制成Class类型 targetClass = (Class)target; try { //System.out.println(targetClass.getSimpleName()); /** * 获取表名 来自于 类上面的注解 */ Table table = (Table)targetClass.getAnnotation(Table.class); tableName = table.name(); } catch (Exception e) { e.printStackTrace(); } } public List<T> findAll(){ try { QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource()); return (List<T>)qr.query("select * from "+tableName+"", new MyBeanListHandler()); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } public T findById(int id){ try { QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource()); return (T)qr.query("select * from "+tableName+" where id=?", new BeanHandler(targetClass),new Object[]{id}); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } /** * 自行设计一个封装多个对象的List集合的ResultSetHandler */ class MyBeanListHandler implements ResultSetHandler{ @Override public Object handle(ResultSet rs) throws SQLException { try { List<T> list = new ArrayList<T>(); //得到结果集的元数据 ResultSetMetaData rsmd = rs.getMetaData(); //得到表的列数量 int columnCount = rsmd.getColumnCount(); while(rs.next()){//行 //创建对象 T obj = (T)targetClass.newInstance(); //把字段值封装到对象中 //遍历列 for(int i=1;i<=columnCount;i++){ //得到列的值 Object value = rs.getObject(i); //得到列名称 String columnName = rsmd.getColumnName(i).toLowerCase(); //遍历所有属性 Field[] fields = targetClass.getDeclaredFields(); for (Field field : fields) { //得到属性上面的注解 Column column = field.getAnnotation(Column.class); //得到注解的内容 String cname = column.name().toLowerCase(); if(columnName.equals(cname)){ field.setAccessible(true); //我需要赋值的属性,给属性赋值 field.set(obj, value); break; } } } //把封装好的对象放入LIst集合中 list.add(obj); } return list; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } } } | |
package com.tongwx.common_code; /** * 具体的业务dao * @author APPle * */ public class StudentDao extends BaseDao<Student>{ } | package com.tongwx.common_code; /** * 具体的业务dao * @author APPle * */ public class TeacherDao extends BaseDao<Teacher>{ } |
package com.tongwx.common_code; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; /** * 连接池版本的jdbcUtil * @author APPle * */ public class JdbcUtil { //创建连接池对象 private static DataSource ds = new ComboPooledDataSource(); /** * 获取连接池对象 */ public static DataSource getDataSource(){ //注意: 不要这么写,这样会导致的连接很快用完了 //DataSource ds = new ComboPooledDataSource(); return ds; } } | package com.tongwx.common_code; import java.util.List; import org.junit.Test; public class TestDao { @Test public void testStu(){ StudentDao stuDao = new StudentDao(); List<Student> list = stuDao.findAll(); for (Student student : list) { System.out.println(student); } } @Test public void testTea(){ TeacherDao teaDao = new TeacherDao(); List<Teacher> list = teaDao.findAll(); for (Teacher teacher : list) { System.out.println(teacher); } } } |