一、简要介绍一下自己封装一个jdbc的思路
- 封装是什么,为什么要封装
封装:是面向对象的一种表现形式,主要是面对可相信的对象提供方便,让这类对象具有使用的权利,对其它对象进行拦截,在没有相应权限的情况下是没有使用权利的。
对于一些工具类就是这样的情况,把具体实现的过程封装到类中,只提供你使用的最终接口,只要能实现你的业务就可以,其他的具体操作你没有办法拿到
封装就是为了将一团分布的东西集中在一起,所以才会有了面向对象的思想,因为将一个具体的事物抽象的放在了一个类中,该类中保存了这个事物的具体属性和行为,
属性就是一个事物的特点,比如:一个人的姓名、身高、体重、性别、年龄等
行为就是一个事物的动作,比如:一个人有吃饭,睡觉,学习的动作
因此,被封装的对象就更加具体化,谁需要访问一个对象的任何成员,就只需要找到该对象就可以了,但是这个对象也有一些成员不想让你看到,比如说每个人都有隐私或者密码,或者不想公开的信息,这些信息,一般人是不知道的,这就是封装。
还有比如说你的qq好友的访问权限一样,你可以把陌生人设置为没有空间的访问权限,一般的好友含有空间访问的权限,但不能看照片,不能评论,好朋友就可以看照片,可以评论,但是你有一些隐私的照片或者留言,你不想让任何人看到,或者你给留言者看到,那么就会被限制大部分的人,另外还有一些信息,你不想被任何人知道,那么能够看到的人也就只有你一个人,这些就属于封装的不同的表现形式,封装就是根据不同的对象给定不同的访问权限,以此达到封装的效果
- jdbc的封装特点:
通过反射打破原有封装,使用对象中的成员,并对成员进行操作,再封装回该对象
但需要处理一个问题,那就是数据库中的表名,字段不一定和你的对象是一致的,这个时候就需要将数据库中的表名,表字段和你的对象进行匹配,但是怎么匹配呢,其实匹配的方法挺多,我自己呢使用过两种匹配的方法,一种的使用map进行匹配,另一种是通过注解进行匹配,我个人推荐使用注解匹配吧
- 需要知道反射和注解的使用方法
**反射:**根据名字可以大概猜测就是反过来映射的意思,其实就是在不通过直接new的情况下创建实例或者拿到这个对象的成员就是反射。有人肯定会问,我直接通过new创建对象不是更加简单吗,使用反射来创建不是跟家复杂麻烦。有这样想法是很正常的,通常都是直接new就可以了,但是有时候你需要在运行之前就要拿到里边的成员,并且对其中的成员做相应的封装的时候,那就需要使用反射了,因为如果你使用new的话,你只能拿到当前的一个封装,里边并没有做任何处理,这不是你想要的结果,所以反射是很重要的,就连很多设置模式都使用了反射的原理,spring的工厂的自动化接口一节对象的实例化也是通过反射来创建,因为spring不能直接new对象,它是通过你在配置文件中设置的bean对象的class路径,通过反射才创建的对象,spring的第二种通过注解对bean的依赖注入也是通过反射,虽然减少了传统的配置文件的配置,但是在配置文件中却需要自动扫描某一个路径或者全包下的所有类文件,然后对标注了这个注解类中的属性对象进行实例化的操作,
其实就是使用反射加载字节码文件也就是class文件,
Class clz = (Class)Class.forName(“com.ucai.entity.Student”);
T newInstance = clz.newInstance();//调用无参构造函数
**注解:**注解比较深的应用我不是特别清楚,现在我使用的最对的也就是一个标注的功能,再通过反射的情况来判断或者含有相应注解的类或者类成员,因为注解可以放在类的所有成员上,类上边也是可以的
所以通过反射和注解就可以对数据库表和实体对象之间做一个联系了,俗话说 一 一 对应就是这么个道理
二、jdbc的映射,表映射,将对象中的属性映射成表字段
注:下边使用的是数据库连接池来获取的连接,数据库连接池的编码,在上一章事务管理中已经给出
- 表注解(Tab.java)
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 实体类映射数据库表类
* @author F
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE})
public @interface Tab {
/**
* 用于修饰实体类,表示实体类名与数据库表名之间的映射
* @return
*/
String table() default "";
}
- 字段注解(Column.java)
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 实体类属性数据库映射标识类
* @author F
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Column {
/**
* 字段名称
* @return
*/
String name();
/**
* 字段类型
* @return
*/
Class<?> type();
/**
* 字段长度
* @return
*/
int len() default 11;
/**
* 是否为主键
* @return
*/
boolean isPrimary() default false;
/**
* 是否可为空
* @return
*/
boolean isNull() default true;
/**
* 是否自增长
* @return
*/
boolean isAutoIncrement() default false;
/**
* 是否可重复
* @return
*/
boolean isUnique() default true;
}
- 实体类employee.java
package entity;
import java.io.Serializable;
import annotation.Column;
import annotation.Tab;
@Tab(table = "employee")
public class Employee implements Serializable{
private static final long serialVersionUID = 1L;
@Column(name="emp_id",type=Integer.class,isNull = false,isPrimary = true,isAutoIncrement=true)
private Integer emp_id;
@Column(name="emp_code",type=String.class,len = 30,isNull = false,isUnique = false)
private String emp_code;
@Column(name="emp_name",type=String.class,len = 30,isNull = true)
private String emp_name;
public Employee(){
super();
}
public Employee(String emp_code, String emp_name) {
this();
this.emp_code = emp_code;
this.emp_name = emp_name;
}
public Integer getEmp_id() {
return emp_id;
}
public void setEmp_id(Integer emp_id) {
this.emp_id = emp_id;
}
public String getEmp_code() {
return emp_code;
}
public void setEmp_code(String emp_code) {
this.emp_code = emp_code;
}
public String getEmp_name() {
return emp_name;
}
public void setEmp_name(String emp_name) {
this.emp_name = emp_name;
}
/**
* 重写父类的toString方法,将对象属性以field&value的形式组装起来
*/
@Override
public String toString() {
return "emp_id=" + emp_id + "&emp_code=" + emp_code + "&emp_name=" + e