Spring框架——ORM


對象關系映射(Object Relational Mapping)

介紹

一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術

框架

  • Hibernate
  • Mybatis
    ....

好處

  • 通用的資源管理
  • 集成事務管理
  • 統一常見的數據訪問異常
  • 更容易測試

Spring集成Hibernate

集成思路

  1. localSessionFactoryBean作為Spring和Hibernate之間的介質,
  2. localSessionFactoryBean可以作為中轉站,被Spring管理。

注入順序

  • localSessionFactoryBean注入給DAO,
  • DAO注入給Sevice
  • Service注入給Controller

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>cakessh</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	
	<!-- 非web配置文件 -->
	<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>
	
	<!-- Dispatcher請求分發 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<!-- web相關配置文件 -->
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	<!-- 字符編碼過濾器 -->
	<!-- 解決中文亂碼 -->
	<filter>
		<filter-name>CharacterEncodingFilter</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>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- 打開一個session -->
	<filter>
		<filter-name>openSessionInView</filter-name>
		<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>openSessionInView</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

配置spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 
	<!-- 自動掃描且只掃描@Controller -->
	<context:component-scan base-package="com.cakeonline">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
	
	<!-- 注解驅動 -->
	<mvc:annotation-driven/>
	
	<!-- 靜態資源直接響應 -->
	<!-- 不需要Dispather分發 -->
    <mvc:resources location="/static/" mapping="/static/**"/>
	
	<!-- 定義JSP文件的位置 --> 
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
		
	<!-- 文件上傳 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">	
	</bean>
</beans>

配置beans.xml(applicationContext.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:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">
	<description>Spring公共配置 </description>

	<!-- 配置Spring上下文的注解 -->
	<context:annotation-config />
	<!-- 使用annotation 自動注冊bean, 並保證@Required、@Autowired的屬性被注入 -->
	<context:component-scan base-package="com.cakeonline">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	
	<!-- hibernate -->
	<!-- 屬性文件位置 -->
	<context:property-placeholder location="classpath:*.properties" />
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>


	<!-- localSessionFactoryBean -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="packagesToScan" value="com.cakeonline.entity" />
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
				<prop key="hibernate.useUnicode">${hibernate.useUnicode}</prop>
				<prop key="hibernate.characterEncoding">${hibernate.characterEncoding}</prop>
				<prop key="current_session_context_class">thread</prop>
			</props>
		</property>
	</bean>
	<!-- 使用annotation定義事務 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate5.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>

dbinfo.properties

#mysql
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/cakeonline_db?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=

#hibernate
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.format_sql=false
hibernate.useUnicode=true
hibernate.characterEncoding=utf-8

實體Bean

  • @Entity

  • @Table(name= "table_name")

  • @Id

  • @GenericGenerator(name = "myassigned", strategy = "assigned")

  • @GeneratedValue(generator = "myassigned")

自定義主鍵

代碼

@Entity
@Table(name = "tbl_user")
public class User {
	
	private String email;
	private String nickName;
	private String password;
	private Date registTime;
	
	@Id
	@GenericGenerator(name = "myassigned", strategy = "assigned")
	@GeneratedValue(generator = "myassigned")
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getNickName() {
		return nickName;
	}
	public void setNickName(String nickName) {
		this.nickName = nickName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Date getRegistTime() {
		return registTime;
	}
	public void setRegistTime(Date registTime) {
		this.registTime = registTime;
	}
	
}

DAO

  • @Repository

    • 表明是數據持久層
    • 命名方式與數據操作貼近
      • saveUser
      • updateUser
      • deleteUser
      • findByName
      • findById
  • @Resource

依賴注入的注解
依賴注入sessionFactory

  • @Id

代碼

@Repository
public class UserDaoImpl {

	@Resource
	private SessionFactory sessionFactory;
	
	/**
	 * saveUser
	 * updateUser
	 * deleteUser
	 * findByName
	 * findById
	 * @return
	 */
	
	public List<User> findAll(){
		Query query = this.sessionFactory.getCurrentSession().createQuery("from User");
		return query.list();
	}
}

Service

  • @Serviec

    • 表明是業務邏輯層
    • 命名方式與實際業務貼近
      • regist
      • login
  • @Transactional(readOnly = true)

事務

  • @Resource

依賴注入的注解
依賴注入DAO

代碼

@Service
@Transactional(readOnly = true)
public class UserServiceImpl {
	
	@Resource
	private UserDaoImpl userDaoImpl;
	/**
	 * regist
	 * login
	 * @return
	 */
	public List<User> listUsers(){
		return this.userDaoImpl.findAll();
	}
}

Controller

  • @Controller

注解表明是一個控制器

  • @RequestMapping("/controllername")

映射路徑

  • @Resource

依賴注入的注解
依賴注入Service

代碼

@Controller
@RequestMapping("/user")
public class UserController {
	
	@Resource
	private UserServiceImpl userServiceImpl;
	
	@RequestMapping("/list")
	public String list(Model model) {
		List<User> users = this.userServiceImpl.listUsers();
		model.addAttribute("users", users);
		return "list";
	}

}

過程

調用過程

  1. http請求(index.jsp)
  2. Controller控制器
  3. Service業務邏輯層
  4. DAO數據持久層
  5. sessionFactroy
  6. dataSource
  7. dbinfo.properties

依賴注入

  1. dataSource
  2. sessionFactroy
  3. DAO數據持久層
  4. Service業務邏輯層
  5. Controller控制器

數據校驗

數據校驗在項目中被廣泛應用,一般分為前端數據校驗和后端數據校驗

后端數據校驗可以采用JSR303進行數據校驗
JSR303是一個運行時數據校驗框架
它使得驗證邏輯從業務代碼中脫離出來
一般用於表單驗證

注解

注解 功能
@NotNull 注解元素必須是非空
@Null 注解元素必須是空
@Digits 驗證數字構成是否合法
@Future 驗證是否在當前系統時間之后
@Past 驗證是否在當前系統時間之前
@Max 驗證值是否小於等於最大指定整數值
@Min 驗證值是否大於等於最小指定整數值
@Pattern 驗證字符串是否匹配指定的正則表達式
@Size 驗證元素大小是否在指定范圍內
@DecimalMax 驗證值是否小於等於最大指定小數值
@DecimalMin 驗證值是否大於等於最小指定小數值
@AssertTrue 被注解的元素必須為true
@AssertFalse 被注解的元素必須為false

用法

Entity

public class User {
//	@NotEmpty(message="登錄賬號不能為空!")
	@NotEmpty
	private String loginName;
//	@Pattern(regexp="[0-9a-zA-Z]{6,30}", message="密碼是6-30個字符,必須是字母或數字組合!")
	@Pattern(regexp="[0-9a-zA-Z]{6,30}")
	private String password;
	@NotEmpty(message="郵箱不能為空!")
	@Email(message="郵件格式不正確!")
	private String email;
	@Past(message="生日不能晚於當前時間!")
	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birthday;
	@Future(message="注冊時間不能早於當前時間!")
	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
	private Date registTime;
	@DecimalMin(value="1000.00", message="工資必須大於1000")
	@DecimalMax(value="10000.00", message="工資必須小於10000")
	@NumberFormat(pattern="#,###.##")
	private Double salary;
	public String getLoginName() {
		return loginName;
	}
	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public Date getRegistTime() {
		return registTime;
	}
	public void setRegistTime(Date registTime) {
		this.registTime = registTime;
	}
	public Double getSalary() {
		return salary;
	}
	public void setSalary(Double salary) {
		this.salary = salary;
	}
	
}

Controller

method(@Valid 實體類,BindingResult bindingResult,
HttpSession session, Model model){
      if(bindingResult.hasErrors()){
            model.addAttribute("user", user);
	    return "user";
      }else{
            session.setAttribute("user", user);
	    return "center";
      }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM