JDBC的弊端:
1.数据库信息硬编码到Java代码中
2.sql语句硬编码到Java代码中
3.JDBC步骤太过于繁琐
使用端:
提供 核心配置文件
xml文件,数据库信息的配置信息
sql语句的配置文件信息
框架端:
首先,我们需要解析使用端提供的xml核心配置文件,解析完后以流的形式存在,
不能将配信息以流的形式放在内存中,不好操作,我们可以创建JavaBean来储存。
创建两个JavaBean来封装这些配置信息
Mapper:
sql sql语句
resultType 返回值类型的全限定类名
Configuration:
数据库的基本信息
一个大的Map<唯一标识,Mapper> 唯一标识:namespace+"."+id
好,封装完xml核心配置后,我们需要创建SqlSession来完成jdbc操作的CRUD
习惯性来一个SqlSession接口,因为这样可以考虑使用JDK的动态代理
创建SqlSession实现类impl 依赖Configuration 我们需要cfg来实现解析xml
发现SqlSession实现类写的东西太多了,还想满足不同数据库的需求
就想到了工厂 SqlSessionFactory 工厂可以产生很多不同的SqlSession
SqlSession 就可以把解析xml的任务交给工厂,
这样工厂也就依赖了Configuration
创建工厂步骤也是很多
工厂可以选择构建者模式 ----来一个SqlSessionFactoryBuilder
在build的类中解析xml文件
知识点: 类加载器.getResourceAsStream("") 返回inputStream is 类型
框架过程也可以先创建一个构建者builder-->工厂-->sqlsession-->实现类
为了使用端的方便:
1.xml -------->最普通的就是了
2.xml 跟 代理对象 -------->使用端只需要一个接口就可以
框架端:在SqlSession接口中添加getMapper(Class clazz) 方法为动态代理使用
在实现类实现方法,
3.注解 跟 代理对象
其中:涉及到自己模糊的知识点有:
反射贯穿其中。
动态代理:
public <E> E getMapper(Class clazz) throws Exception {
//创建incocationHandler
MapperProxyFactory proxy = new MapperProxyFactory(this);
//创建动态代理对象
return (E)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, proxy);
}
}
/////////////////////////////////////////////////////
public class MapperProxyFactory implements InvocationHandler{
private SqlSessionImpl sqlSession;
public MapperProxyFactory(SqlSessionImpl sqlSession) {
this.sqlSession=sqlSession;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取当前接口的全限定类名
String className = proxy.getClass().getGenericInterfaces()[0].getTypeName();
//invoke方法:就是在查询数据库
String mapperId = className+"."+method.getName();
return sqlSession.selectAll(mapperId);
}
}
元数据:
获取查询数据结果中的列名
JDBC:封装结果集
user 类
username
password
结果集resultSet
username : zhangsan
password : 123
借助元数据:
查询出所有的列名
查询出列的个数
获取数据库表名
//2.元数据
ResultSetMetaData metaData = rs.getMetaData();
//获取数据库中的字段个数
int count = metaData.getColumnCount();
//获取所有字段的名字放入list集合中
List<String> countlist = new ArrayList<String>();
for (int i = 1; i <= count; i ++ ) {
countlist.add(metaData.getColumnName(i));
}
while (rs.next()) {
//创建实体对象
Object object = clazz.newInstance();
//赋值
for (String countName : countlist) {
for (Method method : methods) {
if(method.getName().equalsIgnoreCase("set"+countName)) {
method.invoke(object, rs.getObject(countName));
}
}
}
//放入list
list.add(object);
}
XML文件解析:
1.创建SAXReader
SAXReader reader = new SAXReader();
2.获取document对象
Document document = reader.read("");
3.获取根节点
Element root = document.getRootElement();
//根节点
定位节点:
1.selectNodes 指定标签获取 "//标签名"
eg: root.selectNodes("//property");
2.element
3.elements
//解析节点中的内容
1. text 获取标签中的内容
2.attributeValue 根据标签书属性获取属性的取值
网友评论