Hibernate学习笔记(二)

一,我们来模拟hibernate的实现,首先模拟hibernate中的Session对象建立一个Session类,代码如下:

public void save(Student s) throws Exception {	
		String sql = createSQL();
		Class.forName("com.mysql.jdbc.Driver");
		Connection conn =  DriverManager.getConnection("jdbc:mysql://localhost/hibernate","root","root");
		PreparedStatement ps = conn.prepareStatement(sql);
		
		for(int i=0;i<methodNames.length;i++){
			Method m = s.getClass().getMethod(methodNames[i]);
			Class r = m.getReturnType();
			
			if(r.getName().equals("java.lang.String")){	
				String returnValue = (String)m.invoke(s);
				ps.setString(i+1, returnValue);
			}
			
			if(r.getName().equals("int")){	
				Integer returnValue = (Integer)m.invoke(s);
				ps.setInt(i+1, returnValue);
			}
			
		}
		ps.executeUpdate();
		ps.close();
		conn.close();
	}

	private String createSQL() {
		String str1 = "";
		String str2 = "";
		int index = 0;
		for(String s:cfs.keySet()){
			String v = cfs.get(s);
			v = Character.toUpperCase(v.charAt(0)) + v.substring(1);
			methodNames[index] = "get" + v;
			System.out.println(methodNames[index]);
			str1 += s + ",";
			index++;
		}
		str1 = str1.substring(0,str1.length()-1);
		
		for(int i=0;i<cfs.size();i++){
			str2 += "?,";
		}
		str2 = str2.substring(0,str2.length()-1);
		String sql = "insert into "+tableName+"(" + str1 + ")" + " values(" + str2 +");";
		System.out.println(sql);
		
		
		return sql;
	}
}

这里用到了java的反射机制,首先建立一个Map存入对应的字段名和属性名,从中取出对应的字段名拼成sql语句,然后用了PreparedStatement,后面?中的内容用到了反射。

if(r.getName().equals("java.lang.String")){	
				String returnValue = (String)m.invoke(s);
				ps.setString(i+1, returnValue);
			}

对应的测试类代码如下:

public class StudentTest {
	public static void main(String[]args) throws Exception{
		Student s = new Student();
		s.setId(2);
		s.setName("s2");
		s.setAge(2);
		
		Session session = new Session();
		session.save(s);
	}
}

 

二,Hibernate基础配置

Hibernate.cfg.xmlhbm2ddl.auto

在SessionFactory创建时,自动检查数据库结构,或者将数据库schema的DDL导出到数据库. 使用 create-drop时,在显式关闭SessionFactory时,将drop掉数据库schema. 取值 validate | update | create | create-drop

搭建日志环境并配置显示DDL语句

我们使用slf接口,然后使用log4j的实现(其实也可以用slf4j nodepjdk logging apiapach commons-logging)。

1、 首先引入log4jjar(log4j-1.2.14.jar)

2、 然后再引入slf4j实现LOG4J和适配器jar(slf4j-log4j12-1.5.8.jar)

3、 最后创建log4j的配置文件(log4j.properties),并加以修改,只要保留

log4j.logger.org.hibernate.tool.hbm2ddl=debug

   搭建Junit环境

1、首先引入Junit 类库 jar包 (junit-4.8.1.jar)

2、在项目名上右键→newSource Folder→输入名称→finish

3、注意,你对哪个包进行测试,你就在测试下建立和那个包相同的包

4、建立测试类,需要在测试的方法前面加入”@Test”

public class TeacherTest {
	
	private static SessionFactory sf = null;
	
	@BeforeClass//表示Junit此类被加载到内存中就执行这个方法
	public static void beforClass(){
		sf = new AnnotationConfiguration().configure().buildSessionFactory();
	}
	@Test//表示下面的方法是测试用的。
	public void testTeacherSave(){
		Teacher t = new Teacher();
		t.setId(6);
		t.setName("s1");
		t.setTitle("中级");
		Session session = sf.openSession();
		session.beginTransaction();
		session.save(t);
		session.getTransaction().commit();
		
		session.close();
	}
	
	@AfterClass//Junit在类结果时,自动关闭
	public static void afterClass(){
		sf.close();
	}}

Annotation

一、 表名和类名不同,对表名进行配置

Annotation:使用 @Table(name=tableName) 进行注解

/**
 * @Entity 表示下面的这个Teacher是一个实体类
 * @Table 表示映射到数据表中的表名,其中的name参数表示"表名称"
 * @Id 表示主键Id,一般放在getXXX前面
 */
@Entity
@Table(name="_teacher")
public class Teacher {
	[……]
}

Xml

<class name="Student" table="_student">

二、 字段名和属性相同

Annotation:默认为@Basic

注意:如果在成员属性没有加入任何注解,则默认在前面加入了@Basic

Xml中不用写column

三、 字段名和属性名不同

Annotation:使用@Column(name=columnName)进行注解

例如:

/**
 * @Entity 表示下面的这个Teacher是一个实体类
 * @Table 表示映射到数据表中的表名,其中的name参数表示"表名称"
 * @Column 表示实体类成员属性映射数据表中的字段名,其中name参数指定一个新的字段名
 * @Id 表示主键Id
 */
@Entity
@Table(name="_teacher")
public class Teacher {

	private int id;	
	private String name;	
	private String title;

	//设置主键使用@Id
	@Id
	public int getId() {
		return id;
	}

	@Column(name="_name")//字段名与属性不同时
	public String getName() {
		return name;
	}}

Xml

	<property name="name" column="_name"/>

四、 不需要(持久化)psersistence的字段(不重要)

就是不实体类的某个成员属性不需要存入数据库中

Annotation:使用@Transient 进行注解就可以了。

例如:

	@Transient
	public String getTitle() {
		return title;
	}

Xml:不写(就是不需要对这个成员属性进行映射)

五、 映射日期与时间类型,指定时间精度(不重要)

Annotation:使用@Temporal(value=TemporalType)来注解表示日期和时间的注解

其中TemporalType有三个值:TemporalType.TIMESTAMP 表示yyyy-MM-dd HH:mm:ss

 TemporalType.DATE表示yyyy-MM-dd

 TemporalType.TIME表示HH:mm:ss

@Temporal(value=TemporalType.DATE)
	public Date getBirthDate() {
		return birthDate;
	}

注意:当使用注解时,属性为value时,则这个属性名可以省略,例如:@Temporal(TemporalType)

Xml:使用type属性指定hibernate类型

	<property name="birthDate" type="date"/>

注意:hibernate日期时间类型有:date, time, timestamp,当然您也可以使用Java包装类。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值