Spring Data JPA 是一个持久层的框架,而一个持久层框架所做的事情不过两件:
连接数据库(比如 JDBD连接数据库) 2.操作数据库(比如 sql 操作数据库);连接数据库:配置参数抽取: config.properties 配置:# oracle jdbc properties
jdbc.url = jdbc:oracle:thin:@localhost:1521:XE
jdbc.driver= oracle.jdbc.driver.OracleDriver
jdbc.user = bos
jdbc.password = bos
applicationContext-dataSource.xml 配置:数据库连接池配置: config.properties在主配置文件 applicationContext.xml 中通过配置加载属性文件:
<!-- 加载properties文件 -->
<context:property-placeholder location=\"大众classpath:config.properties\"大众 />
( ${jdbc.url} 这种类似EL表达式的是SpringEL 表达式 )
<bean id=\"大众dataSource\"大众 class=\"大众com.mchange.v2.c3p0.ComboPooledDataSource\公众>
<property name=\"大众driverClass\公众 value=\公众${jdbc.driver}\"大众 />
<property name=\公众jdbcUrl\公众 value=\"大众${jdbc.url}\公众 />
<property name=\"大众user\公众 value=\"大众${jdbc.user}\"大众 />
<property name=\公众password\"大众 value=\"大众${jdbc.password}\公众 />
</bean>
Spring整合JPA配置:(在 entityManagerFactory中配置了连接池 和 domain中的bean ,这就相称于是用连接把实体类与数据库表建立了联系, [这里解释一点:实体和表之间的准确对应关系是依赖实体类中的表明来准确定位的] 这种联系是非常紧密的,实体工具属性值的变革直接会反响到数据库表中, 而JPA作为接口规范,这里选择 hibernate作为持久化供应者; 然后便是一些数据库的基本配置了;)
<!-- 整合JPA配置 -->
<bean id=\"大众entityManagerFactory\公众
class=\"大众org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean\"大众>
<property name=\"大众dataSource\公众 ref=\"大众dataSource\"大众 />
<property name=\公众packagesToScan\公众 value=\公众cn.itcast.bos.domain\公众 />
<property name=\公众persistenceProvider\"大众>
<bean class=\"大众org.hibernate.jpa.HibernatePersistenceProvider\"大众 />
</property>
<property name=\"大众jpaVendorAdapter\公众>
<bean class=\公众org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter\公众>
<property name=\"大众generateDdl\公众 value=\"大众true\"大众 />
<property name=\公众database\公众 value=\"大众ORACLE\"大众 />
<property name=\"大众databasePlatform\公众 value=\"大众org.hibernate.dialect.Oracle10gDialect\公众 />
<property name=\公众showSql\"大众 value=\"大众true\"大众 />
</bean>
</property>
<property name=\"大众jpaDialect\"大众>
<bean class=\公众org.springframework.orm.jpa.vendor.HibernateJpaDialect\"大众 />
</property>
<!-- <property name=\公众jpaPropertyMap\"大众> -->
<!-- <map> -->
<!-- <entry key=\公众hibernate.query.substitutions\公众 value=\"大众true 1, false 0\"大众 /> -->
<!-- <entry key=\公众hibernate.default_batch_fetch_size\公众 value=\"大众16\"大众 /> -->
<!-- <entry key=\公众hibernate.max_fetch_depth\"大众 value=\"大众2\公众 /> -->
<!-- <entry key=\"大众hibernate.generate_statistics\"大众 value=\"大众true\"大众 /> -->
<!-- <entry key=\"大众hibernate.bytecode.use_reflection_optimizer\公众 -->
<!-- value=\公众true\"大众 /> -->
<!-- <entry key=\"大众hibernate.cache.use_second_level_cache\公众 value=\"大众false\"大众 /> -->
<!-- <entry key=\公众hibernate.cache.use_query_cache\"大众 value=\"大众false\"大众 /> -->
<!-- </map> -->
<!-- </property> -->
</bean>
2.操作数据库:
整合Spring Data JPA (相称于扫描了Dao, 这样dao的操作才能被识别;)这里解释一点: dao的操作能被识别是CRUD的哪种操作, 至于操作哪个表, 是由在接口创建时传入的泛型参数确定的, 传入了一个泛型类,这个类代表着某张表; 简而言之:dao描述了两个问题: 1.我要实行什么操作, 2.我要操作那张表;
<!-- 整合spring data jpa -->
<jpa:repositories base-package=\"大众cn.itcast.bos.dao\"大众 />
3.声明式事务管理配置:
1. 配置事务管理器:
(JDBC事务管理的实质,是对Session的管理, 那么这里配置了事务管理器, 就相称于指明了由谁来管理事务, 而同时属性注入了 entityManagerFactory 实体管理者工厂,这就相称于将数据库操作中的session交给了事务管理器,也就随意马虎实现事务的管理了)
<!-- JPA事务管理器 -->
<bean id=\"大众transactionManager\"大众 class=\"大众org.springframework.orm.jpa.JpaTransactionManager\"大众 >
<property name=\"大众entityManagerFactory\"大众 ref=\"大众entityManagerFactory\公众 />
</bean>
配置”事务表明驱动”(这样就可以识别 Service 中的 @Transactional了)
<!-- 表明管理事务 -->
<tx:annotation-driven transaction-manager=\公众transactionManager\"大众 proxy-target-class=\公众true\公众/>
4.Spring Data JPA 配置小结:
1. SpringDataJPA 的配置便是通过将基本数据库连接参数:比如driven , url , username, password通过SPEL读取到连接池DataSource, 这个时候连接池实在已经拿到了数据库的连接connection, 理论上已经可以通过sql操作数据库了,但是此时我们又将: dataSource, , domain , persistenceProvider 通过属性注入到 entityManagerFactory ,实在这个时候 ”实体管理器工厂” 已经利用 DataSource中的 connection 将 domain 下的实体类 entity 与数据库中的表 table 建立了紧密联系, 此时已经完成类与表的强干系; 至此,我们对数据库的操为难刁难象不再是真真正正的表了,而是与之强干系的类了,操作的实现不再是sql语句,而是利用java代码来实现了; 至于哪个类对应哪个表,这便是 映射文件 hbm.xml 或者是类中的映射表明配置来细化了;
2. 在第1步得到类与数据库的连接往后,我们就要操作数据库了,我们是通过:
<jpa:repositories base-package=\"大众cn.itcast.bos.dao\"大众 />
这个相称于是扫描指定包下的 repository 接口, (当然这些repository 继续了jpaRepository,或者JpaSpecificationExecutor接口), 这样实在底层也是利用了AOP 当我们在Service中 @autowired 这些接口实现时, AOP 会给我们注入 SpringDataJPA 默认实现,这些实现了本身已经封装了一些常见的CRUD操作,以是我们可以省去常见CRUD操作的sql的编写,但是对付一些繁芜的CRUD操作, SpringDataJPA 也给我们留了一个口子:
比如一些标准的操作:findById() , findByProvinceAndCityAndDistrict 等更繁芜的操作:@Query(value=\"大众update Courier set deltag='1' where id=?\"大众)
@Modifying
public void updateDeltag(int id);
或者是这个:
@Query(value=\公众update Courier set deltag='' where id=?\"大众)
@Modifying
public void doRestore(int id);
3 . 至于事务管理: 事理是Spring 有IOC ,那么类的创建,准确来说是Service类的创建,也是由Spring来创建, 根据Spring创建bean的生命周期方法的实行流程,我们知道,后处理bean中的方法实行机遇是在我们得到bean工具之前,那么,后处理bean会利用AOP思想,在我们得到的Service工具的方法实行开始都加上session的事务开启,在方法实行末端加上session的事务提交,和事务回滚,那么在我们拿到IOC 容器给我们创建的bean时,这个bean便是在事务管理之中的bean了; 这就完成了事务管理;
===============以上SpringDataJPA == 以下 WebService====================
WebService的配置:0.框架知识概述:
(WebService 按目前利用来看便是供应了跨做事器远程数据获取的一种办法, 那我们只会关心两个问题: 1. 远程做事的创建与发布, 2,本地对远程做事的访问与数据吸收; 实在远程做事的创建,便是一个service接口 中方法访问路径,访问办法,吸收数据格式,返回数据格式的声明, 至于做事的发布实在是交给了配置文件; 至于本地客户端可能只须要WebClient 加上一个精确格式的url就可以了)我们这里说一下 JAX-RS 的配置:
1.首先说一下做事端配置:
作为一个做事供应端,它须要识别到对 它的所有WebService要求, 那么它便是通过在 web.xml中配置一个 CXFServlet 用来专门吸收并处理WebService要求:比如下面配置会拦截所有端口号后以 /services 开头的url要求:
<servlet>
<servlet-name>CXFService</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFService</servlet-name>
<url-pattern>/services/</url-pattern>
</servlet-mapping>
在第1步拦截到所有WebService要求的根本上,它会根据要求的url 去探求对应的Service , 那么到哪里去探求呢? 当然是到已经发布到做事器中的Service中去找, 那么怎么才算是发布到做事器中了呢? 这里我们是通过在 .xml配置文件来实现发布的:比如下面配置 是将 PromotionServiceImpl 发布到做事器中
<jaxrs:server id=\公众promotionService\"大众 address=\"大众/promotionService\"大众>
<jaxrs:serviceBeans>
<bean class=\公众cn.itcast.bos.service.take_delivery.impl.PromotionServiceImpl\"大众 />
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<bean class=\"大众org.apache.cxf.interceptor.LoggingInInterceptor\公众></bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class=\公众org.apache.cxf.interceptor.LoggingOutInterceptor\"大众></bean>
</jaxrs:outInterceptors>
</jaxrs:server>
--------------------------------下面附上 Service接口中方法声明---------------------------------------
// 根据page和rows 返回分页数据
@Path(\"大众/pageQuery\公众)
@GET
@Produces({ \"大众application/xml\"大众, \公众application/json\"大众 })
PageBean<Promotion> findPageData(@QueryParam(\"大众page\"大众) int page,
@QueryParam(\"大众rows\"大众) int rows);
--------------------------------下面附上 Service实现编写示例---------------------------------------
@Override
public PageBean<Promotion> findPageData(int page, int rows) {
Pageable pageable = new PageRequest(page - 1, rows);
Page<Promotion> pageData = promotionRepository.findAll(pageable);
// 封装到Page工具
PageBean<Promotion> pageBean = new PageBean<Promotion>();
pageBean.setTotalCount(pageData.getTotalElements());
pageBean.setPageData(pageData.getContent());
return pageBean;
}
2.做事端配置小结:
实在以上已经解释了Service 接口编写, Service接口实现编写, Service做事在做事器端发布, 以及做事器端对 WebService 要求的拦截;
3.客户端要求操作:
客户端作为做事的调用者,相对来说不须要特殊的配置,只须要利用一个客户端要求工具WebClient 加上精确的url 就可以发送要求了:个中 WebClient.create 创建了要求; .accept 指明了是吸收数据(吸收用accept, 发送用 type) ; .get 指明了要求办法是get要求(get要求是查询操作, post要求是添加操作, put要求是更新操作, delete 要求是删除操作)
@Action(value = \"大众promotion_pageQuery\公众, results = { @Result(name = \"大众success\"大众, type = \"大众json\"大众) })
public String pageQuery() {
// 基于WebService 获取 bos_management的 活动列表 数据信息
PageBean<Promotion> pageBean = WebClient
.create(Constants.BOS_MANAGEMENT_URL
+ \"大众/bos_management/services/promotionService/pageQuery?page=\"大众
+ page + \公众&rows=\公众 + rows)
.accept(MediaType.APPLICATION_JSON).get(PageBean.class);
ActionContext.getContext().getValueStack().push(pageBean);
return SUCCESS;
}
4.WebService配置小结:
实在我们来理顺全体过程: 客户端 利用WebClient.create();发起要求-------->做事端 web.xml配置 CXFServlet 拦截所有 /services 开头要求--------> applicationContext-webService.xml 发布做事-------> Service接口中的详细方法, 声明做事访问办法,-------> Service实现类中 供应了做事真正的操作内容;
=================以上WebService == 以下 ActiveMQ ======================
3.ActiveMQ 的配置:0.框架知识概述:
ActiveMQ 是JMS java做事的规范的实现: 个人觉得它是一个做事器,有着自己的访问端口,但是它的事情却是存储, 又很像一个存放的数据库,以是在和 Spring整合时特像一个数据库: 实在:ActiveMQ 的事情也是两件:1.给生产者供应存放的入口, 2.给消费者供应消费的入口:
根本连接配置:无论是 “生产” 还是 “消费” :我们都要有根本的连接配置:
ActiveMQ 本身给我们供应了一个连接工厂: ActiveMQConnectionFactory<!-- ActiveMQ 连接工厂 -->
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS做事厂商供应-->
<!-- 如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->
下面这种连接办法须要是为了简化<bean>配置,但须要下载第三方的支持,开始运行时较慢:
<!-- <amq:connectionFactory id=\"大众amqConnectionFactory\公众 -->
<!-- brokerURL=\公众tcp://localhost:61616\"大众 userName=\"大众admin\"大众 password=\"大众admin\公众 /> -->
<bean id=\"大众amqConnectionFactory\公众
class=\公众org.apache.activemq.ActiveMQConnectionFactory\公众>
<property name=\"大众brokerURL\"大众 value=\"大众tcp://localhost:61616\公众></property>
<property name=\"大众userName\公众 value=\"大众admin\"大众></property>
<property name=\"大众password\公众 value=\"大众admin\公众></property>
</bean>
Spring 对 ActiveMQ 连接工厂的封装 CachingConnectionFactorySpring在 JMS做事供应商供应连接工厂的根本上,给我们进行了一次封装,这个封装可以理解成 Spring 供应的API 与 ActiveMQ 之间的适配器 ; 达到理解耦的浸染, 这样Spring就可以整合各个JMS供应商供应的连接工厂了;
<!-- Spring Caching连接工厂 -->
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id=\公众mqConnectionFactory\"大众 class=\"大众org.springframework.jms.connection.CachingConnectionFactory\"大众>
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name=\"大众targetConnectionFactory\公众 ref=\"大众amqConnectionFactory\"大众></property>
<!-- 同上,同理 -->
<!-- <constructor-arg ref=\公众amqConnectionFactory\"大众 /> -->
<!-- Session缓存数量 -->
<property name=\"大众sessionCacheSize\"大众 value=\公众1\"大众 />
</bean>
根本配置小结不管我们用那种JMS产品,它都会供应一个连接工厂,而与Spring整合时,我们用 CachingConnectionFactory 将JMS做事厂商供应的连接工厂进行封装, 那么我们就可以不须要针对不同的 连接工厂操作了,只须要对同一个 CachingConnectionFactory 进行操作,达到理解耦的目的; 流程如下:
JMS厂商供应ActiveMQ 供应 ActiveMQConnectionFactory 连接工厂------>Spring 供应 CachingConnectionFactory 缓存连接工厂 封装厂商供应的连接工厂
生产者配置:这个生产者配置,Spring利用了它惯用的模板思想,给你供应了一个模板工具,没有什么特殊之处,这个模板工具封装了连接工厂,就相称于持有了对ActiveMQ的连接, 那么这个时候向ActiveMQ中添加该当是可以的; 下边配置了两种类型的jmsTemplate: 1. 点对点模式: 行列步队Queue, 2. 发布订阅模式的: 话题Topic ; 他们的配置大同小异,唯一不同之处在于 :<property name=\"大众pubSubDomain\公众 value=\"大众false\公众 />
的配置的value 值是false 还是 true; (true:发布订阅模式 false:点对点模式;)
<!-- 定义JmsTemplate的Queue类型 -->
<bean id=\"大众jmsQueueTemplate\"大众 class=\公众org.springframework.jms.core.JmsTemplate\"大众>
<!-- 这个connectionFactory对应的是我们定义的Spring供应的那个ConnectionFactory工具 -->
<constructor-arg ref=\公众mqConnectionFactory\公众 />
<!-- 非pub/sub模型(发布/订阅),即行列步队模式 -->
<property name=\"大众pubSubDomain\公众 value=\"大众false\公众 />
</bean>
<!-- 定义JmsTemplate的Topic类型 -->
<bean id=\"大众jmsTopicTemplate\"大众 class=\"大众org.springframework.jms.core.JmsTemplate\公众>
<!-- 这个connectionFactory对应的是我们定义的Spring供应的那个ConnectionFactory工具 -->
<constructor-arg ref=\"大众mqConnectionFactory\"大众 />
<!-- pub/sub模型(发布/订阅) -->
<property name=\"大众pubSubDomain\公众 value=\公众true\"大众 />
</bean>
<!--Spring JmsTemplate 的生产者 end-->
3.生产者编程:
1.在生产者配置的根本上,配置了一个jmsTemplate模板,我们可以利用:
// 注入queue模板
@Autowired
@Qualifier(\"大众jmsQueueTemplate\公众)
private JmsTemplate jmsQueueTemplate;
注入到我们的程序中,然后调用send方法,向activeMQ中生产:
// 调用MQ做事,发送短信验证码
jmsQueueTemplate.send(\"大众bos_sms\"大众, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
MapMessage mapMessage = session.createMapMessage();
mapMessage.setString(\公众telephone\"大众, model.getTelephone());
mapMessage.setString(\"大众checkCode\"大众, checkCode);
return mapMessage;
}
});
大略阐明一下: send(名称, 创建接口);
这个地方相称繁芜:利用了两个不随意马虎理解的知识点: 我们大略聊聊:
第一个问题: jmsQueueTemplate 的Send()方法须要 MessageCreator 的createMessage()方法创建的内容,但是 MessageCreator 创建时须要 session,但是它却没有; 然而 jmsQueueTemplate 的execute()方法 却可以得到session , 以是 jmsQueueTemplate 对 MessageCreator 说:你先过来,然后我给你弄个session , 然后你给我弄message, 这里边表示的是, 接口作为参数时,实现了主调方法的资源对接口中的方法的共享, 这里主调方法是 send ,它可以想办法拿到 session,然后 它把session共享给了 createMessage()方法;如果说一样平常数据类型数据做为形参,主调方法是为了获取实参的值,
那么接口作为形参时,主调方法是为了得到接口的方法, 还有一点附带效果:传入的接口中的方法可以共享主调方法的参数访问权限(便是主调方法可以用的参数,接口中的方法也可以用;)
第二个问题: send 发送的内容是不固定的(有:1.MapMessage;2.ByteMessage;3.ObjectMessage;4.StreamMessage;5.TextMessage),也便是说 创建的方法体是不固定的,那么是如何实现的呢? 用接口作为参数传入,由用户动态定义方法的实现;如果说我们在方法中调用类的静态方法,是将一段固定代码插入到主调方法中;
那么对接口方法的调用,便是将一段动态代码插入到主调方法中;
4.生产者总结:
ActiveMQ 的生产者:
厂商的 ActiveMQConnectionFactory 注入到 ------>Spring的 CachingConnectionFactory ------>注入到 Spring的 JmsTemplate ; 配置供应了这个模板工具之后,我们就可以在java代码中注入这个工具,进行的创建;
5.消费者配置:
消费者要从ActiveMQ中拿, 肯定是要连接ActiveMQ做事器的,以是根本连接配置,消费者配置中也须要一份,我们假设消费者配置中,已经配置好了根本连接; 那么这个时候已经可以拿到 CachingConnectionFactory , 这意味着我们已经可以通过这个连接工厂得到与ActiveMQ的连接了; 如何完成消费呢? 首先编写一个类实现 MessageListener 接口 ,然后将这个类注册到监听器容器中; 这里解释一点,类实现了 MessageListener 接话柄质上是为了让这个类实现监听器该当具有的方法, 然而并没有真正监听ActiveMQ中的,这个时候须要配置到监听器的容器(listener-container)中才能生效; 而这个(listener-container) 到底如何事情的呢? 我们来看看这个,消费者配置:
<!-- 定义Queue监听器 -->
<jms:listener-container destination-type=\公众queue\公众 container-type=\"大众default\"大众
connection-factory=\"大众connectionFactory\"大众 acknowledge=\"大众auto\公众>
<!-- 默认注册bean名称,该当是类名首字母小写 -->
<jms:listener destination=\公众bos_sms\"大众 ref=\"大众smsConsumer\"大众/>
</jms:listener-container>
<!-- 定义Topic监听器 -->
<!-- <jms:listener-container destination-type=\公众topic\"大众 container-type=\"大众default\公众
connection-factory=\公众connectionFactory\"大众 acknowledge=\公众auto\"大众>
<jms:listener destination=\公众spring_topic\"大众 ref=\"大众topicConsumer1\"大众/>
<jms:listener destination=\"大众spring_topic\"大众 ref=\公众topicConsumer2\"大众/>
</jms:listener-container> -->
我们可以看到:在监听容器中,注入了两个参数:
connection-factory=\公众connectionFactory\"大众
这个是配置了连接工厂, 是得到与ActiveMQ做事器连接的;
<jms:listener destination=\"大众bos_sms\"大众 ref=\公众smsConsumer\"大众/>
这个是配置了监听的目标: destination=\"大众bos_sms\"大众
(监听者)消费者: ref=\"大众smsConsumer\"大众
6.消费者编程:
(监听者)消费者 本身是一个类,实现了 MessageListener 接口:
@Service(\公众smsConsumer\公众)
public class SmsConsumer implements MessageListener {
@Override
public void onMessage(Message message) {
MapMessage mapMessage = (MapMessage) message;
String telephone = null;
String checkCode = null;
try {
telephone = mapMessage.getString(\"大众telephone\"大众);
checkCode = mapMessage.getString(\公众checkCode\"大众);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 用输出语句代替短信发送
System.out.println(telephone+\公众 的验证码是 : \公众+checkCode);
}
}
7.消费者总结:
实在消费者无非便是从ActiveMQ中得到得到, 那么首先要得到与ActiveMQ的连接,这个是通过根本配置完成的, 连接往后要从里边拿呀,这个地方是在配置文件中配置一个监听器容器, 将连接工厂和监听器(实在便是一个实现了MessageListener的java类) 注入到这个监听器中,这个时候就相称于通过监听器容器,将监听器和ActiveMQ建立了联系;
=================以上ActiveMQ == 以下 Quartz=====================
4.Quartz的配置:0.框架知识概述:
Quartz是一个定时任务调度框架, 它关心的只有两件事情:
要做什么事情---->jobDetail(即任务详情)什么时候做,频率是什么---->SimpleTrigger(依据韶光)/CronTriggerFactoryBean(依据日历) 即:任务实行策略;Ps:
任务调度员scheduler,这个是将 jobDetail 和 SimpleTrigger 进行组合,天生一个日程,其余还有一点要解释一下,在实际生产中,我们 jobDetail(即任务详情)可能并不在Spring的管理之中, 但是, jobDetail(即任务详情) 却须要@autowired 被Spring管理的Service 或者其他bean, 这就违背了Spring规定:一个工具要想被注入工具,必须自己在Spring 管理之中,这个时候该怎么办理呢, 我们知道, Struts2与Spring整合时, action 没有被Spring管理,却可以注入被Spring管理的Service, 这里我们利用同样的方法办理这个问题,那便是创建了一个可以使 我们的 jobDetail 具有可以自动注入功能的工厂类 JobFactory ;我们在实际配置中是将 jobDetail 注入 SimpleTrigger ,再将 SimpleTrigger 注入 SchedulerFactoryBean ,那么,此时我们将 JobFactory 也注入到 SchedulerFactoryBean 中,那么创建出来的 jobDetail 就具有了自动注入的功能; 问题得以办理;JobDetailFactoryBean配置:JobDetailFactoryBean 是job的工厂,我们在里边注入我们的job类工具, 下面的配置中job并不在Spring管理中;
<bean id=\公众promotionJob\"大众 class=\"大众org.springframework.scheduling.quartz.JobDetailFactoryBean\公众>
<property name=\"大众jobClass\"大众 value=\公众cn.itcast.bos.quartz.PromotionJob\"大众></property>
</bean>
Job类编写:public class PromotionJob implements Job{
@Autowired
private PromotionService promotionService;
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
//每分钟实行一次,当前韶光大于promotion数据表中的endDate ,活动已经由期,设置status='2'
promotionService.updateStatus(new Date());
}
}
SimpleTriggerFactoryBean 配置:将JobDetailFactoryBean 注入到 SimpleTriggerFactoryBean中:
<bean id=\"大众simpleTrigger\"大众 class=\"大众org.springframework.scheduling.quartz.SimpleTriggerFactoryBean\"大众>
<property name=\"大众jobDetail\公众 ref=\"大众promotionJob\公众></property>
<property name=\公众startDelay\公众 value=\公众0\公众></property>
<property name=\"大众repeatInterval\"大众 value=\公众10000\"大众></property>
</bean>
SchedulerFactoryBean的配置:将 SimpleTriggerFactoryBean 注入到 SchedulerFactoryBean中,同时还注入了一个 jobFactory这个jobFactory 注入的目的是是为了让我们的Job具有Spring自动注入功能;
<bean id=\"大众\公众 class=\"大众org.springframework.scheduling.quartz.SchedulerFactoryBean\公众>
<property name=\"大众jobFactory\公众 ref=\"大众jobFactory\"大众></property>
<property name=\公众triggers\公众>
<list>
<ref bean=\"大众simpleTrigger\公众/>
</list>
</property>
</bean>
附上 jobFactory的代码:@Service(\"大众jobFactory\"大众)
public class JobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle)
throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
5.redis配置:Redis是一个内存数据库,由于存取速率非常快,每每用作缓存; 作为一个数据库, 无非便是考虑两个问题:
怎么连接这个数据库,怎么操作这个数据库;配置连接池基本参数:<!-- jedis 连接池配置 -->
<bean id=\"大众poolConfig\"大众 class=\"大众redis.clients.jedis.JedisPoolConfig\"大众>
<property name=\"大众maxIdle\"大众 value=\公众300\公众 />
<property name=\"大众maxWaitMillis\"大众 value=\公众3000\"大众 />
<property name=\公众testOnBorrow\"大众 value=\"大众true\公众 />
</bean>
配置连接工厂:<!-- jedis 连接工厂 -->
<bean id=\"大众redisConnectionFactory\公众
class=\公众org.springframework.data.redis.connection.jedis.JedisConnectionFactory\"大众
p:host-name=\"大众localhost\"大众 p:port=\公众6379\"大众 p:pool-config-ref=\公众poolConfig\"大众
p:database=\"大众0\"大众 />
配置模板:<!-- spring data 供应 redis模板 -->
<bean id=\"大众redisTemplate\"大众 class=\"大众org.springframework.data.redis.core.RedisTemplate\公众>
<property name=\"大众connectionFactory\公众 ref=\"大众redisConnectionFactory\"大众 />
<!-- 如果不指定 Serializer -->
<property name=\"大众keySerializer\"大众>
<bean class=\"大众org.springframework.data.redis.serializer.StringRedisSerializer\"大众 />
</property>
<property name=\公众valueSerializer\公众>
<bean class=\"大众org.springframework.data.redis.serializer.StringRedisSerializer\公众>
</bean>
</property>
</bean>
Java代码编写示例:// 2.将激活码保存到redis中 可以设置存货韶光;
redisTemplate.opsForValue().set(model.getTelephone(), activeCode, 24, TimeUnit.HOURS);
6.SpringDataElasticSearch配置:0.框架知识概述:
简化操作ElasticSearch的技能: 是SpringData 项眼前的一个子项目,为了整合 ElasticSearch ; 经由一系列配置,供应了类似SpringDataJPA的操作模式;
ElasticSearch是一个全文搜索做事器 , 但实质上是一个索引库: 它的一些基本观点和关系型数据库观点对应关系如下:
索引(index)------->表(table)
文档(document)------->一条数据实体(entity)
域(filed) --------> 字段(field)
作为一个数据库,我们还是关心两个老问题:1.怎么连接上这个数据库, 2.怎么操作这个数据库;
连接ElasticSearch:1.配置客户端 client
<!-- 配置elasticsearch 连接 实在这个地方配置的是客户端 :transportclient -->
<elasticsearch:transport-client id=\公众client\公众 cluster-nodes=\"大众localhost:9300\公众 />
2.配置模板工具: 注入client工具
<!-- spring data elasticsearch DAO 必须依赖 elasticsearchTemplate -->
<bean id=\"大众elasticsearchTemplate\公众
class=\公众org.springframework.data.elasticsearch.core.ElasticsearchTemplate\"大众>
<constructor-arg name=\"大众client\公众 ref=\"大众client\公众 />
</bean>
3.实体类要配置映射
这个映射与hibernate中的工具映射有些类似,但是还有不同,这个映射配置, 实在配置了实体的存储策略(就想当于指明关系数据库的表构造怎么建),检索策略,分词策略,等;
4.连接配置小结:
配置客户端:client ------>注入 elasticsearchTemplate ----->实体配置映射表明;
这个地方实体映射配置某种程度上说是一个 纯挚的映射配置的载体; 模板工具读取这个类时,可以读取这个工具中的映射文件;
操作ElasticSearch:配置扫描dao , 并且我们的dao继续了 ElasticSearchRepository 接口,这样我们在
@autowired dao实现时,就会注入框架默认的实现;
<!-- 扫描DAO包 自动创建实现 -->
<elasticsearch:repositories base-package=\"大众cn.itcast.dao\"大众 />
3.ElasticSearch 配置小结:
我们连接ElasticSearch 是通过配置客户端操为难刁难象 transportclient , 实在拿着这个client已经可以操作 ElasticSearch 了,但是 我们又对这个client进行了一次封装,封装成了一个 template (模板), 这个模板已经可以完成了一些基本操作了, 然而在此时,我们没有止步,而是又做了一层封装, 封装成了一个默认实现,我们编写一个dao 继续 ElasticsearchRepository 这个接口,然后AOP就会给我们返回一个默认实现的 repository,这个repository 实现了基本增编削, 规范的find查询方法,等等 这点有点儿类似SpringDataJPA ;
7.shiro配置:Shiro是一个权限掌握框架:
权限掌握流程: applicationCode -----> Subject------> ShiroSecurityManager----->Realm ;
实在权限掌握问题大略来说便是: 哪些user 可以访问哪些 url的问题;
1.粗粒度url权限验证流程:
request 要求发出--->web.xml中的DelegatingFilterProxy 代理过滤器过滤到要求----> 交给applicationContext.xml 中的真正的过滤器 ShiroFilterFactoryBean----> 过滤器将要求交给 \"大众安全管理器\"大众 securityManager ----->\"大众安管\公众读取过滤器中的 \"大众资源与访问权限对应清单\"大众 filterChainDefinitions ----->\"大众安管\"大众找到request要访问的资源须要的权限:permission1 ---->
\"大众安管\"大众 调用 \"大众小弟\公众 realm 的 doGetAuthorizationInfo()方法,获得当前用户所持有的权限: permission2 ---->此时:\"大众安管\"大众已经从过滤器中拿到 1. 要访问的资源须要的权限:permission1 2. 前用户所持有的权限: permission2 ,以是\"大众安管\"大众可以很轻松地将两个权限做比较,如果匹配,那么就许可用户访问资源,如果不匹配,则谢绝访问该资源,并跳转到没有权限访问的页面;
2.细粒度方法级别权限验证流程:
request要求发出----> 调用 save()方法----> Spring 考试测验利用 IOC 创建cglib 动态代理工具,却创造目标类 的save()方法上有shiro表明,然后就利用AOP 在代理类的save方法上加上前置关照: AuthorizationAttributeSourceAdvisor 来读取save()方法上的 shiro表明,并将结果交给\"大众安管\"大众----->securityManager 得到 save()方法访问应具备的权限 -----> 调用realm的doGetAuthorizationInfo()方法,来获得当前用户所持有的权限, 然后安管自己会对两个权限为难刁难比,剖断是否可以访问资源...;
3.两种权限验证办法比拟剖析:
粗粒度url权限掌握 与 细粒度方法级别权限掌握 比拟剖析:
粗粒度url权限掌握
细粒度方法级别权限掌握
资源掌握者
securityManager
securityManager
资源访问所需权限获取来源
过滤器 shiroFilter 中的属性配置
Spring框架 (IOC和AOP共同浸染)从方法的表明读取
当前用户访问权限获取来源
小弟: realm
小弟:realm
权限不敷时处理办法
过滤器配置相应友好提示页面
抛出相应非常给方法调用者;
缓存框架Ehcache 的配置0.框架知识概述:
当我们用Shiro做权限管理的时候,我们每一次对资源进行访问时我们的 “安全管理器” securityManager 会对当前用户进行权限的授权信息获取, 如果每次获取当前用户的授权信息都到数据库中查询,这样无疑是降落了资源获取的速率,用户体验不好,以是这种情形,我们一定要对用户权限信息进行缓存处理;
Flag:缓存技能不一定用在权限管理,但权限管理一定会用到缓存;
复制自带配置文件 ehcache-failsafe.xmlEhcache 的jar包下有默认配置文件,我们将它复制到与applicationContext.xml 同级目录下;
我们在这个配置文件里边创建自定义的缓存空间;
Spring整合(管理)EhcacheEhcache 的 EhCacheManager “缓存管理器” 交给Spring的EhCacheManagerFactoryBean “缓存管理器工厂bean” 来管理;
至此, ehcache已经在Spring的管理之中了;
<!-- Ehcache配置 (ehcache的 \公众缓存管理器\公众 纳入Spring管理) -->
<bean id=\"大众ehCacheManager\"大众 class=\公众org.springframework.cache.ehcache.EhCacheManagerFactoryBean\"大众>
<property name=\公众configLocation\"大众 value=\公众classpath:ehcache.xml\"大众></property>
</bean>
Ehcache 对Shiro 的权限数据进行数据缓存Shiro 整合 EhcacheEhcache 底层是Map构造实现,以是Shiro要对Ehcache 的缓存管理器再做一层封装,指明什么作为key,什么作为value ,这个封装类便是: EhCacheManager ,我们将ehcache的 \"大众缓存管理器\"大众 属性注入到shiro 的 EhCacheManager :
<!-- shiro配置 (将ehcache的 \"大众缓存管理器\"大众 属性注入到shiro) -->
<!-- ehcache 底层是Map实现,以是Shiro要对ehcache的缓存管理器在做一层封装,指明什么作为key,什么作为value -->
<bean id=\公众shiroEhCacheManager\"大众 class=\"大众org.apache.shiro.cache.ehcache.EhCacheManager\公众>
<property name=\公众cacheManager\"大众 ref=\"大众ehCacheManager\"大众></property>
</bean>
Shiro “安全管理器” 得到 “Ehcache缓存管理器”根据Shiro权限验证实行流程: 运用程序代码------> subject ------> securityManager----->
Realm ------> 访问安全数据 ;
<!-- 安全管理器 -->
<bean id=\"大众securityManager\公众 class=\公众org.apache.shiro.web.mgt.DefaultWebSecurityManager\"大众>
<property name=\公众realm\"大众 ref=\公众bosRealm\"大众></property>
<property name=\"大众cacheManager\"大众 ref=\公众shiroEhCacheManager\公众></property>
</bean>
上边配置的结果是: “安全管理器” 得到了缓存操作权限; 这样它的小弟 realm 就可以向 “安全管理器” 申请一个缓存空间, 什么意思呢? 便是小弟realm说:你把 “bos” 这个缓存区给我,往后你找我要数据,你先到这个缓存区看看有没有,如果没有,我再去数据库帮你找到,然后你要把数据放进去,下次不要找我要了;
Reaml 指定将 哪些 数据存入 哪个 缓存区<!-- Realm配置, 指明将 \"大众授权数据\"大众 缓存到 \公众bos\"大众 缓冲区-->
<bean id=\"大众bosRealm\"大众 class=\公众cn.itcast.bos.realm.BosRealm\"大众>
<property name=\公众authorizationCacheName\"大众 value=\公众bos\"大众></property>
</bean>
Ehcache对权限数据缓存的 配置流程总结:在Ehcache的 ehcache-failsafe.xml中自定义缓存区 ------> Spring与Ehcache的整合类(EhCacheManagerFactoryBean)读取配置文件 得到 ehCacheManager------> ehCacheManager
注入到 Shiro的 shiroEhCacheManager ------> shiroEhCacheManager 注入到 “安全管理器” securityManager ------> Reaml 通过属性配置 来 声明要缓存数据,以及要缓存的区域 (比如 bos) ;
4. Ehcache对一样平常数据的缓存配置:
1. Spring “缓存管理器” 封装 Ehcache的 “缓存管理器”
在Shiro 整合Ehcache时,有一个 shiroEhCacheManager 来管理 key-value的天生策略, 那么在对一样平常数据的缓存配置时,肯定是不能用这个缓存管理器了, 这个时候Spring 就出来说话了,他说 我定义一个 “缓存管理器” 来管理 一样平常数据的key-value的天生策略;
<!-- Spring 封装Ehcache的缓存管理器,它规范了普通数据缓存时的key-value 天生策略 -->
<bean id=\"大众springCacheManager\"大众 class=\公众org.springframework.cache.ehcache.EhCacheCacheManager\"大众>
<property name=\公众cacheManager\"大众 ref=\公众ehCacheManager\"大众/>
</bean>
这个缓存管理器一方面是得到 Ehcache 的缓存管理器,拥有了缓存操作权限 ; 另一方面是供应了一些标签,它可以阐明这些标签,来实行缓存操作 ;
2.在Spring的配置文件中 激活spring 缓存表明
目的便是让Spring 能够识别它管理的类中的缓存表明;
<!-- 激活spring 缓存表明 -->
<cache:annotation-driven cache-manager=\"大众springCacheManager\公众/>
3.在被Spring管理的bean的方法上利用 @Cacheable() , @CacheEvict() :
@Cacheable(value=”缓存区”) : 运用缓存, 对方法返回结果进行缓存, 这个表明多用在查询方法上; 至于谁是key ,谁是value 由Spring的缓存管理器来卖力; 如果被表明的方法有不同的 传入参数, 可在表明中利用SpEL (Spring表达式) 自定义key值;
@CacheEvict (value=”缓存区”,allEntries=”true”): 打消缓存区的数据, allEntries代表所有数据;
缓存配置中的把稳点:被缓存的工具数据对应的类要序列化 : implements Serializable ;
Freemarker 模板引擎Struts2 默认是利用 Freemarker作为自定义标签模板,以是项目导入了Struts2 就已经导入了Freemarker的jar包;
0.技能概述:
Freemarker便是一个模板引擎,它类似我们之前学习的jsp; FreeMarker 它通过编写一个模板文件,结合我们程序中的动态数据,输出标准的文本内容,一样平常情形下我们用它来天生html文件比较多;
大略来说: 模板文件 + java数据工具 == 输出 (任何格式文本)
FreeMarker 模板文件,常日扩展名 .ftl (当然也可以用 .html / .jsp)
我们编写前,要安装一个Freemarker的插件,安装到eclipse ,这样我们编辑时就会有提示; Freemarker 模板文件中的变量 跟EL 表达式一样,都是 ${变量名}
编写模板文件 promotion_detail.ftl<link rel=\公众stylesheet\公众 type=\"大众text/css\公众 href=\"大众css/promotion_detail.css\公众>
<div class=\公众container promotions\"大众 >
<div class=\公众col-md-2 prolist\"大众>
<h5 class=\公众title\公众><a href=\"大众#/promotion\公众><strong>返回匆匆销列表</strong></a></h5>
<img src=\公众images/pro.jpg\"大众 class=\"大众img-responsive\"大众>
</div>
<div class=\"大众col-md-10 procontent\"大众>
<h5 class=\"大众title\"大众>${promotion.title}</h5>
<div class=\"大众intro\"大众>
<p>活动范围: ${promotion.activeScope}</p>
<p>活动韶光: ${promotion.startDate?string(\"大众yyyy-MM-dd\"大众)} -
${promotion.endDate?string(\"大众yyyy-MM-dd\"大众)}</p>
</div>
<div class=\"大众partline clearfix\"大众></div>
<div class=\"大众promotionbox\公众>
${promotion.description}
</div>
</div>
</div>
编写java代码// 用面向工具思想,将配置文件目录封装为configuration工具
Configuration configuration = new Configuration(
Configuration.VERSION_2_3_22);
configuration.setDirectoryForTemplateLoading(new File(
ServletActionContext.getServletContext().getRealPath(
\"大众/WEB-INF/freemarker_templates\"大众)));
// 用 configuration 获取模板工具 template
Template template = configuration
.getTemplate(\"大众promotion_detail.ftl\"大众);
// 动态数据
Promotion promotion = WebClient
.create(Constants.BOS_MANAGEMENT_URL
+ \"大众/bos_management/services/promotionService/promotion/\公众
+ model.getId()).accept(MediaType.APPLICATION_JSON)
.get(Promotion.class);
//布局动态数据 ()
Map<String, Object> parameterMap = new HashMap<String, Object>();
parameterMap.put(\"大众promotion\"大众, promotion);
//利用模工具合并数据 template 合并输出
/ @param dataModel the holder of the variables visible from the template (name-value pairs); usually a {@code Map<String, Object>} or a JavaBean (where the JavaBean properties will be the variables) /
template.process(parameterMap, new OutputStreamWriter(
new FileOutputStream(htmlFile), \"大众utf-8\"大众));
模板工具 template 合并数据时,将数据模型数据dataModel 输出到writer流中; 而这个dataModel 的数据类型一样平常是 Map<String, Object> , 当然也可以是 JavaBean ,这个 JavaBean 的属性是模板中的变量; 其余要说一点,如果模板中有变量必须全部赋值, 如果存在一个没有赋值, 彷佛会报错;
Spring与Mybatis整合配置PS: mybatis框架的特殊之处是,它实现了sql语句与java代码的分离,以是它要办理的核心问题是如何让mapper.xml中的sql语句在数据库操作时起浸染;
其余解释一点:
在mybatis单独利用时: mapper.xml-----> SqlMapConfig.xml ------> sqlSessionFactory ----->sqlSession , 以是这个时候 mapper.xml的引用在sqlSession中,因此 外置sql语句的调用是由sqlSession来完成的;
在mybatis与spring整合时: SqlMapConfig.xml ----> sqlSessionFactory ----> MapperFactoryBean; 由于在mybatis与spring整合时,SqlMapConfig.xml是一个空的文件,以是里边没有mapper.xml的引用,以是没有办法利用里边的sql,这个时候怎么办理这个问题呢? 通过一个逼迫哀求: 映射文件(mapper.xml)必须与相应的接口同名且在同一个目录下,这样在创建代理时,在读取接口的同时会在相同目录下去探求映射文件,这样就同时利用接口和映射文件天生了代理工具;
连接数据库数据库连接参数抽取: db.propertiesjdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123
Spring核心配置文件applicationContext.xml 中加载db.properties并配置连接池BasicDataSource1.大略解释:
连接池的浸染是供应连接,并且不用反复创建销毁数据库连接;
2.配置内容:
<!-- 加载属性配置文件 -->
<context:property-placeholder location=\公众classpath:db.properties\"大众/>
<!-- 配置连接池 -->
<bean id=\"大众dataSource\"大众 class=\"大众org.apache.commons.dbcp.BasicDataSource\"大众
destroy-method=\"大众close\"大众>
<property name=\"大众driverClassName\"大众 value=\公众${jdbc.driver}\公众 />
<property name=\"大众url\公众 value=\"大众${jdbc.url}\"大众 />
<property name=\"大众username\公众 value=\"大众${jdbc.username}\"大众 />
<property name=\公众password\"大众 value=\"大众${jdbc.password}\"大众 />
<property name=\公众maxActive\公众 value=\"大众10\"大众 />
<property name=\公众maxIdle\公众 value=\公众5\"大众 />
</bean>
配置Spring与Mybatis整合类 org.mybatis.spring.SqlSessionFactoryBean1.大略解释:
sqlSessionFactory 跟hibernate的SessionFactory , SpringDataJPA的EntityManagerFactory 的功能非常类似:
1.注入连接池,得到了连接数据库的能力;
2. 注入了映射配置文件位置; 差异在于:hibernate的映射配置文件是配置了实体与表之间的映射,末了干脆通过表明,将映射配置放到了实体类中,末了sql语句(或者hql)的编写就写到dao中了; 然后便是SpringDataJPA, 它是在Hibernate根本之上,将一部分sql语句做了封装实现,这样我们在对数据库进行一些大略操作的时候,我们可以直接通过调用一些方法就可以了,即是是帮我们已经完成了一些大略的CRUD操作; 但是一些繁芜的查询操作,我们还是须要自己在 Dao中编写查询语句(hql或者是sql),不论是hibernate还是 SpringDataJPA 都没有将Sql语句与java 代码分离, 而mybatis却做了这一点: mybatis的映射配置文件中有三部分: 1.输入映射; 2.输出映射;3. sql语句映射; 个中输入输出映射完成了类似orm映射的功能,完成类与表的对应; 而sql语句映射实在是供应了一些固定的sql操作,然后我们通过:
1. sql映射的namespace 利用Dao接口的 全限定名
2.sql映射的 statementId 与Dao接口的方法名同等
3.sql映射的parameterType与Dao中方法的参数类型同等
4.sql映射的resultType与Dao中方法的返回值类型同等
以上四点约定,我们的sql映射实际上已经成为往后Mybatis利用Mapper代理办法时,Spring创建代理的依据; 以是说某种程度上说mapper映射文件中的sql映射部分可以视作是Dao接口的实现类; 这样实在实现了 “实现类”到”映射文件”的转变( java代码----->xml配置的转变), 将sql语句从java 代码中抽离出来了;
2.配置内容:
<!-- 配置sqlSessionFactoryBean -->
<bean id=\"大众sqlSessionFactory\公众 class=\"大众org.mybatis.spring.SqlSessionFactoryBean\公众>
<!-- 注入连接池 -->
<property name=\"大众dataSource\"大众 ref=\公众dataSource\公众></property>
<!-- 加载mybatis 核心配置文件 -->
<property name=\公众configLocation\"大众 value=\公众classpath:mybatis/SqlMapConfig.xml\公众/>
</bean>
操作数据库大略解释:我在前面总结持久层框架的时候喜好将配置分为两部分:
连接数据库 : 得到SessionFactory操作数据库 : 将SessionFactory 与dao领悟;2.配置内容:
<!-- 第一种办法: 通过设置mapper接口 ; 缺陷:一次只能配置一个接口-->
<!-- <bean class=\"大众org.mybatis.spring.mapper.MapperFactoryBean<T>\"大众>
<property name=\"大众sqlSessionFactory\公众 ref=\"大众sqlSessionFactory\"大众></property>
<property name=\公众mapperInterface\"大众 value=\公众cn.itheima.mybatis.mapper.UserMapper\"大众></property>
</bean> -->
<!-- 第二种办法: 通过对mapper包扫描;
优点:1.可以对mapper包下的所有接口完成代理; 2.会自动注入 sqlSessionFactory -->
<bean class=\"大众org.mybatis.spring.mapper.MapperScannerConfigurer\"大众>
<property name=\公众basePackage\"大众 value=\"大众cn.itheima.mybatis.mapper\"大众/>
</bean>
上边两种配置都可以完成 sqlSessionFactory 与Dao的领悟,但是第二种更有上风: 我们大略剖析一下: 它是通过扫描包,然后找到包下的接口,然后读取到包下同名的mapper.xml映射文件,然后根据 接口和映射文件创建 接口实现类工具;
8.持久层框架配置套路总结:实在:持久层无非做了两件事: 1.连接数据库, 2操作数据库 ;环绕这两件事每个框架都各有千秋,但是它们与Spring整合时的配置该当是有一些套路的:
1 . Spring 的JdbcTemplate
这个类简化了JDBC操作,
它的基本操作: update(sql语句, 参数); query(sql语句, 参数);
操作流程如下:
配置驱动连接池 (可以用默认的,也可以单独配比如C3P0连接池),属性注入连接参数: driven, url , username , password配置 JdbcTemplate我们可以在java类中直接注入 JdbcTemplate 进行CRUD操作;2.hibernate:
这是一个orm框架,通过映射文件,实现了对数据库表的操作 到 对类的工具操作的转化
操作流程如下:
将基本连接参数分离成一个.properties文件在application.xml中引入.properties文件配置连接池 (注入连接参数)配置 LocalSessionFactory (注入1.连接池; 2.数据库基本配置; 3.映射文件位置 )编写dao 继续 HibernateDaoSupport类 并在配置dao (注入sessionFactory, 实质上是注入到HibernateDaoSupport 中) 这样在dao中就可以得到: hibernateTemplate 模板工具;利用模板工具进行CRUD操作,这个时候操作的,这个模板工具也是简化hibernate数据访问操作;3.SpringDataJPA
1. 将基本连接参数分离成一个.properties文件
2. 在application.xml中引入.properties文件
3. 配置连接池 (注入连接参数)
4. 配置LocalContainerEntityManagerFactoryBean
注入 : 1.连接池; 2.domain扫描包路径(相称于映射文件配置); 3.持久化供应者; 4.其他数据库基本配置;
<property name=\"大众dataSource\"大众 ref=\"大众dataSource\"大众 />
<property name=\"大众packagesToScan\"大众 value=\"大众cn.itcast.bos.domain\"大众 />
<property name=\公众persistenceProvider\"大众>
<bean class=\"大众org.hibernate.jpa.HibernatePersistenceProvider\"大众 />
</property>
...
5. Jpa扫描dao; 这一步等价于hibernate中的 dao配置,hibernate中是给dao中注入sessionFactory,使到可以得到hibernateTemplate模板, 这个地方 通过扫描dao的办法,在得到dao工具时通过AOP技能供应给我们默认的dao实现;
<jpa:repositories base-package=\"大众cn.itcast.bos.dao\"大众 />
4.redis
1.配置连接池 JedisPoolConfig
2.配置连接工厂 JedisConnectionFactory
3.配置模板 RedisTemplate
4.java代码中操作:
redisTemplate.opsForValue().set(model.getTelephone(), activeCode, 24, TimeUnit.HOURS);
5.小结:
通过比较持久层这个几个配置,我们可以看出来,Spring在全体各种框架是,基本套路也便是:
配置连接参数, 2.配置连接池, 3.配置连接工厂 4.配置模板;比较之下: SpringDataJPA做的事情更多一些,它没有直接供应给你一个模板,而是编写了一个默认实现,你只要让你的dao实现了JPARepository / JpaSpecificationExecutor , 在配上 jpa扫描:
<jpa:repositories base-package=\"大众cn.itcast.bos.dao\"大众 />
在你注入这个包下的工具时,它就会判断你是否继续了 JPARepository / JpaSpecificationExecutor 这些接口,如果继续了,那么它会利用AOP返给你一个默认实现的类,而在这个类中,已经给我们默认实现了一些CRUD常用操作,以是避免了常用CRUD操作的方法编写;