前言
最近因为需求,需要接触Spring+SpringMVC+Hibernate的java框架,下面来谈谈Spring和Hibernate,以及将它们结合
开始
Hibernate
使用JDBC做数据库相关功能开发会做很多重复性的工作,比如创建连接,关闭连接,把字段逐一映射到属性中。 Hibernate把这一切都封装起来了,使得数据库访问变得轻松而简单,代码也更加容易维护。
使用起来也很简单:
1.创建一个数据库
2.创建表
3.创建一个Java Project,导入Hibernate所依赖的包
4.然后创建实体类
重点来了
5.在实体类的包中配置一个xxxx.hbm.xml文件,用于映射类对应数据库中的表。
<?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">
<hibernate-mapping package="com.how2java.pojo">
<!-- 表示类Product对应表product_ -->
<class name="Product" table="product_">
<!-- 表示属性id,映射表里的字段id -->
<id name="id" column="id">
<!--<generator class="native"> 意味着id的自增长方式采用数据库的本地方式 -->
<generator class="native">
</generator>
</id>
<property name="name" />
<property name="price" />
<many-to-one name="category" class="Category" column="cid"/>
<set name="users" table="user_product" lazy="false">
<key column="pid" />
<many-to-many column="uid" class="User" />
</set>
</class>
</hibernate-mapping>
6.然后再java的src目录下创建xxxx.cfg.xml,这个是Hibernate的配置文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- hibernate配置文件 -->
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</property>
<property name="connection.username">root</property>
<property name="connection.password">admin</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/how2java/pojo/Product.hbm.xml" />
<mapping resource="com/how2java/pojo/Category.hbm.xml" />
<mapping resource="com/how2java/pojo/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
7.最后编写测试类
测试基本步骤是:
1. 获取SessionFactory
2. 通过SessionFactory 获取一个Session
3. 在Session基础上开启一个事务
4. 通过调用Session的save方法把对象保存到数据库
5. 提交事务
6. 关闭Session
7. 关闭SessionFactory
package com.how2java.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Category;
import com.how2java.pojo.Product;
import com.how2java.pojo.User;
public class TestHibernate {
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
//hibernate中的事务由s.beginTransaction();开始
s.beginTransaction();
/*插入
for(int i=0;i<10;i++) {
Product p = new Product();
p.setName("iphone"+i);
p.setPrice(i);
s.save(p);
}
*/
/*new 了一个Product();,在数据库中还没有对应的记录,这个时候Product对象的状态是瞬时的。
通过Session的save把该对象保存在了数据库中,
该对象也和Session之间产生了联系,此时状态是持久的。
最后把Session关闭了,这个对象在数据库中虽然有对应的数据,
但是已经和Session失去了联系,相当于脱离了管理,状态就是脱管的
Product p = new Product();
p.setName("p1");
System.out.println("此时p是瞬时状态");
s.save(p);
System.out.println("此时p是持久状态");
s.getTransaction().commit();
s.close();
System.out.println("此时p是脱管状态");
sf.close();
调用Session的get方法,根据id获取对象。 除了id之外,还需要传递一个类对象,
毕竟需要知道获取的是哪个对象
除了使用get方法,还可以使用load获取对象。 请参考get和load的区别
Product p =(Product) s.get(Product.class, 6);
System.out.println("id=6的产品名称是: "+p.getName());
删除一条数据
s.delete(p);
修改数据
System.out.println(p.getName());
p.setName("iphone-modified");
s.update(p);
TestHibernate 测试many-to-one关系
Category c =new Category();
c.setName("c1");
s.save(c);
Product p = (Product) s.get(Product.class, 8);
p.setCategory(c);
s.update(p);
TestHibernate 测试one-to-many关系
Category c = (Category) s.get(Category.class, 1);
Set<Product> ps = c.getProducts();
for (Product p : ps) {
System.out.println(p.getName());
}
*/
//TestHibernate 测试many-to-many关系
//增加3个用户
Set<User> users = new HashSet();
for (int i = 0; i < 3; i++) {
User u =new User();
u.setName("user"+i);
users.add(u);
s.save(u);
}
//产品1被用户1,2,3购买
Product p1 = (Product) s.get(Product.class, 1);
p1.setUsers(users);
s.save(p1);
//hibernate中的事务由s.getTransaction().commit();结束
//在同一个事务中执行的操作,一方失败,则全部失败。
//因为这两个操作都是在一个事务中,而且第二个操作失败了,所以最后的结果是两个操作都没有生效
//在Mysql中,只有当表的类型是INNODB的时候,才支持事务,所以需要把表的类型设置为INNODB,否则无法观察到事务.
s.getTransaction().commit();
s.close();
sf.close();
}
}
Spring
Spring是一个基于IOC和AOP的结构J2EE系统的框架
IOC 反转控制 是Spring的基础,Inversion Of Control
简单说就是创建对象由以前的程序员自己new 构造方法来调用,变成了交由Spring创建对象
DI 依赖注入 Dependency Inject. 简单地说就是拿到的对象的属性,已经被注入好相关值了,直接使用即可。
原理:
以获取对象的方式来进行比较
传统的方式:
通过new 关键字主动创建一个对象
IOC方式
对象的生命周期由Spring来管理,直接从Spring那里去获取一个对象。 IOC是反转控制 (Inversion Of Control)的缩写,就像控制权从本来在自己手里,交给了Spring。
打个比喻:
传统方式:相当于你自己去菜市场new 了一只鸡,不过是生鸡,要自己拔毛,去内脏,再上花椒,酱油,烤制,经过各种工序之后,才可以食用。
用 IOC:相当于去馆子(Spring)点了一只鸡,交到你手上的时候,已经五味俱全,你就只管吃就行了。
传统方式获取对象:Person p = new Person();
使用IOC方式获取:Person p = Spring 生产
怎么使用呢?
1.创建一个Java Project,导入Spring所依赖的包
2.然后创建实体类
重点来了:
3.在src目录下新建applicationContext.xml文件,applicationContext.xml是Spring的核心配置文件,通过关键字c即可获取Category对象,该对象获取的时候,即被注入了字符串”category 1“到name属性中,这种注入用value
注入对象时使用ref
嗯,这就是所谓的注入
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean name="c" class="com.how2java.pojo.Category">
<property name="name" value="category 1" />
</bean>
</beans>
4.测试
c对象的name属性被注入了category1
package com.how2java.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.how2java.pojo.Category;
public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
Category c = (Category) context.getBean("c");
System.out.println(c.getName());
}
}
Spring+Hibernate
1.创建一个java project
2.导入相关的包
3.准备一个实体类
package com.how2java.pojo;
public class Category {
private int id;
private String name;
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;
}
}
4.准备一个xxxx.hbm.xml文件,用于映射类对应数据库中的表。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.how2java.pojo">
<class name="Category" table="category_">
<id name="id" column="id">
<generator class="native">
</generator>
</id>
<property name="name" />
</class>
</hibernate-mapping>
5.准备一个DAO层,DAO继承HibernateTemplete,而HibernateTemplete类里有一个setSessionFactory用于接收sessionFactory的注入
package com.how2java.dao;
import org.springframework.orm.hibernate3.HibernateTemplate;
public class CategoryDAO extends HibernateTemplate {
}
6.准备Spring的核心配置文件applicationContext.xml,位置当然是src目录下,两个框架整合时,原来Hibernate的cfg文件的配置就在这个文件里面注入了…
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean name="c" class="com.how2java.pojo.Category">
<property name="name" value="yyy" />
</bean>
<bean name="dao" class="com.how2java.dao.CategoryDAO">
<property name="sessionFactory" ref="sf" />
</bean>
<bean name="sf"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="ds" />
<property name="mappingResources">
<list>
<value>com/how2java/pojo/Category.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
</value>
</property>
</bean>
<bean name="ds"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=GBK" />
<property name="username" value="root" />
<property name="password" value="admin" />
</bean>
</beans>
7.然后就是测试了,测试查询,增,删,改。
package com.how2java.test;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.how2java.dao.CategoryDAO;
import com.how2java.pojo.Category;
public class TestSpring {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
CategoryDAO dao = (CategoryDAO) context.getBean("dao");
Category c = new Category();
c.setName("category yyy");
//增加
dao.save(c);
//获取
Category c2 = dao.get(Category.class, 1);
//修改
//c2.setName("category zzz");
//dao.update(c2);
//删除
//dao.delete(c2);
}
}