JDBCTemplate
1、JdbcTemplate概述
什么是 JdbcTemplate(Template)译为模板?
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。它是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作 模板类。例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nosql数据库的RedisTemplate,操 作消息队列的JmsTemplate等等。
2、JdbcTemplate开发步骤
① 导入spring-jdbc和spring-tx坐标
<!--导入spring的jdbc坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.5.RELEASE</version></dependency><!--导入spring的tx坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.5.RELEASE</version></dependency>
② 创建数据库表和实体
publicclassAccount { privateStringname; privatedoublemoney; publicStringgetName() { returnname; } publicvoidsetName(Stringname) { this.name=name; } publicdoublegetMoney() { returnmoney; } publicvoidsetMoney(doublemoney) { this.money=money; } publicStringtoString() { return"Account{"+"name='"+name+'\''+", money="+money+'}'; } }
③ 创建JdbcTemplate对象
importcom.mchange.v2.c3p0.ComboPooledDataSource; importorg.junit.Test; importorg.springframework.context.ApplicationContext; importorg.springframework.context.support.ClassPathXmlApplicationContext; importorg.springframework.jdbc.core.JdbcTemplate; importjava.beans.PropertyVetoException; publicclassJdbcTemplateTest { //测试Spring产生jdbcTemplate对象publicvoidtest2() throwsPropertyVetoException { ApplicationContextapp=newClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplatejdbcTemplate=app.getBean(JdbcTemplate.class); introw=jdbcTemplate.update("insert into account values(?,?)", "lisi", 5000); System.out.println(row); } //测试JdbcTemplate开发步骤publicvoidtest1() throwsPropertyVetoException { //创建数据源对象ComboPooledDataSourcedataSource=newComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); dataSource.setUser("root"); dataSource.setPassword("root"); JdbcTemplatejdbcTemplate=newJdbcTemplate(); //设置数据源对象 知道数据库在哪jdbcTemplate.setDataSource(dataSource); //执行操作introw=jdbcTemplate.update("insert into account values(?,?)", "tom", 5000); System.out.println(row); } }
④ 执行数据库操作
importorg.junit.Test; importorg.junit.runner.RunWith; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.jdbc.core.BeanPropertyRowMapper; importorg.springframework.jdbc.core.JdbcTemplate; importorg.springframework.test.context.ContextConfiguration; importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner; importjava.util.List; SpringJUnit4ClassRunner.class) ("classpath:applicationContext.xml") (publicclassJdbcTemplateCRUDTest { privateJdbcTemplatejdbcTemplate; publicvoidtestQueryCount(){ Longcount=jdbcTemplate.queryForObject("select count(*) from account", Long.class); System.out.println(count); } publicvoidtestQueryOne(){ Accountaccount=jdbcTemplate.queryForObject("select * from account where name=?", newBeanPropertyRowMapper<Account>(Account.class), "tom"); System.out.println(account); } publicvoidtestQueryAll(){ List<Account>accountList=jdbcTemplate.query("select * from account", newBeanPropertyRowMapper<Account>(Account.class)); System.out.println(accountList); } publicvoidtestUpdate(){ jdbcTemplate.update("update account set money=? where name=?",10000,"tom"); } publicvoidtestDelete(){ jdbcTemplate.update("delete from account where name=?","tom"); } }
Spring产生JdbcTemplate对象
我们可以将JdbcTemplate的创建权交给Spring,将数据源DataSource的创建权也交给Spring,在Spring容器内部将 数据源DataSource注入到JdbcTemplate模版对象中,配置如下:
<!--加载jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源对象-->
<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.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--jdbc模板对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/testjdbc.username=rootjdbc.password=root
拦截器
1、拦截器的作用
Spring MVC 的拦截器(interceptor)类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。在访问被拦截的方 法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
2、拦截器和过滤器区别
区别 | 过滤器(Filter) | 拦截器(Interceptor) |
使用范围 | 是 servlet 规范中的一部分,任何 Java Web 工程都可以使用 | 是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用 |
拦截范围 | 在 url-pattern 中配置了/*之后, 可以对所有要访问的资源拦截 | 在中配置了/**之 后,也可以多所有资源进行拦截,但是可以通 过标签 排除不需要拦截的资源 |
3、拦截器是快速入门
自定义拦截器很简单,只有如下三步:
① 创建拦截器类实现HandlerInterceptor接口
importorg.springframework.web.servlet.HandlerInterceptor; importorg.springframework.web.servlet.ModelAndView; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; publicclassMyInterceptor1implementsHandlerInterceptor { //在目标方法执行之前 执行publicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler) throwsServletException, IOException { System.out.println("preHandle....."); Stringparam=request.getParameter("param"); if("yes".equals(param)){ returntrue; }else{ request.getRequestDispatcher("/error.jsp").forward(request,response); returnfalse;//返回true代表放行 返回false代表不放行 } } //在目标方法执行之后 视图对象返回之前执行publicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, ModelAndViewmodelAndView) { modelAndView.addObject("name","itheima"); System.out.println("postHandle..."); } //在流程都执行完毕后 执行publicvoidafterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, Exceptionex) { System.out.println("afterCompletion...."); } }
② 配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--对哪些资源执行拦截操作-->
<mvc:mapping path="/**"/>
<bean class="com.xmp.interceptor.MyInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
③ 测试拦截器的拦截效果
测试再访问时实现被拦截效果
4、多拦截器操作
同上,在编写一个MyHandlerInterceptor2操作,测试执行顺序
importorg.springframework.web.servlet.HandlerInterceptor; importorg.springframework.web.servlet.ModelAndView; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; publicclassMyInterceptor2implementsHandlerInterceptor { //在目标方法执行之前 执行publicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler) throwsServletException, IOException { System.out.println("preHandle22222....."); returntrue; } //在目标方法执行之后 视图对象返回之前执行publicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, ModelAndViewmodelAndView) { System.out.println("postHandle2222..."); } //在流程都执行完毕后 执行publicvoidafterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, Exceptionex) { System.out.println("afterCompletion2222...."); } }
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--对哪些资源执行拦截操作-->
<mvc:mapping path="/**"/>
<bean class="com.xmp.interceptor.MyInterceptor2"/>
</mvc:interceptor>
<mvc:interceptor>
<!--对哪些资源执行拦截操作-->
<mvc:mapping path="/**"/>
<bean class="com.xmp.interceptor.MyInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
5、拦截器方法说明
方法名 | 说明 |
preHandle() | 方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的, 当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会 再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle方 法 |
postHandle() | 该方法是在当前请求进行处理之后被调用,前提是preHandle 方法的返回值为 true 时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调 用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象 进行操作 |
afterCompletion() | 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图 之后执行,前提是preHandle 方法的返回值为true 时才能被调用 |