1 bean容器
knight.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="com.llq.dao"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" p:dataSource-ref="dataSource">
<!-- <property name="mappingLocations">
<list>
<value>Student.hbm.xml</value>
</list>
</property> -->
<property name="packagesToScan" value="com.llq.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" p:sessionFactory-ref="sessionFactory"/>
<!-- <aop:aspectj-autoproxy proxy-target-class="true"/> -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="studentDao" class="com.llq.dao.impl.StudentDaoImpl"></bean>
</beans>
jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://10.10.82.227:3306/test
jdbc.username=root
jdbc.password=root
2 Java 代码
2.1实体类
package com.llq.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="Student")
public class Student {
private int id;
private String name;
private int age;
public Student() {
// TODO Auto-generated constructor stub
}
public Student(String name,int age) {
// TODO Auto-generated constructor stub
this.name=name;
this.age=age;
}
@Id
@Column(name="id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "name:"+name+" , age:"+age;
}
}
2.2 dao接口
package com.llq.dao.interf;
import java.util.List;
import com.llq.entity.Student;
public interface IStudentDao {
public void addStudent(Student student);
public void deleteStudent(Student student);
public Student getStudentById(int id);
public List<Student> getStudents();
}
2.3 dao实现
package com.llq.dao.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;
import com.llq.dao.interf.IStudentDao;
import com.llq.entity.Student;
@Transactional
public class StudentDaoImpl implements IStudentDao {
@Autowired
private HibernateTemplate hibernateTemplate;
@Override
public void addStudent(Student student) {
// TODO Auto-generated method stub
hibernateTemplate.save(student);
}
@Override
public void deleteStudent(Student student) {
// TODO Auto-generated method stub
hibernateTemplate.delete(student);
}
@Transactional(readOnly=true)
@Override
public Student getStudentById(int id) {
// TODO Auto-generated method stub
return hibernateTemplate.get(Student.class, id);
}
@SuppressWarnings("unchecked")
@Transactional(readOnly=true)
@Override
public List<Student> getStudents() {
// TODO Auto-generated method stub
String sql="from Student";
return hibernateTemplate.find(sql);
}
}
2.4 测试
package study.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.llq.dao.interf.IStudentDao;
import com.llq.entity.Student;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("knight.xml");
IStudentDao dao=(IStudentDao)context.getBean("studentDao");
Student student=new Student("shit",23);
dao.addStudent(student);
System.out.println(dao.getStudentById(1));
System.out.println(dao.getStudents().size());
}
}
3 需要注意的方面
3.1 测试代码中
IStudentDao dao=(IStudentDao)context.getBean("studentDao");
而不能写成:
StudentDaoImpl dao=(StudentDaoImpl)context.getBean("studentDao");
否则会提示错误:
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy11 cannot be cast to com.llq.dao.impl.StudentDaoImpl
直接原因是使用了事务,而事务是AOP的一个应用,而AOP是通过动态代理来实现的,动态代理又主要包括两种技术:JDK动态代理和CGLIB动态代理。这两种代理的适用情况和实现技术不同。上面那种错误是因为默认使用了JDK动态代理。因此解决方法主要就有两种:一种是,换成另一种CGLIB代理;另一种方法是,转型的时候强制转换成接口类型。
强制使用CGLIB代理:
<aop:config proxy-target-class="true">
详细分析请参考:
3.2 实体类中
必须要有默认的无参构造函数,否则会报错:
nested exception is org.hibernate.InstantiationException: No default constructor for entity: com.llq.entity.Student
原因分析:
简单来说就是因为hibernate使用反射来构造对象实例,会调用Class.forName("**").newInstance(),使用无参构造函数。因此我们也可以知道,当进行插入或者删除和更新时,没有无参构造器也没关系,但是,当查询一个对象时,必须要有无参构造器。
更多分析可以参考:
3.3 不使用实体类基于注解的方式,使用配置文件的方式
需要修改两个地方:
一个是sessionFactory的bean:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:dataSource-ref="dataSource">
<property name="mappingLocations">
<list>
<value>Student.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
</bean>
另一个是添加Student.hbm.xml映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.llq.entity">
<class name="Student" table="Student">
<!-- 如果是Model类和表名一样,则table属性可以省略 -->
<id name="id" column="id"></id>
<!-- 指定数据库主键, name指定Model类中的属性,column属性指定表中的列。如果是Model类属性和列名一样,则column属性可以省略 -->
<property name="name" column="name"></property><!-- 指定其他属性 -->
<property name="age" column="age"></property>
</class>
</hibernate-mapping>
3.4 几个重要的JAR包
<properties>
<spring.version>3.1.1.RELEASE</spring.version>
<hibernate.version>3.6.9.Final</hibernate.version>
</properties>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.9.0.GA</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.1_3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
</dependency>