`

看我山寨版 hibernate 简单实现 一

阅读更多

      这两天在做山寨的 hibernate,现已完成了 Session save,update, delete, get 还有Query 接口的实现.

Hiberate  ORM是软件在对象与关系数据库之间进行转换的一个模块层, 可简化数据库操作Dao类的实现.

一. 技术要点: 

1. 动态装载

 

      程序运行后才决定要装载哪些类,然后才实例化.

装载

Class c = Class.forName(className);

 

实例化

Object o = c.newInstance(); //调用的只是类的无参构造方法,但对本程序来说已经足够了

 

2 .反射

通过一个类的Class 类对象可以得到此类的所有信息,如 静态块,属性,方法,父类、接口,构造器,异常,方法参数,方法返回值, 它们都以对象的形式出现。一切皆对象。但是private 修饰的属性,方法却得不到,还是得要访问权限的。

java.lang.reflect Method[] m = c.getMethods();//到所有方法

...

得到的方法还可以调用

如 Object rt = m[0].invoke(o,参数);

class User{
   private String name;

   public void getName()
   {
      return name
   }
   public String setName(String name){
      this.name = name;
   }

}

 

如果我们要把从数据库中得到的  "name" 字段值 赋给 User 的name属性该怎么做?

那就应该调用 setName方法了.不会是一般的调用,用反射。

 

3。读取xml配置文件

 

使用dom4j

SAXReader reader = new SAXReader();
Document doc = reader.read(file); // file为File 对象
Element root = doc.getRootElement(); //得到根结点
Element e = root;
Iterator it=e.elementIterator();//得到迭代器

 

4. 得到xml配置文件的路径

这我以前讲过的,在写web工程时 src目录下的文件实际上被放到了 WEB-INF/classes下了

 

		String path = this.getClass.toString();//得到类名
		path = this.getClass.getResource(path.substring(path.lastIndexOf(".")+1)+".class").toString();//得得此类的路径  
		path = path.substring(0,path.indexOf("/WEB-INF"));  //得到项目路径
		path = path + "/WEB-INF/classes";//得到classes路径
		path = path + "/hibernate.hbm.xml";//得到配置文件路径
		if(path.startsWith("jar:")){
			path = path.substring(4);
		}
		URI uri = null;
		try {
			uri = new  URI(path);
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		Log.printLog("uri="+uri);
		File file = new File(uri);
		if(!file.exists()){
			Log.printLog("配置文件不存在!");
			return null;
		}

 

 

二。 配置及使用

 

1. 在src目录下建立hibernate.hbm.xml,先要引入mysql的驱动包啊

 

<?xml version="1.0" encoding="UTF-8"?>

<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property> //显示sql
<property name="dialect">mysql</property>   //数据库名
<property name="driver">com.mysql.jdbc.Driver</property> //
<property name="url">jdbc:mysql://localhost:3306/catpage</property>
<property name="username">root</property>
<property name="password">root</property>
<mapping-resource>User.hbm.xml</mapping-resource>      //pojo映射文件
</session-factory>
</hibernate-configuration>

 

    这和真的Hernate 差不多

 

2. 再在同级目录下建User.hbm.xml文件,也可以要其他路径,但得修改hibernate.hbm.xml了

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-mapping>
<class name="cn.netjava.model.User" table="user"> //pojo路径及表名
<id name="id" column="id"></id>  //主键

<property name="name" column="name" /> //字段
<property name="pwd"  column="pwd"/>
</class>
</hibernate-mapping>

 

3.编写pojo类 如User

package cn.netjava.model;

public class User {

	private int id;
	private String name;
	private String pwd;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
}

 

4.开始测试吧

package cn.netjava.model;

import cn.netjava.hibernate.Configuration;
import cn.netjava.hibernate.Session;

public class Test {

	public static void main(String args[]){
		try {
			//
			Session session = new Configuration().configure().buildSessionFactory().openSession();
			User user = (User)session.query(User.class, 8);//取得id为8的user
			System.out.println("name="+user.getName()+"\tpwd="+user.getPwd());
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 

 

打印结果: 

//省略.事先已经有了user表,也可用save方法,就可不事先建表啦

 name=a pwd=a 

 

 

 

三..再看代码吧.

 

首先是Session接口

 

package cn.netjava.hibernate;

public interface Session {

	/**
	 * 保存 pojo到数据库中
	 * @param obj  pojo bean对象
	 * @return  返回主键
	 */
	public int save (Object obj,Class c) ;
	/**
	 * 查询数据库得到pojo对象
	 * @param c pojo的类对象
	 * @param priKey 主键
	 * @return  pojo对象
	 */
	public Object query(Class c,Object priKey);
	
	/**
	 * 更新pojo到数据库中
	 * @param priKey 主键 属性值
	 * @param obj 要更新的pojo对象
	 * @param c 要更新的pojo 类对象
	 */
	public void update(Object priKey,Object obj,Class c);
	
	/**
	 * 从数据库中删除 pojo
	 * @param priKey 主键值
	 *  @c: pojo的类对象
	 *  return 删除是否成功
	 */
	public boolean delete(Object priKey,Class c);
	
	/**
	 * 使用sql查询语句查询
	 * @param sql sql查询语句
	 * @return 查询对象
	 */
	public Query createQuery(String sql);
	
}

 

它的实现类是 HibernateSession, 只看save代码好了

 

	/**
	 * 保存 pojo到数据库中
	 * @param obj  pojo bean对象
	 * @c Pojo的类对象
	 * @return  返回主键
	 */
	public int save (Object obj,Class c) {
		MappingConfiguration mc = findConfig(c);//pojo的配置信息类
//		查询是否有表存在,不存在则创建

		if(!hasTable(mc.getTable())){
			try {
				if(createTable(obj,c,mc.getTable())){
					Log.printLog("已创建表"+mc.getTable());
					tableMap.put(mc.getTable(), true);
				}
				else{
					Log.printLog("创建表失败");
					return 0;
				}
				
			} catch (Exception e) {
				Log.printLog("创建表失败");
				e.printStackTrace();
				return 0;
			}
		}
		
		List<Word> wordList = mc.getWordList(); // 取得pojo的字段列表
		
		//生成sql语句
		String sql = "insert into "+mc.getTable() +"(";
		for(Word w:wordList){
			if(!w.getAttrname().equals(mc.getPriKey().getAttrname())){//不是主建
				sql+=w.getColumn()+",";
			}
		}
		sql+=") values(";
		for(Word w:wordList){
			if(!w.getColumn().equals(mc.getPriKey().getColumn())){
				sql+="?,";
			}
		}
		sql+=")";
		/*  下几行为将sql中()里的多余的','去掉*/
		StringBuffer sb = new StringBuffer(sql);
		int s = sb.indexOf(",)");
		while(s>0){
			sb.deleteCharAt(s);
			s=sb.indexOf(",)");
		}
		sql =sb.toString();
		
		PreparedStatement pstmt = dbconn.getPSatement(sql);
		int num=0;
		try{
			//填充sql中的?
			for(Word w:wordList){
				if(!w.getColumn().equals(mc.getPriKey().getColumn())){
					Method m = Tool.getGetMethod(c,w.getAttrname());
					Object ort = m.invoke(obj);
					System.out.println("ort="+ort);
					pstmt.setString(++num, ort.toString());
						
				}	
			}
			pstmt.execute();
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		//以下为得到表中最后一行,因为设定mysql的主键生成方式为递增的,才能得到刚插入的行的 id
		sql = "select * from "+mc.getTable()+" order by "+mc.getPriKey().getColumn()+" desc limit 1";
		Query query = createQuery(sql);
		query.addEntity(c);
		List l = query.list();
		Object result = l.get(0);
		Method mPriKey = Tool.getGetMethod(c, mc.getPriKey().getAttrname());//取得主键的get方法
		Object rt = null;
		try {
			rt = mPriKey.invoke(result);
		} catch (Exception e) {
			Log.printLog("取得主键时出错了");
			e.printStackTrace();
		}
		Log.printLog("priKek="+rt);
		return Integer.parseInt(rt.toString());
	}

 

再看Query接口吧,它是查询数据库必要的,它的实现 是QueryImp,不贴出来了

 

package cn.netjava.hibernate;

import java.util.List;
/**
 * 查询接口
 * @author sky
 *
 */
public interface Query {

	/**
	 * 给查询得到的结果加入类型
	 * @param c 要转换成的类的类对象
	 */
	public void addEntity(Class c);
	/**
	 * 执行查询
	 * @return 是否成功
	 */
	public boolean excute();
	/**
	 * 得到查询结果,放到List中
	 * @return 结果列表
	 */
	public List list();
	
	/**
	 * 设置预编译sql
	 * @param index '?'的索引,从1开始
	 * @param value '?'的值
	 */
	public  void setString(int index,String value);
	/**
	 * 设置预编译sql
	 * @param index '?'的索引,从1开始
	 * @param value '?'的值
	 */
	public void setInt(int index,int value);
	/**
	 * 设置预编译sql
	 * @param index '?'的索引,从1开始
	 * @param value '?'的值
	 */
	public void setFloat(int index,float value);
}

 

Configuration配置类

 

/**
 * hibernate 的配置类
 * @author sky
 *
 */
public class Configuration {

	private boolean isShowSql;  				//是否显示sql语句
	private String dialect;						//连结数据库的类型
	private String driver;						//连结数据库的驱动
	private String url;							//连结数据库的url地址
	private String username;					//连结数据库的用户名
	private String password;					//连接数据库的密码
	private List<String> mapping_resource;		//pojo的映射配置文件
	private List<MappingConfiguration> mcList;	//pojo的映射配置信息列表

     /*

      上面所有属性的seter,getter方法都有
       */



	/**
	 * 读取配置文件
	 * @return this
	 */
	public Configuration configure(){
                          /*读xml*/
                          ......
               }

	/**
	 * 建立Session的工厂类
	 * @return 工厂
	 * @throws Exception 
	 */
	public SessionFactory buildSessionFactory() throws Exception{
		SessionFactory sf = SessionFactory.getSessionFactory(this);
		return sf;
	}


}

 

 还待完善

 好了,不宜将所有代码都帖上,有兴趣就下代码看看吧

 

分享到:
评论
1 楼 javafound 2010-11-12  
才看到 ,8错.

相关推荐

    JSP+Hibernate实现留言板

    总的来说,"JSP+Hibernate实现留言板"项目展示了如何利用这两项技术构建一个完整的Web应用。通过结合JSP的视图展示能力和Hibernate的数据处理能力,我们可以轻松地构建出功能强大的留言板系统,同时保持代码的可维护...

    hibernate3 最简单实现项目

    【hibernate3 最简单实现项目】 在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作。本项目基于Hibernate3,将介绍如何实现最简单的查询功能,并且提供了必要的jar包以供...

    Hibernate实现原理模拟

    Hibernate是一个开源的ORM框架,它提供了一种在Java应用中持久化对象到关系数据库的方式,通过消除手写SQL和JDBC代码,实现了Java对象和数据库记录之间的映射。Hibernate的核心组件包括配置文件、实体类、映射文件和...

    论坛系统项目(Struts 2+Hibernate+Spring实现)

    论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts...

    hibernate注册功能的实现

    在IT行业中,Web开发是关键领域之一,而Struts和Hibernate是两个非常重要的框架,用于构建动态、数据驱动的Web应用程序。在这个实例中,我们将深入探讨如何利用这两个框架实现用户注册功能,即向数据库中插入一条新...

    Spring+Hibernate实现用户登录

    本项目"Spring+Hibernate实现用户登录"旨在演示如何整合这两个框架,构建一个能够处理用户登录功能的Web应用程序。下面将详细介绍这个项目涉及的关键知识点。 1. **Spring框架**:Spring是一个全面的Java应用开发...

    struts2+hibernate实现登录及增删改操作

    综上所述,"struts2+hibernate实现登录及增删改操作"涉及到的是如何利用这两个框架构建一个完整的Java Web应用,包括用户身份验证、数据库操作以及对数据的增删改等核心功能。这个小案例可以帮助开发者理解并熟练...

    Struts和Hibernate技术实现电子商务系统(电子书)

    《Struts和Hibernate技术实现电子商务系统》一书深入探讨了如何利用Struts和Hibernate两大技术来构建高效、稳定的电子商务系统。这不仅是一本教程,更是实践者在J2EE环境下进行系统开发的宝典。 **Struts:MVC架构...

    Spring源代码解析(八):Spring驱动Hibernate的实现.doc

    在Spring框架中,整合Hibernate作为持久层解决方案是一个常见的实践。Spring通过`LocalSessionFactoryBean`类实现了对Hibernate的驱动,使得开发者能够更加灵活和方便地管理数据持久化操作。`...

    基于hibernate的简单留言本

    基于Hibernate的简单留言本是一个基本的Web应用程序,它使用Hibernate作为数据持久化层,用户可以通过该系统进行留言、查看留言以及回复等操作。这个系统展示了如何在实际项目中应用Hibernate来管理数据库交互。 ...

    基于hibernate的简单数据库实现

    **基于Hibernate的简单数据库实现** Hibernate是一个开源的对象关系映射(ORM)框架,它为Java开发者提供了方便的数据持久化服务,使得开发人员可以避免编写大量的SQL语句,从而更加专注于业务逻辑。通过Hibernate...

    基于Struts 2和Hibernate的Blog实现

    本项目利用Struts 2和Hibernate这两个流行的Java框架,实现了一个基本的博客系统。Struts 2是MVC(模型-视图-控制器)架构的一个强大实现,而Hibernate则是持久层框架,负责数据库操作。 **Struts 2框架** Struts ...

    ssh框架用struts2 hibernate实现图片的上传源码

    1. **Struts2**:Struts2是一个基于MVC设计模式的Web应用框架,它通过拦截器模型来处理用户的请求。在图片上传的场景中,Struts2提供Action类来接收用户上传的图片文件,同时可以通过配置Struts2的配置文件(struts....

    Hibernate orm 实现原理

    Hibernate orm 实现原理 主要讲解了关于hibernate 的一些知识

    山寨版当当网 struts+hibernate

    "山寨版当当网 struts+hibernate"是一个基于Struts和Hibernate框架构建的简易电子商务平台,模拟了知名电商网站当当网的部分功能。在这个项目中,开发者使用了Struts作为前端MVC(Model-View-Controller)框架,以及...

    基于SpringMVC+Hibernate实现的在线购物商城.zip

    基于springmvc+Hibernate实现的在线购物商城.zip基于springmvc+Hibernate实现的在线购物商城.zip基于springmvc+Hibernate实现的在线购物商城.zip基于springmvc+Hibernate实现的在线购物商城.zip基于springmvc+...

    hibernate+struts实现简单登录

    在IT行业中,开发Web应用程序是常见的任务之一,而"hibernate+struts实现简单登录"就是一个典型的应用场景。这个项目使用了MyEclipse作为集成开发环境,Struts作为MVC框架,以及Hibernate作为对象关系映射(ORM)...

    JAVA struts+hibernate实现的网络购物系统.zip

    JAVA struts+hibernate实现的网络购物系统JAVA struts+hibernate实现的网络购物系统JAVA struts+hibernate实现的网络购物系统JAVA struts+hibernate实现的网络购物系统JAVA struts+hibernate实现的网络购物系统JAVA ...

Global site tag (gtag.js) - Google Analytics