java框架之Spring(4)-Spring整合Hibernate和Struts2
准备
导包
Struts2
导入 Struts2 zip 包解压目录下 'apps/struts-blank.war' 中所有 jar 包,如下:
asm-3.3.jar asm-commons-3.3.jar asm-tree-3.3.jar commons-fileupload-1.4.jar commons-io-2.2.jar commons-lang3-3.2.jar freemarker-2.3.28.jar javassist-3.11.0.GA.jar log4j-api-2.3.jar # 可选 log4j-core-2.3.jar # 可选 ognl-3.0.21.jar struts2-core-2.3.37.jar xwork-core-2.3.37.jar
另外导入 lib 下如下包:
struts2-convention-plugin-2.3.37.jar # Struts2 注解开发包 struts2-json-plugin-2.3.37.jar # Struts2 内置 Json 序列化支持包 struts2-spring-plugin-2.3.37.jar # Struts2 整合 Spring 包
Hibernate
首先是 Hibernate 开发的必须包,即 Hibernate zip 包 解压目录下 'lib/required' 下所有的包,如下:
antlr-2.7.7.jar dom4j-1.6.1.jar geronimo-jta_1.1_spec-1.1.1.jar hibernate-commons-annotations-5.0.1.Final.jar hibernate-core-5.0.7.Final.jar hibernate-jpa-2.1-api-1.0.0.Final.jar jandex-2.0.0.Final.jar javassist-3.18.1-GA.jar jboss-logging-3.3.0.Final.jar
Strut2 和 Hibernate 都引入了一个相同的 jar 包 javassisit,整合时必须只保留一个。
还需导入日志记录包:
log4j-1.2.16.jar slf4j-api-1.6.1.jar slf4j-log4j12-1.7.2.jar
如果使用这里的日志记录包,那么 Struts2 包中两个可选日志记录包就不需要引入。
如果 Hibernate 要使用 C3P0 连接池,还需引入 'lib\optional\c3p0' 下所有包,如下:
c3p0-0.9.2.1.jar hibernate-c3p0-5.0.7.Final.jar mchange-commons-java-0.2.3.4.jar
当然,使用 Hibernate 还需要数据库驱动包,这里我使用 MySQL 驱动包:
mysql-connector-java-5.1.7-bin.jar
Spring
使用 IoC 需引入的包:
com.springsource.org.apache.commons.logging-1.1.1.jar com.springsource.org.apache.log4j-1.2.15.jar spring-beans-4.2.4.RELEASE.jar spring-context-4.2.4.RELEASE.jar spring-core-4.2.4.RELEASE.jar spring-expression-4.2.4.RELEASE.jar
使用 AOP 需引入的包:
com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aop-4.2.4.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar
使用 JDBC 模板需引入的包:
spring-jdbc-4.2.4.RELEASE.jar spring-tx-4.2.4.RELEASE.jar
使用事务管理需引入的包:
spring-tx-4.2.4.RELEASE.jar
整合 web 项目需引入的包:
spring-web-4.2.4.RELEASE.jar
整合单元测试测试需引入的包:
spring-test-4.2.4.RELEASE.jar
整合 ORM 框架 Hibernate 需引入的包:
spring-orm-4.2.4.RELEASE.jar
配置
Struts2
配置 Struts2 的核心过滤器:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
WEB-INF/web.xml
引入 Struts2 核心配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="test" extends="struts-default" namespace="/"> </package> </struts>
struts.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-configuration> <session-factory> <!-- 连接数据库的基本参数 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 配置Hibernate的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 可选配置================ --> <!-- 打印SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- 自动创建表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置C3P0连接池 --> <property name="connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property> <!--在连接池中可用的数据库连接的最少数目 --> <property name="c3p0.min_size">5</property> <!--在连接池中所有数据库连接的最大数目 --> <property name="c3p0.max_size">20</property> <!--设定数据库连接的过期时间,以秒为单位, 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 --> <property name="c3p0.timeout">120</property> <!--每3000秒检查所有连接池中的空闲连接 以秒为单位--> <property name="c3p0.idle_test_period">3000</property> </session-factory> </hibernate-configuration>
hibernate.cfg.xml
Spring
配置 Spring 的核心监听器:
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--默认情况下 Spring 会查找路径为 WEB-INF/applicationContext.xml 的配置文件,通过如下配置,让 Spring 在 classpath 下查找--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
WEB-INF/web.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- Spring整合Hibernate --> <!-- 引入Hibernate的配置的信息=============== --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- 引入hibernate的配置文件 --> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
applicationContext.xml
Log4j 配置:
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### # error warn info debug trace log4j.rootLogger= info, stdout
log4j.properties
代码
package com.zze.domain; public class User { private Integer id; private String name; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
com.zze.domain.User
package com.zze.dao; import com.zze.domain.User; public interface UserDao { void save(User user); }
com.zze.dao.UserDao
package com.zze.dao.impl; import com.zze.dao.UserDao; import com.zze.domain.User; public class UserDaoImpl implements UserDao { @Override public void save(User user) { } }
com.zze.dao.impl.UserDaoImpl
package com.zze.service; import com.zze.domain.User; public interface UserService { void save(User user); }
com.zze.service.UserService
package com.zze.service.impl; import com.zze.dao.UserDao; import com.zze.domain.User; import com.zze.service.UserService; public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save(User user) { userDao.save(user); } }
com.zze.service.impl.UserServiceImpl
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } }
com.zze.web.action.UserAction
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean name="userService" class="com.zze.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean> <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl"> </bean> </beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="test" extends="struts-default" namespace="/"> <action name="customer_*" class="com.zze.web.action.UserAction" method="{1}"> </action> </package> </struts>
struts.xml
Spring整合Struts2
方式一:Action由Struts2自身创建
在 Action 中我们会调用业务层代码,如果按照传统方式,我们要获取到业务类实例,需要通过 Spring 工厂来手动获取,如下:
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; import com.zze.service.UserService; import org.apache.struts2.ServletActionContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } public String save() { //传统方式获取 Service WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); UserService userService = (UserService) applicationContext.getBean("userService"); System.out.println(userService); /* 访问 http://localhost:8080/customer_save,输出结果如下: com.zze.service.impl.UserServiceImpl@4b65044b */ return NONE; } }
com.zze.web.action.UserAction
而这种方式的代码显然过于复杂,Struts2 在与 Spring 整合时 Struts2 还为我们提供了更简易的方式哦。
Spring 整合 Struts2 需要引入一个 jar 包 struts2-spring-plugin.jar,这个 jar 包在上述准备工作中就已经引入,查看该 jar 中的 struts-plugin.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!-- /* * $Id$ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" /> <!-- Make the Spring object factory the automatic default --> <constant name="struts.objectFactory" value="spring" /> <constant name="struts.class.reloading.watchList" value="" /> <constant name="struts.class.reloading.acceptClasses" value="" /> <constant name="struts.class.reloading.reloadConfig" value="false" /> <constant name="xwork.disallowProxyMemberAccess" value="true" /> <package name="spring-default"> <interceptors> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> </interceptors> </package> </struts>
struts2-spring-plugin-2.3.37.jar!/struts-plugin.xml
可以看到在该文件中配置了如下常量:
<constant name="struts.objectFactory" value="spring" />
查看 Struts2 的默认配置:
# # $Id$ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ### START SNIPPET: complete_file ### Struts default properties ###(can be overridden by a struts.properties file in the root of the classpath) ### ### This can be used to set your default locale and encoding scheme # struts.locale=en_US struts.i18n.encoding=UTF-8 ### if specified, the default object factory can be overridden here ### Note: short-hand notation is supported in some cases, such as "spring" ### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here # struts.objectFactory = spring ### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name ### indicates to the struts-spring integration if Class instances should be cached ### this should, until a future Spring release makes it possible, be left as true ### unless you know exactly what you are doing! ### valid values are: true, false (true is the default) struts.objectFactory.spring.useClassCache = true ### ensures the autowire strategy is always respected. ### valid values are: true, false (false is the default) struts.objectFactory.spring.autoWire.alwaysRespect = false ### By default SpringObjectFactory doesn't support AOP ### This flag was added just temporally to check if nothing is broken ### See https://issues.apache.org/jira/browse/WW-4110 struts.objectFactory.spring.enableAopSupport = false ### if specified, the default object type determiner can be overridden here ### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger" ### Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation name here ### Note: By default, com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer is used which handles type detection ### using generics. com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer was deprecated since XWork 2, it's ### functions are integrated in DefaultObjectTypeDeterminer now. ### To disable tiger support use the "notiger" property value here. #struts.objectTypeDeterminer = tiger #struts.objectTypeDeterminer = notiger ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data # struts.multipart.parser=cos # struts.multipart.parser=pell # struts.multipart.parser=jakarta-stream struts.multipart.parser=jakarta # uses javax.servlet.context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize=2097152 ### Load custom property files (does not override struts.properties!) # struts.custom.properties=application,org/apache/struts2/extension/custom ### How request URLs are mapped to and from actions #struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper ### Used by the DefaultActionMapper ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do ### The blank extension allows you to match directory listings as well as pure action names ### without interfering with static resources, which can be specified as an empty string ### prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,, struts.action.extension=action,, ### Used by FilterDispatcher ### If true then Struts serves static content from inside its jar. ### If false then the static content must be available at <context_path>/struts struts.serve.static=true ### Used by FilterDispatcher ### This is good for development where one wants changes to the static content be ### fetch on each request. ### NOTE: This will only have effect if struts.serve.static=true ### If true -> Struts will write out header for static contents such that they will ### be cached by web browsers (using Date, Cache-Content, Pragma, Expires) ### headers). ### If false -> Struts will write out header for static contents such that they are ### NOT to be cached by web browser (using Cache-Content, Pragma, Expires ### headers) struts.serve.static.browserCache=true ### Set this to false if you wish to disable implicit dynamic method invocation ### via the URL request. This includes URLs like foo!bar.action, as well as params ### like method:bar (but not action:foo). ### An alternative to implicit dynamic method invocation is to use wildcard ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}"> struts.enable.DynamicMethodInvocation = false ### Set this to true if you wish to allow slashes in your action names. If false, ### Actions names cannot have slashes, and will be accessible via any directory ### prefix. This is the traditional behavior expected of WebWork applications. ### Setting to true is useful when you want to use wildcards and store values ### in the URL, to be extracted by wildcard patterns, such as ### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or ### "/foo/save". struts.enable.SlashesInActionNames = false ### Disables support for action: prefix struts.mapper.action.prefix.enabled = false ### Blocks access to actions in other namespace than current with action: prefix struts.mapper.action.prefix.crossNamespaces = false ### use alternative syntax that requires %{} in most places ### to evaluate expressions for String attributes for tags struts.tag.altSyntax=true ### when set to true, Struts will act much more friendly for developers. This ### includes: ### - struts.i18n.reload = true ### - struts.configuration.xml.reload = true ### - raising various debug or ignorable problems to errors ### For example: normally a request to foo.action?someUnknownField=true should ### be ignored (given that any value can come from the web and it ### should not be trusted). However, during development, it may be ### useful to know when these errors are happening and be told of ### them right away. struts.devMode = false ### when set to true, resource bundles will be reloaded on _every_ request. ### this is good during development, but should never be used in production ### struts.i18n.reload=false ### Standard UI theme ### Change this to reflect which path should be used for JSP control tag templates by default struts.ui.theme=xhtml struts.ui.templateDir=template ### Change this to use a different token to indicate template theme expansion struts.ui.theme.expansion.token=~~~ #sets the default template type. Either ftl, vm, or jsp struts.ui.templateSuffix=ftl ### Configuration reloading ### This will cause the configuration to reload struts.xml when it is changed ### struts.configuration.xml.reload=false ### Location of velocity.properties file. defaults to velocity.properties struts.velocity.configfile = velocity.properties ### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext struts.velocity.contexts = ### Location of the velocity toolbox struts.velocity.toolboxlocation= ### used to build URLs, such as the UrlTag struts.url.http.port = 80 struts.url.https.port = 443 ### possible values are: none, get or all struts.url.includeParams = none ### Load custom default resource bundles # struts.custom.i18n.resources=testmessages,testmessages2 ### workaround for some app servers that don't handle HttpServletRequest.getParameterMap() ### often used for WebLogic, Orion, and OC4J struts.dispatcher.parametersWorkaround = false ### configure the Freemarker Manager class to be used ### Allows user to plug-in customised Freemarker Manager if necessary ### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager #struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager ### Enables caching of FreeMarker templates ### Has the same effect as copying the templates under WEB_APP/templates ### struts.freemarker.templatesCache=false ### Enables caching of models on the BeanWrapper struts.freemarker.beanwrapperCache=false ### See the StrutsBeanWrapper javadocs for more information struts.freemarker.wrapper.altMap=true ### maxStrongSize for MruCacheStorage for freemarker, when set to 0 SoftCacheStorage which performs better in heavy loaded application ### check WW-3766 for more details struts.freemarker.mru.max.strong.size=0 ### configure the XSLTResult class to use stylesheet caching. ### Set to true for developers and false for production. struts.xslt.nocache=false ### Whether to always select the namespace to be everything before the last slash or not struts.mapper.alwaysSelectFullNamespace=false ### Whether to allow static method access in OGNL expressions or not struts.ognl.allowStaticMethodAccess=false ### Whether to throw a RuntimeException when a property is not found ### in an expression, or when the expression evaluation fails struts.el.throwExceptionOnFailure=false ### Logs as Warnings properties that are not found (very verbose) struts.ognl.logMissingProperties=false ### Caches parsed OGNL expressions, but can lead to memory leaks ### if the application generates a lot of different expressions struts.ognl.enableExpressionCache=true ### Indicates if Dispatcher should handle unexpected exceptions by calling sendError() ### or simply rethrow it as a ServletException to allow future processing by other frameworks like Spring Security struts.handle.exception=true ### END SNIPPET: complete_file
struts2-core-2.3.37.jar!/org/apache/struts2/default.properties
在第 34 行可以看到,该常量默认是关闭的,而该常量只要开启,第 38 行的常量就会生效:
### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name
而该配置的作用就是让 Action 可以按照变量名称自动注入 Spring 工厂中管理的实例,所以业务类实例还可通过如下方式获取:
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; import com.zze.service.UserService; public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } public String save() { System.out.println(userService); /* 访问 http://localhost:8080/customer_save,输出结果如下: com.zze.service.impl.UserServiceImpl@389b9f55 */ return NONE; } }
com.zze.web.action.UserAction
方式二:Action由Spring创建
修改配置:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 让 Spring 来创建 Action 实例 注意,Action 类要配置为多例 --> <bean name="userAction" class="com.zze.web.action.UserAction" scope="prototype"> <property name="userService" ref="userService"/> </bean> <bean name="userService" class="com.zze.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean> <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl"> </bean> </beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="test" extends="struts-default" namespace="/"> <!-- 修改 class 对应 applicationContext.xml 中 bean 的名称 (id/name) --> <action name="customer_*" class="userAction" method="{1}"> </action> </package> </struts>
struts.xml
测试:
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; import com.zze.service.UserService; public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } public String save() { System.out.println(userService); /* 访问 http://localhost:8080/customer_save,输出结果如下: com.zze.service.impl.UserServiceImpl@4f543a20 */ return NONE; } }
com.zze.web.action.UserAction
Spring整合Hibernate
方式一:保留Hibernate配置文件
编写实体映射文件:
<?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> <class name="com.zze.domain.User" table="user"> <id name="id" column="id"> <generator class="native"/> </id> <property name="name" column="name" length="32"/> <property name="age" column="age"/> </class> </hibernate-mapping>
com/zze/domain/User.hbm.xml
在 Hibernate 核心配置文件中引入实体映射文件:
<mapping resource="com/zze/domain/User.hbm.xml"/>
hibernate.cfg.xml
修改 Dao 代码:
package com.zze.dao.impl; import com.zze.dao.UserDao; import com.zze.domain.User; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; // 使用 Hibernate 提供的 Dao 模板类 public class UserDaoImpl extends HibernateDaoSupport implements UserDao { @Override public void save(User user) { this.getHibernateTemplate().save(user); } }
com.zze.dao.impl.UserDaoImpl
将 Hibernate 的核心工厂类实例交给 Spring 创建:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--Spring 整合 Hibernate--> <!--引入 Hibernate 配置信息--> <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> </bean> <!-- <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"/> </bean> --> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--Spring 整合 Struts2--> <!-- 让 Spring 来创建 Action 实例 注意,Action 类要配置为多例 --> <bean name="userAction" class="com.zze.web.action.UserAction" scope="prototype"> <property name="userService" ref="userService"/> </bean> <bean name="userService" class="com.zze.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean> <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> <!-- <property name="hibernateTemplate" ref="hibernateTemplate"/> --> </bean> </beans>
applicationContext.xml
测试:
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; import com.zze.service.UserService; public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } public String save() { userService.save(user); return NONE; } }
com.zze.web.action.UserAction
方式二:去除Hibernate配置文件
新建数据库连接信息属性文件:
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///test jdbc.username=root jdbc.password=root
jdbc.properties
删除 Hibernate 配置文件 hibernate.cfg.xml,在 Spring 配置文件中完成 Hibernate 相关配置:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <!--配置 C3P0 数据源--> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!--Spring 整合 Hibernate--> <!--引入 Hibernate 配置信息--> <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- 注入连接池 --> <property name="dataSource" ref="dataSource"/> <!-- 配置Hibernate的相关属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <!-- 设置映射文件 --> <property name="mappingResources"> <list> <value>com/zze/domain/User.hbm.xml</value> </list> </property> </bean> <!-- <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"/> </bean> --> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--Spring 整合 Struts2--> <!-- 让 Spring 来创建 Action 实例 注意,Action 类要配置为多例 --> <bean name="userAction" class="com.zze.web.action.UserAction" scope="prototype"> <property name="userService" ref="userService"/> </bean> <bean name="userService" class="com.zze.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean> <bean name="userDao" class="com.zze.dao.impl.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> <!-- <property name="hibernateTemplate" ref="hibernateTemplate"/> --> </bean> </beans>
applicationContext.xml
测试:
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; import com.zze.service.UserService; public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } public String save() { userService.save(user); return NONE; } }
com.zze.web.action.UserAction
补充
延迟加载问题
Hibernate 是有延迟加载策略的,Spring 整合 Hibernate 后,session 的是由 Spring 管理的。当我们做一个有延迟加载的查询操作时,默认情况下在 service 层已经完成了 session 的开启与关闭操作,所以如果我们要在 web 层使用延迟加载,此时 session 是关闭的状态,会抛出如下异常:
对于这个问题 Spring 也给我们提供了解决方案,只需要配置上它提供的一个过滤器即可,如下:
<filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
WEB-INF/web.xml
抽取通用Dao
package com.zze.dao; import org.hibernate.criterion.DetachedCriteria; import java.io.Serializable; import java.util.List; public interface BaseDao<T> { /** * 保存操作 * * @param model 要保存的模型 */ void save(T model); /** * 更新操作 * * @param model 要更新的模型 */ void update(T model); /** * 删除操作 * * @param id 删除的 id */ void delete(Serializable id); /** * 通过 id 查询单个对象 * * @param id 要删除数据主键 * @return 返回 id 对应的单个对象 */ T findById(Serializable id); /** * 查询所有数据 * * @return 以 List 方式返回所有数据 */ List<T> findAll(); /** * 查询数据条数 * * @param detachedCriteria 离线查询对象 * @return 数据条数 */ Serializable findCount(DetachedCriteria detachedCriteria); /** * 分页查询 * * @param detachedCriteria 离线查询对象 * @param begin 数据起始索引 * @param pageSize 每页数据条数 * @return 返回分页的珊瑚橘 */ List<T> findPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize); }
com.zze.dao.BaseDao
package com.zze.dao.impl; import com.zze.dao.BaseDao; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projections; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { private Class clazz; public BaseDaoImpl() { /* 例: class UserDaoImpl extends BaseDaoImpl<User> */ // 获取到运行时实际类 UserDaoImpl Class<? extends BaseDaoImpl> actualClass = this.getClass(); // 获取到实际类父类 BaseDaoImpl<User> Type genericSuperclass = actualClass.getGenericSuperclass(); // 转为参数化类型 ParameterizedType type = (ParameterizedType) genericSuperclass; // 获取类型化参数 User Type[] actualTypeArguments = type.getActualTypeArguments(); this.clazz = (Class) actualTypeArguments[0]; } @Override public void save(T model) { this.getHibernateTemplate().save(model); } @Override public void update(T model) { this.getHibernateTemplate().update(model); } @Override public void delete(Serializable id) { this.getHibernateTemplate().delete(id); } @Override public T findById(Serializable id) { return (T) this.getHibernateTemplate().get(clazz, id); } @Override public List<T> findAll() { return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName()); } @Override public Serializable findCount(DetachedCriteria detachedCriteria) { detachedCriteria.setProjection(Projections.rowCount()); List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria); return list.size() > 0 ? list.get(0).intValue() : null; } @Override public List<T> findPage(DetachedCriteria detachedCriteria,Integer begin,Integer pageSize) { detachedCriteria.setProjection(null); return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize); } }
com.zze.dao.impl.BaseDaoImpl
SSH注解整合
1、导包,同上述准备工作中包。
2、配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--Struts2 过滤器--> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--Spring 核心监听器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--配置 Spring 配置文件加载路径,默认加载 WEB-INF/applicationContext.xml--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> </web-app>
WEB-INF/web.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <!--开启组件扫描--> <context:component-scan base-package="com.zze"/> <!--配置 C3P0 数据源--> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driverClass}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!--Spring 整合 Hibernate--> <!--引入 Hibernate 配置信息--> <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- 注入连接池 --> <property name="dataSource" ref="dataSource"/> <!-- 配置Hibernate的相关属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <!--配置映射扫描--> <property name="packagesToScan" value="com.zze.domain"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 开启注解事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <bean name="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"/> </bean> </beans>
applicationContext.xml
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///test jdbc.username=root jdbc.password=root
jdbc.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c\:mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### # error warn info debug trace log4j.rootLogger= info, stdout
log4j.properties
3、使用注解:
package com.zze.domain; import javax.persistence.*; @Table(name = "user") @Entity public class User { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
com.zze.domain.User : Hibernate 实体映射注解
package com.zze.dao.impl; import com.zze.dao.BaseDao; import org.hibernate.SessionFactory; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate5.HibernateTemplate; import org.springframework.orm.hibernate5.support.HibernateDaoSupport; import javax.annotation.Resource; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> { /** * 注入 sessionFactory * * @param sessionFactory */ @Autowired private void setSF(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); } /* 或 @Resource(name = "hibernateTemplate") private HibernateTemplate hibernateTemplate; */ private Class clazz; public BaseDaoImpl() { /* 例: class UserDaoImpl extends BaseDaoImpl<User> */ // 获取到运行时实际类 UserDaoImpl Class<? extends BaseDaoImpl> actualClass = this.getClass(); // 获取到实际类父类 BaseDaoImpl<User> Type genericSuperclass = actualClass.getGenericSuperclass(); // 转为参数化类型 ParameterizedType type = (ParameterizedType) genericSuperclass; // 获取类型化参数 User Type[] actualTypeArguments = type.getActualTypeArguments(); this.clazz = (Class) actualTypeArguments[0]; } @Override public void save(T model) { this.getHibernateTemplate().save(model); } @Override public void update(T model) { this.getHibernateTemplate().update(model); } @Override public void delete(Serializable id) { this.getHibernateTemplate().delete(id); } @Override public T findById(Serializable id) { return (T) this.getHibernateTemplate().get(clazz, id); } @Override public List<T> findAll() { return (List<T>) this.getHibernateTemplate().find("from " + clazz.getSimpleName()); } @Override public Serializable findCount(DetachedCriteria detachedCriteria) { detachedCriteria.setProjection(Projections.rowCount()); List<Long> list = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria); return list.size() > 0 ? list.get(0).intValue() : null; } @Override public List<T> findPage(DetachedCriteria detachedCriteria, Integer begin, Integer pageSize) { detachedCriteria.setProjection(null); return (List<T>) this.getHibernateTemplate().findByCriteria(detachedCriteria, begin, pageSize); } }
com.zze.dao.impl.BaseDaoImpl : dao 层注入 sessionFactory
package com.zze.dao.impl; import com.zze.dao.UserDao; import com.zze.domain.User; import org.springframework.stereotype.Repository; @Repository("userDao") public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao { }
com.zze.dao.impl.UserDaoImpl : dao 层实例化注解
package com.zze.service.impl; import com.zze.dao.UserDao; import com.zze.domain.User; import com.zze.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Transactional @Service("userService") public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public void save(User user) { userDao.save(user); } }
com.zze.service.impl.UserServiceImpl : service 层实例化和事务注解
package com.zze.web.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.zze.domain.User; import com.zze.service.UserService; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.springframework.stereotype.Controller; @Controller("userAction") @ParentPackage("struts-default") @Namespace("/user") public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); @Override public User getModel() { return user; } private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } // 访问路径 localhost:8080/user/save @Action(value = "save",results = {@Result(name = "success",location = "/index.jsp")}) public String save() { userService.save(user); return NONE; } }
com.zze.web.action.UserAction : web 层实例化和 Struts2 配置注解
属性文件值注入
jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///test jdbc.username=root jdbc.password=root
jdbc.properties
<?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" 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"> <context:property-placeholder location="classpath:jdbc.properties"/> </beans>
applicationContext.xml
package com.zze.spring.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Demo { @Value("${jdbc.driverClass}") private String driverClass; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Test public void test() { System.out.println(driverClass); System.out.println(url); System.out.println(username); System.out.println(password); /* com.mysql.jdbc.Driver jdbc:mysql:///test root root */ } }
com.zze.spring.test.Demo
java框架之Spring(4)-Spring整合Hibernate和Struts2的更多相关文章
- 【Java EE 学习 53】【Spring学习第五天】【Spring整合Hibernate】【Spring整合Hibernate、Struts2】【问题:整合hibernate之后事务不能回滚】
一.Spring整合Hibernate 1.如果一个DAO 类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了:如果一个DAO类没有 ...
- Spring Data初步--整合Hibernate
Spring Data课程中的技术介绍 Hibernate: Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,它将 pojo 与数据库表建立映射关系 ...
- Spring学习7-Spring整合Hibernate
一.Springl为什么要整合Hibernate 二者的整合主要是把hibernate中核心的一些类型交给spring管理,这些类型主要包括sessionFactory. transactionM ...
- java框架之Quartz-任务调度&整合Spring
准备 介绍 定时任务,无论是互联网公司还是传统的软件行业都是必不可少的.Quartz,它是好多优秀的定时任务开源框架的基础,使用它,我们可以使用最简单基础的配置来轻松的使用定时任务. Quartz 是 ...
- java框架之MyBatis(2)-进阶&整合Spring&逆向工程
进阶内容 准备 jdbc.url=jdbc:mysql://192.168.208.192:3306/test?characterEncoding=utf-8 jdbc.driver=com.mysq ...
- Spring再接触 整合Hibernate
首先更改配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http ...
- java框架之SpringMVC(1)-入门&整合MyBatis
前言 SpringMVC简介 SpringMVC 是一个类似于 Struts2 表现层的框架,属于 SpringFramework 的后续产品. 学习SpringMVC的原因 SpringMVC 与 ...
- 【java框架】SpringBoot(7) -- SpringBoot整合MyBatis
1.整合MyBatis操作 前面一篇提到了SpringBoot整合基础的数据源JDBC.Druid操作,实际项目中更常用的还是MyBatis框架,而SpringBoot整合MyBatis进行CRUD也 ...
- 【java框架】SpringBoot(5)--SpringBoot整合分布式Dubbo+Zookeeper
1.理论概述 1.1.分布式 分布式系统是若干独立计算机的集合,这些计算机对于用户来讲就像单个系统. 由多个系统集成成一个整体,提供多个功能,组合成一个板块,用户在使用上看起来是一个服务.(比如淘宝网 ...
随机推荐
- C#学习笔记(35)——事件做的登录案例
说明(2018-4-9 20:11:42): 1. 先自定义了一个登录控件,可以输入账号.密码,点击登录.然后在Form1里面拖入这个控件,要求输入账号密码正确时,点击登录,控件显示绿色,否则显示红色 ...
- 关于 GET、POST、表单、Content-Type
关于 GET.POST.表单.Content-Type headers HTTP 的请求头,在这里也可以放参数,不论 GET 请求或 POST 请求都可以. GET 请求 GET 请求的参数都在 UR ...
- Mysql数据按天分区,定期删除
需求: 1.日志表需要按天分区 2.只保留一个月数据 方案: 1.创建两个事件,一个事件生成未来需要的分区,另一个事件定期检查过期数据(移除分区) 2.创建事件每小时执行一次,删除事件每天执行一次 3 ...
- go语言字符串的连接和截取
字符串的连接: https://studygolang.com/articles/12281?fr=sidebar 字符串的截取: https://studygolang.com/articles/9 ...
- iOS电量获取
一.Ios获取方法 Instrument电量工具获取 操作步骤: a) 手机不能连接数据线,kill掉后台所有app进程 b) 点击设置,选择开发,点击Logging,开启Energy,点击Start ...
- go for-range中的循环变量
测试的时候发现一个有意思的地方,就是go始终利用同一块内存来接收集合中的一个值,只是在每次循环的时候重新赋值而已. package main import ( "fmt" ...
- 开学收好这 17 种工具 App,让你新学期学习更有效率
开学啦!不管是想勾搭学长还是想讨好学妹,相信同学们对新学期.新同学或者新学校都已经满怀期待了.但是,除了帅气逼人的学长和青春靓丽的学妹,你们可不能忘记上学的首要任务还是学习噢. 那么,为了帮助同学们更 ...
- Tomcat manager页面报403
一.前言 我这边已经配置了tomcat-users.xml: <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns ...
- GO语言-基础语法:条件判断
1. IF判断(aa.txt内容:asdfgh.bb.txt内容:12345) package main import ( "io/ioutil" "fmt" ...
- 线程的信号量Semaphore
线程和进程一样也有信号量,一个资源在同一时刻只有规定数量的线程能使用.