模拟Hibernate动态生成SQL语句

时间:2023-03-09 04:07:05
模拟Hibernate动态生成SQL语句

这里有一个xml配置文件,也就是Hibernate框架中会用到的POJO和数据库的映射文件

 <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="hp.pojo.Member" table="member" catalog="hedb">
<id name="mid" type="java.lang.String">
<column name="mid" length="50" />
<generator class="assigned"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name" length="50" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<property name="salary" type="java.lang.Double">
<column name="salary" precision="22" scale="0" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="0" />
</property>
<property name="note" type="java.lang.String">
<column name="note" length="65535" />
</property>
</class>
</hibernate-mapping>

POJO类如下:

 package hp.pojo;

 import java.util.Date;

 /**
* Member entity. @author MyEclipse Persistence Tools
*/ @SuppressWarnings("serial")
public class Member implements java.io.Serializable
{ // Fields private String mid;
private String name;
private Integer age;
private Double salary;
private Date birthday;
private String note; // Constructors /** default constructor */
public Member()
{
} /** minimal constructor */
public Member(String mid)
{
this.mid = mid;
} /** full constructor */
public Member(String mid, String name, Integer age, Double salary, Date birthday, String note)
{
this.mid = mid;
this.name = name;
this.age = age;
this.salary = salary;
this.birthday = birthday;
this.note = note;
} // Property accessors public String getMid()
{
return this.mid;
} public void setMid(String mid)
{
this.mid = mid;
} public String getName()
{
return this.name;
} public void setName(String name)
{
this.name = name;
} public Integer getAge()
{
return this.age;
} public void setAge(Integer age)
{
this.age = age;
} public Double getSalary()
{
return this.salary;
} public void setSalary(Double salary)
{
this.salary = salary;
} public Date getBirthday()
{
return this.birthday;
} public void setBirthday(Date birthday)
{
this.birthday = birthday;
} public String getNote()
{
return this.note;
} public void setNote(String note)
{
this.note = note;
} }

下面代码演示了利用反射以及XML解析,动态生成SQL语句,并且利用JDBC技术执行SQL语句的过程:

 package hp.test;

 import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Date;
import java.util.List; import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; import com.mysql.jdbc.PreparedStatement; public class MyHibernate
{
private class Column
{
private String name;
private String length;
} private class Generator
{
private String type;
} private class Id
{
private String name;
private String type; private Column column;
private Generator generator;
}
private class Property
{
private String name;
private String type;
private Column column;
} private class Class
{
private String name;
private String table;
private String catalog; private Id id;
private List<Property> allProperties;
}
private class KeyValuePair
{
private String type;
private Object value; private KeyValuePair(String type,Object value)
{
this.type = type;
this.value = value;
}
} private String configPath ;
private Object obj = null;
private Document document;
private Class voClass ;
private String sql;
private List<KeyValuePair> allValues; public MyHibernate(String configPath)
{
this.configPath = configPath;
} public int save(Object obj) throws Exception
{
this.obj = obj;
this.load();
this.format();
this.generateSql();
return this.saveToDb();
} public void load() throws Exception
{
SAXReader saxReader = new SAXReader();
this.document = saxReader.read(new File(this.configPath));
}
public void format() throws Exception
{
Class _class = new Class();
org.dom4j.Element root = this.document.getRootElement();
Element classElement = root.element("class");
_class.name = classElement.attributeValue("name");
_class.table = classElement.attributeValue("table");
_class.catalog = classElement.attributeValue("catalog"); Element idElement = classElement.element("id");
_class.id = new Id();
_class.id.name = idElement.attributeValue("name");
_class.id.type = idElement.attributeValue("type"); Element columnElementInId = idElement.element("column");
_class.id.column = new Column();
_class.id.column.name = columnElementInId.attributeValue("name");
_class.id.column.length = columnElementInId.attributeValue("length"); Element generatorElement = idElement.element("generator");
_class.id.generator = new Generator();
_class.id.generator.type = generatorElement.attributeValue("class"); List<Property> allProperties = new ArrayList<MyHibernate.Property>();
_class.allProperties = allProperties; List<Element> allPropertiesElements = classElement.elements("property");
for(Element item : allPropertiesElements)
{
Property property = new Property();
property.name = item.attributeValue("name");
property.type = item.attributeValue("type"); Element columnElement = item.element("column");
property.column = new Column();
property.column.name = columnElement.attributeValue("name");
property.column.length = columnElement.attributeValue("length");
allProperties.add(property);
//System.out.println("name: " + property.name);
}
this.voClass = _class;
} public void generateSql() throws Exception
{
this.allValues = new ArrayList<MyHibernate.KeyValuePair>();
StringBuffer columns = new StringBuffer();
StringBuffer values = new StringBuffer();
StringBuffer sql = new StringBuffer(" INSERT INTO ");
sql.append(this.voClass.table).append("( "); if("assigned".equals(this.voClass.id.generator.type))
{
//需要用户提供主键列
columns.append(this.voClass.id.column.name).append(",");
values.append("?,"); Field field = this.obj.getClass().getDeclaredField(this.voClass.id.name);
field.setAccessible(true);
this.allValues.add(new KeyValuePair(this.voClass.id.type, field.get(this.obj)));
} for(Property property : this.voClass.allProperties)
{
columns.append(property.column.name).append(",");
values.append("?,"); Field field = this.obj.getClass().getDeclaredField(property.name);
field.setAccessible(true);
this.allValues.add(new KeyValuePair(property.type, field.get(this.obj)));
} columns.delete(columns.length()-1, columns.length());
values.delete(values.length()-1, columns.length()); sql.append(columns.toString()).append(") VALUES (");
sql.append(values.toString()).append(")");
this.sql = sql.toString();
System.out.println(this.sql);
} public int saveToDb() throws Exception
{
java.lang.Class.forName("org.gjt.mm.mysql.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hedb", "root", "admin");
java.sql.PreparedStatement ps = conn.prepareStatement(this.sql); for(int i = 0; i < this.allValues.size(); i++)
{
//System.out.println("***type:" + this.allValues.get(i).type);
if(String.class.getName().toString().equals(this.allValues.get(i).type))
{
ps.setString(i+1, (String)this.allValues.get(i).value);
}
else if(Integer.class.getName().toString().equals(this.allValues.get(i).type))
{
ps.setInt(i+1, (Integer)this.allValues.get(i).value);
}else if(Double.class.getName().toString().equals(this.allValues.get(i).type))
{
ps.setDouble(i+1, (Double)this.allValues.get(i).value);
}else if(Date.class.getName().toString().equals(this.allValues.get(i).type))
{
ps.setDate(i+1, new java.sql.Date(((Date)this.allValues.get(i).value).getTime()));
} //System.out.println("设置第" + (i+1) + "个值("+this.allValues.get(i).type+","+this.allValues.get(i).value+")");
}
return ps.executeUpdate(); }
}

测试代码:

 package hp.test;

 import java.util.Date;

 import org.hibernate.Session;
import org.hibernate.SessionFactory; import hp.pojo.Member;
import hp.utils.HibernateHelper; public class Main
{ public static void main(String[] args)
{
Member vo = new Member();
vo.setMid("admin4");
vo.setAge(24);
vo.setBirthday(new Date());
vo.setName("sheldon4");
vo.setNote("a good person4");
vo.setSalary(44444.44); try
{
MyHibernate mh = new MyHibernate("C:\\D\\code\\resource\\mapping.xml");
int count = mh.save(vo);
System.out.println("成功插入" + count + "行数据");
}
catch(Exception e)
{
e.printStackTrace(); }
System.out.println("main done//~");
} }