`
确实比较男
  • 浏览: 115265 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Guzz源码分析(三) guzz加载dialect初始化数据类型

    博客分类:
  • Guzz
阅读更多

1. 前面分析了guzz加载guzz.xml的过程,今天继续解析guzz加载数据库方言,初始化数据类型的过程

2. 首先在GuzzContextImpl的initFromMainConfig方法中找到下面的代码:

 

//加载dialect初始化数据类型
Map ds = builder.getConfiguredDialect() ;
if(ds == null){
	log.warn("dialect(s) not found.") ;
}else{
	this.dialects = ds ;
}

这里就是guzz在加载dialect初始化数据类型,主要的实现在GuzzConfigFileBuilder的getConfiguredDialect方法中,因为整个guzz.xml的文件都是加载到了GuzzConfigFileBuilder中,进入到getConfiguredDialect()方法中

public Map getConfiguredDialect(){
List ls = this.rootDoc.selectNodes("dialect") ;
	if(ls == null) return null ;
	if(ls.isEmpty()) return null ;
	HashMap ds = new HashMap() ;
	for(int i = 0 ; i < ls.size() ; i++){
		Element e = (Element) ls.get(i) ;
		String d_cls = e.attributeValue("class") ;
		String d_name = e.attributeValue("name") ;
		if(StringUtil.isEmpty(d_name)){
			d_name = "default" ;
		}
		Dialect dialect = (Dialect) BeanCreator.newBeanInstance(d_cls) ;
		//注册用户自定义的类型
		List types = e.selectNodes("type") ;
		for(int j = 0 ; j < types.size() ; j++){
		        Element t = (Element) types.get(j) ;
		        String typeName = t.attributeValue("name") ;
		        String className = t.attributeValue("class") ;
		        Class cls = ClassUtil.getClass(className) ;
		        Assert.assertTrue(SQLDataType.class.isAssignableFrom(cls), "user-defined data type must be a instance of type:" + SQLDataType.class.getName()) ;
		        dialect.registerUserDefinedTypes(typeName, cls) ;
	        }
	        ds.put(d_name, dialect) ;
        }
	return ds ;
}

首先查询了文档中所有的dialect节点,然后查询了每一个节点的属性(calss,name),若没有配置name属性,那么就默认是default,这里和帮助文档中的一致,根据配置的class,通过BeanCreator创建了一个实例,具体是什么对象,要看guzz.xml中的配置,我这里的配置是:

 

<dialect class="org.guzz.dialect.Mysql5Dialect"></dialect>

所有创建的实例就是Mysql5Dialect,由于guzz.xml支持多个数据库,所以方言肯定也是不同的,Guzz的方言类结构图如下:

从类结构图可以看出来guzz支持的数据库有哪些,当然我们自己根据需要也可以自己定义需要的数据库方言,只要实现AbstractDialect这个抽象类就可以了,因为我使用的是mysql,所以也就只看了Mysql5Dialect,打开看类,只有一个主要的方法,就是对mysql的limit的出来,每一中数据库的分页查询方式都有不同的实现。接着就是查看父类进入到AbstractDialect类,有3个重要的方法regSystemTypes,getDataType,registerUserDefinedTypes

3. 首先看regSystemTypes,部分代码:

 

protected void regSystemTypes(){
	sqlTypes.put("int", IntegerSQLDataType.class) ;
	sqlTypes.put("Integer", IntegerObjectSQLDataType.class) ;
	sqlTypes.put(Integer.class.getName(), IntegerObjectSQLDataType.class) ;
		
	sqlTypes.put("string", StringSQLDataType.class) ;
	sqlTypes.put("varchar", StringSQLDataType.class) ;
	sqlTypes.put("nvarchar", StringSQLDataType.class) ;
	....
}

一看就明白,把java对应的数据类型和数据库中的数据类型都写了一个对应的出来类,放入到了一个map对象中。getDataType方法看名字也知道了是获取数据列的类型处理类也就是SQLDataType,类结构图:

4. 然后我们回到getConfiguredDialect,继续看,在这个方法中我们看到了在找了dialect节点后,又在dialect节点下面找子节点type,若是有配有type的话就解析后调用registerUserDefinedTypes方法,这个方法是注册用户自定义的数据类型,这点在帮助文档中没有提到,但实际上Guzz是有这个功能的。

出来完了所有的dialect节点后返回存有dialect的一个map,这个map中村了所有的dialect,每一个dialect对象中又存有所有的数据类型(SQLDataType)

5. 到此为止,guzz 完成了加载dialect初始化数据类型。

6. 刚才说到guzz可以自定义数据类型,出来特定类型的对象,但是guzz帮助文档没有提到,我们写一个简单的例子测试这个功能:

6.1 定义两个实体类员工类 Emp 和部门类Depart

 

package com.hqhp.maven.model;
import javax.persistence.Column;
import org.guzz.annotations.Table;
/**
 * 员工
 * @author 确实比较男
 */
@javax.persistence.Entity
@org.guzz.annotations.Entity(businessName = "emp")
@Table(name = "tb_emp")
public class Emp extends BaseModel {
	private static final long serialVersionUID = -3759132536120038862L;
	private String name;
	private int age;
	@Column(name = "departid")
	private Depart depart;

	//getter   setter  省略
	@Override
	public String toString() {
		return "Emp [name=" + name + ", age=" + age + ", depart=" + depart + "]";
	}
}

 

package com.hqhp.maven.model;
import org.guzz.annotations.Table;
/**
 * 部门
 * @author 确实比较男
 */
@javax.persistence.Entity
@org.guzz.annotations.Entity(businessName = "depart")
@Table(name = "tb_depart")
public class Depart extends BaseModel {
	private static final long serialVersionUID = -2394287758178521691L;
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Depart [name=" + name + "]";
	}

}

6.2 guzz.xml配置文件如下:

 

<guzz-configs>
	<dialect class="org.guzz.dialect.Mysql5Dialect">
		<type name="com.hqhp.maven.model.Depart" class="org.guzz.orm.type.DepartSQLDataType" />
	</dialect>
	<tran locator="spring">
		<dbgroup name="default" masterDBConfigName="masterDB" />
	</tran>
	<!-- 类似于Mysql数据库的配置文件 -->
	<config-server>
		<server class="org.guzz.config.LocalFileConfigServer">
			<param name="resource" value="guzz_app.properties" />
		</server>
	</config-server>
	<business-scan resources="classpath*:com/hqhp/maven/model/*.class" />
</guzz-configs>

根据源码的分析,我们的dialect节点可以这样写。

6.3 接下来我们就开始写org.guzz.orm.type.DepartSQLDataType,也就是自定义SQLDataType,仿照到guzz的写,代码如下:

 

package org.guzz.orm.type;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.guzz.exception.DataTypeException;
import com.hqhp.maven.dao.UserDao;
import com.hqhp.maven.model.Depart;
import com.hqhp.maven.utils.SpringUtil;
/**
 * @author 确实比较男
 */
public class DepartSQLDataType implements SQLDataType {
	@Override
	public void setNullToValue(Object nullValue) {
		System.out.println("setNullToValue...............");
		if (nullValue != null) {
			throw new DataTypeException("null value unsupported. nullValue is:" + nullValue);
		}
	}
	@Override
	public Object getSQLValue(ResultSet rs, String colName) throws SQLException {
		System.out.println("getSQLValue...........colName....");
		String departid = rs.getString(colName);
		System.out.println("=====:" + departid);
		UserDao userDao = (UserDao) SpringUtil.getBean("userDao");
		Depart depart = userDao.queryDepart(departid);
		System.out.println(depart.getId() + "  " + depart.getName());
		return depart;
	}

	@Override
	public Object getSQLValue(ResultSet rs, int colIndex) throws SQLException {
		System.out.println("getSQLValue..........colIndex.....");
		String departid = rs.getString(colIndex);
		UserDao userDao = (UserDao) SpringUtil.getBean("userDao");
		Depart depart = userDao.queryDepart(departid);
		System.out.println(depart.getId() + "  " + depart.getName());
		return depart;
	}
	@Override
	public void setSQLValue(PreparedStatement pstm, int parameterIndex, Object value) throws SQLException {
		System.out.println("setSQLValue...................");
		System.out.println(value);
		Depart depart = (Depart) value;
		System.out.println(depart.getId());
		pstm.setString(parameterIndex, depart.getId());
	}
	@Override
	public Class getDataType() {
		System.out.println("getDataType...............");
		return Depart.class;
	}
	@Override
	public Object getFromString(String value) {
		System.out.println("getFromString...............");
		return null;
	}
}

主要是这两个方法,在保存和查询的时候会调用。

6.4 最后写一个查询类去查询和保存emp对象:

 

public boolean insertEmp(Emp emp) {
	TransactionManager tm = guzzDao.getTransactionManager();
	WriteTranSession session = tm.openRWTran(true);
	try {
		return session.insert(emp) == null ? false : true;
	} finally {
		session.close();
	}
}
public Emp queryEmp(Serializable id) {
	TransactionManager tm = guzzDao.getTransactionManager();
	ReadonlyTranSession session = tm.openDelayReadTran();
	try {
         	return (Emp) session.findObjectByPK(Emp.class, id);
	} finally {
		session.close();
	}
}

向数据库中插入一个emp对象,若是把depart的id存入了数据库那么说明保存对象正确;查询一个emp对象,若是取出的emp对象的depart对象不为空那么查询也是正确的,就可以直接存取对象了,说明自定义数据类型正确

 

Depart depart = new Depart();
depart.setName("技术前沿研究所");
userDao.insertDepart(depart);
depart.setId("402881eb4371f277014371f358b70000");
Emp emp = new Emp();
emp.setName("silentwu");
emp.setAge(21);
emp.setDepart(depart);
empDao.insertEmp(emp);   //保存emp
		
//查询emp
Emp emp= empDao.queryEmp("402881eb4372033c01437203744f0000");
System.out.println(emp);

测是结果正确。

分享到:
评论

相关推荐

    guzz: a empty sample project build20110323.zip

    通过分析和运行这个项目,我们可以深入理解Guzz的核心概念和使用方法。 首先,Guzz的设计目标是提供一种灵活、高效的解决方案,用于处理实时或批处理的数据流任务。它采用了面向任务编程模型,使得开发者可以专注于...

    guzz的jar包

    guzz的jar包,工程下直接考过来的,可以直接使用

    guzz开发jar

    guzz是一套用来进行快速开发和高性能网站设计的java框架,通过ORM、多数据源数据管理、以及通用数据处理,为系统在数据层的设计提供一站式解决方案。用于替代或者补充hibernate或ibatis,并提供更多的大型系统架构...

    Guzz-crx插件

    为了安装这个插件,用户通常需要将Guzz.crx文件拖放到支持的浏览器的扩展管理页面,或者通过浏览器的开发者模式手动加载。 总的来说,Guzz-crx插件通过提供屏幕共享功能,极大地丰富了Guzz.io的协作体验,让用户...

    guzz的「Guzz」-crx插件

    为Guzz启用屏幕共享。 此扩展程序允许www.guzz.io用户共享桌面屏幕 支持语言:English

    bicq代码

    学习源码首先需要熟悉这些语言的基本语法、数据类型、控制结构等。 2. **设计模式和架构**:源码通常遵循一定的设计原则和模式,如单例模式、工厂模式或MVC(模型-视图-控制器)架构。理解和分析这些模式有助于我们...

    java框架面试题

    它负责初始化和创建Session对象,并且通常在整个应用程序生命周期内只创建一次。 **2. Session的线程安全性** Session对象是非线程安全的,不能被多个线程共享。每个线程应该有自己的Session实例。为了避免频繁地...

    java框架方面面试题

    持久层负责数据的持久化存储,与数据存储逻辑的分离、抽象化的数据访问接口的提供、底层实现的分离、资源管理与调度的分离、数据抽象的实现都是持久层设计需要关注的方面。目前市面上有多个持久层框架,如Hibernate...

    JAVA面试问题及答案.docx

    常见的持久层框架有Hibernate、MyBatis、TopLink、Guzz、jOOQ、Spring Data和ActiveJDBC等,它们都为开发者提供了便捷的数据持久化解决方案。 在Hibernate中,Session提供了多种操作数据库的方法,如load()和get()...

    Java面试题全集(下)

    持久层框架则是实现数据持久化操作的一系列框架,常见的有Hibernate、MyBatis、TopLink、Guzz-jOOQ、SpringData和ActiveJDBC等。 3. Hibernate持久层框架:Hibernate是一个开源的ORM框架,它提供了一个完整的解决...

    InstallAnywhere 2008破解与自定义PlugIn陷阱经验分享

    NULL 博文链接:https://guzz.iteye.com/blog/256235

    轻松将一张大表分切到不同的机器中

    NULL 博文链接:https://guzz.iteye.com/blog/883225

    JAVA面试问题及标准答案.docx

    常见的Java持久层框架有Hibernate、MyBatis、TopLink、Guzz、jOOQ、Spring Data和ActiveJDBC等,它们都提供了方便的数据操作和数据库访问功能。 在Hibernate中,SessionFactory是一个关键组件,它是线程安全的,...

    Java面试题全集.docx

    - **数据抽象**:将数据操作面向对象化,使得开发者更加关注业务逻辑而不是底层数据操作。 - **常用持久层框架**: - **Hibernate**:最受欢迎的ORM框架之一,提供了强大的对象关系映射功能。 - **MyBatis**:一...

    bof:人类的HTTP客户端

    总结起来,Bof: 是用户友好的避免使用魔术字符串和数组进行配置:相反,它提供可由IDE自动完成的显式,类型化和文档化方法带有默认值:默认支持JSON,4xx和5xx响应抛出异常,默认情况下超时时间短符合PSR-7 未来的...

    哀悼日变灰操作

    根据给定文件的信息,我们可以提炼出与“哀悼日变灰操作”相关的IT知识点,但首先需要澄清的是,文件内容似乎包含了一些不相关的代码片段和文档,这些内容涉及一个名为"Guzz"的全栈数据层解决方案框架,以及一系列与...

    php-sdk:用于连接到MultiSafepay REST API的默认PHP库

    MultiSafepay PHP SDK关于...如果您没有安装任何客户端实现,请使用以下命令: composer require guzzlehttp/guzzle如果您没有安装任何工厂实现,请使用以下命令: composer require http-interop/http-factory-guzz

Global site tag (gtag.js) - Google Analytics