一、三大架構介紹
1、sssj --》springmvc spring springjdbc(第一個項目)
2、早期:ssh (struts2 spring hibernate) 用的比較多 ,現在struts2被springmvc替代
3、中小型項目 :s s sdj(第二個項目)
springmvc spring springdatajpa(就是對jpa進行封裝) – spring全家桶
4、現在(比較流行):ssm架構(第三個或者第四項目)
springmvc+spring+mybatis
二、搭建Spring+jpa環境
步驟:
一般都是Spring和其他架構進行整合 Spring和JPA
所有配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 掃描spring service注解 repostory注解 開啟全注解-->
<context:component-scan base-package="com.cc.ssj"></context:component-scan>
<!--大的步奏:jdbc.properties dataSource EntityManagerFactory Transaction-->
<!-- 1、加載配置jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 2、配置連接配接池dataSource 加載jdbc.properties中的資訊到程式中來 -->
<!-- destroy-method="close" 目前bean銷毀的時候,會先調用close方法,關閉連接配接 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///db0731ssj"></property>
<property name="username" value="root"></property>
<property name="password" value="cc123456"></property>
</bean>
<!--3、配置EntityManagerFactory-->
<!-- 得到EntityManagerFactory:LocalContainerEntityManagerFactoryBean-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 1.注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
<!-- 2.從哪個包去掃描@Entity,domain包 -->
<property name="packagesToScan" value="com.cc.ssj.domain"></property>
<!-- 3.配置JPA的實作 -->
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--是否顯示Sql-->
<property name="showSql" value="true"></property>
<!-- 是否建立表-->
<property name="generateDdl" value="true"></property>
<!--資料庫方言-->
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"></property>
</bean>
</property>
</bean>
<!-- 事務管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<!--注入:EntityManagerFactory 好讓我們的事務去管理他-->
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 開啟事務 掃描@Transaction這種注解-->
<tx:annotation-driven/>
</beans>
1、applicationContext.xml 中Bean對象注入的順序
引用jdbc.properties–>dataSource–>EntityManagerFactory–>-->Transaction
2、配置步奏:
0、配置掃描包:掃描Spring的注解(@Service、@Repostory、等等)
1、配置:jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///db0731ssj
jdbc.username=root
jdbc.password=cc123456
2、配置連接配接池dataSource
2.1、加載jdbc.properties中的資訊到程式中來
2.2、destroy-method=“close” 目前bean銷毀的時候,會先調用close方法,關閉連接配接
3、配置EntityManagerFactory
3.1、得到:EntityManagerFactory
LocalContainerEntityManagerFactoryBean
3.2、注入 dataSource
3.3、掃描實體類的配置 @Entity—— 掃描domain包
3.4、配置JPA的實作
4、搭建三層結構
1、IProductDao(新增 修改 删除)
2、ProductDaoImpl(新增 修改 删除)
DaoImpl層:使用——>@PersistenceContext 注入EnttiyManager
//開啟dao層注解
@Repository
public class ProductDaoImpl implements IProductDao {
//注入EnttiyManager
//@Autowired 不能使用這個注入
//@PersistenceContext通過持久化上下文得到entityManager
@PersistenceContext
private EntityManager entityManager;
……增傷改查方法……}
3、IProductService
4、 ProductServiceImpl
注入的Dao的接口,以後都是了。
Service層需要處理業務——開啟事務注解
/* 處理業務:開啟事務
* Propagation.REQUIRED(常用)
表示目前方法必須運作在事務中。
Propagation.SUPPORTS(常用)
* 表示目前方法不需要事務上下文,但是如果存在目前事務的話,那麼該方法會在這個事務中運作
*/
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class ProductServiceImpl implements IProductService {
//注入Dao的接口
@Autowired
private IProductDao productDao;
/*這裡的增、删、改都是需要事務的哦!!是以再給他們單獨配置一個*/
@Transactional(propagation = Propagation.REQUIRED)
public void save(Product product) {
productDao.save(product);
}
三、Spring事務傳播機制
3.1、什麼是傳播機制
多個方法之間,比如A方法 去調用B方法 事務就可以進行互相傳播(A有事務,調用B後,B也被加起事務了)
3.2、傳播機制總共有七種:
Propagation.REQUIRED(常用)
表示目前方法必須運作在事務中。如果目前事務存在,方法将會在該事務中運作。否則,會啟動一個新的事務
Propagation.SUPPORTS(常用)
Propagation.SUPPORTS(常用)
表示目前方法不需要事務上下文,但是如果存在目前事務的話,那麼該方法會在這個事務中運作
3.3、配置及使用:
1、注入:JpaTransactionManager
<!-- 1、事務管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<!--注入:EntityManagerFactory 好讓我們的事務去管理他-->
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!-- 2、開啟事務 掃描@Transaction這種注解-->
<tx:annotation-driven/>
2、使用
如果@Transactional配置到類上面 ,類裡面方法都是用這個傳播機制 ;
如果自身的方法配置@Transactional傳播機制 方法上面就采用自己配置注解
readOnly = true 隻讀:隻允許讀取 – 查詢方法配置
@Service
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class ProductServiceImpl implements IProductService {
//注入Dao的接口
@Autowired
private IProductDao productDao;
/*這裡的增、删、改都是需要事務的哦!!是以再給他們單獨配置一個*/
@Transactional(propagation = Propagation.REQUIRED)
public void save(Product product) {
productDao.save(product);
}
四、SpringMVC+spring內建
1、配置步奏
(1)導入jar --spring-web /spring-webmvc
(2)、配置 applicationContext-MVC.xml 配置檔案
0、配置mvc命名空間(如果報紅-找不到,就把jar包删了)
1、掃描controller
2、靜态資源放行
3、 掃描@RequestMapping注解
4、視圖解析器:InternalResourceViewResolver
配置字首 字尾
5、上傳解析器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 1、掃描controller-->
<context:component-scan base-package="com.cc.ssj.web.controller"></context:component-scan>
<!-- 2、靜态資源放行-->
<mvc:default-servlet-handler/>
<!-- 3、掃描RequestMapping-->
<mvc:annotation-driven/>
<!-- 4、視圖解析器:InternalResourceViewResolver-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--5、上傳-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>${1024*1024*10}</value>
</property>
</bean>
</beans>
(3)、配置web.xml
1、核心控制器配置:DispatcherServlet
初始化:通路 classpath:applicationContext_mvc.xml 這個配置檔案
2、字元編碼過濾器:CharacterEncodingFilter
3、監聽器讀取配置
4、處理懶加載關閉問題
4.1、異常1:(JSON的對象資料傳不過去)
JsonMappingException: could not initialize proxy - no Session
LazyInitializationException: could not initialize proxy - no Session
處理方式:
延遲 entityManager 關閉(我們去取dir分類中的name的時候已經關閉了。)。
加一層過濾器(放到最上面)
4.1、異常2:沒有找到 “handler” 這個屬性
異常2:HttpMessageNotWritableException……中沒有找到 "handler" 這個屬性
1.jpa在底層延遲加載的時候額外生産了一個屬性"handler"
2.SpringMVC傳回JSON資料進行資料組裝的時候,出現沖突
處理方式:
讓SpringMVC忽略"handler" 這個屬性
在實體類中的List資料(Product中的dir屬性)上面打注解:
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
5、web.xml 所有配置:
<!-- 4、處理懶加載關閉問題 -->
<filter>
<filter-name>openEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>openEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 1、核心控制器配置-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext_mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--所有的servlet都要過-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--2、字元編碼過濾器-->
<filter>
<filter-name>characterEncoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--3、監聽器讀取配置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
(4)、配置tomCat伺服器
略……
五、前台處理資料 及 Controller層注意事項
1、Controller層注意事項
如果要傳回json資料,一定要用:@ResponseBody ——傳回json資料
2、處理資料:
注意:jsp傳回資料時,如果傳回的json資料中有Obejct對象的資料,需要:
1、在需要取值的定義一個:formatter: 函數名(cc) 屬性
2、使用JS代碼去取值即可
dir是product中的一個字段,但是是對象,是以需要這樣取值
<script type="text/javascript">
function cc (dir) {
if (dir != null) {
return dir.name;
}
}
</script>
2、處理資料:
注意:jsp傳回資料時,如果傳回的json資料中有Obejct對象的資料,需要:
1、在需要取值的定義一個:formatter: 函數名(cc) 屬性
2、使用JS代碼去取值即可
dir是product中的一個字段,但是是對象,是以需要這樣取值
<script type="text/javascript">
function cc (dir) {
if (dir != null) {
return dir.name;
}
}
</script>