一、自动封装
1.数据的封装思想:
在使用java的过程中,不可避免的要从数据库中查询数据,那么如何将查询到的结果进行展示呢?我们先来观察一下查询结果的内容展示:
Java中无法做到像数据库管理系统这样如此方便的获得并展示数据,但是我们通过观察之后发现,每一行数据都具有相同的内容(id,empName,deptId,regTime),换句话说每一行数据都具有相同的属性;在Java中我们把具有相同属性的事物称之为类,那么这张表是不是也可以看作是一个类,每一行数据都是这个类的对象,这就是java获取数据库数据的基本思想;
2.为了方便获取数据,java提供了JavaBean规范,要求所有的类在创建的时候需要遵循JavaBean规范,这些规范其实就是对应了数据库中的数据安全规范
3.自动封装获取数据
我们为查询结果建立一个实体类,因为满足JavaBean规范,所有java程序会自动的将查询结果去跟类中的属性(成员变量进行匹配)
public List<Applicant> selectApplicant() throws SQLException {
//准备sql
String sql = "select * from applicant ";
//执行sql,qury方法的三个参数,sql:要执行的sql语句,null:执行sql时需要的参数,这里没有过滤条件,所以是null;Applicant.class:我们创建的实体类的.class文件,这里用了反射
List<Applicant> applicantList = super.query(sql, null, Applicant.class);
//返回结果,sql查询的结果被写入到list集合中;
return applicantList.size() > 0 ? applicantList : null;
}
4.数据的存储
Java中用于保存数据的手段常用的有两种:数组和集合;数组的长度有限,而集合的长度无限,所以这里选择集合来接收sql的查询结果;
我们将sql查询结果中的每一行数据封装成一个类对象,再将这些对象存入到集合中;也就是说集中的任意一个元素就代表一行数据。
但是这种封装也是有弊端的:
弊端一:就是我们只能对一个表进行操作,但在实际使用中经常会出现多表查询关联查询;
弊端二:自动封装只能识别java中的8大基本类型(byte,short,int,long,float,double,char,boolean),引用类型和自定义类型无法识别;
弊端一的解决方式:根据多表查询的结果创建一个实体类,然后继续使用自动封装;还有种方式就是手动封装;
弊端二的解决方式:在封装的时候手动注册引用类型和自定义类型;
接下来我们来看重点:手动封装!
二、手动封装
1.手动封装的原理及思想:
虽然在解决多表查询时可以根据结果新建实体类,但是有时候字段属性太多,会造成繁琐的工作量;为了避免这种情况就使用手动封装,说白了其中心思想就是偷懒~
原理:就是利用表中的外键,将外键换成要关联的表的类对象想;
下面上代码:
表1:用户表
表2:权限表
3.关联查询结果
4.根据关联结果建立实体类
package com.qfedu.vo;
import com.qfedu.entity.Role;
import java.util.Date;
public class VUserInfo {
private Integer id;
private String userName;
private String password;
private boolean gender;
private Date birthday;
private Date createTime;
private String content;
private Role role;//这里是重点,将关联表的类对象替换了外键roleId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
5.手动封装代码
public class UserDaoImpl implements UserDao {
@Override
public List<VUserInfo> findAll() {
QueryRunner qr = JdbcUtils.getQueryRunner();
String sql = "select u.*, r.id rid,r.roleName from user u\n" +
"inner join role r\n" +
"on u.roleId=r.id";
List<VUserInfo> userList = null;
try {
userList = qr.query(sql, new ResultSetHandler<List<VUserInfo>>() {
@Override
public List<VUserInfo> handle(ResultSet rs) throws SQLException {
List<VUserInfo> list = new ArrayList<>();
while (rs.next()) {
VUserInfo user = new VUserInfo();
user.setId(rs.getInt("id"));
user.setUserName(rs.getString("userName"));
user.setPassword(rs.getString("password"));
user.setBirthday(rs.getTimestamp("birthday"));
user.setCreateTime(rs.getTimestamp("createTime"));
user.setContent(rs.getString("content"));
user.setGender(rs.getBoolean("gender"));
Role role = new Role();
role.setId(rs.getInt("rid"));
role.setRoleName(rs.getString("roleName"));
user.setRole(role);
list.add(user);
}
return list;
}
});
} catch (SQLException e) {
e.printStackTrace();
}
return userList;
}
}