导图社区 框架Spring
Web MVC Spring 对web部分 以及 MVC设计模式的支持。
编辑于2020-11-20 09:52:24Spring MyBatis框架
框架的构成
IOC容器 控制反转容器 它是构成Spring的核心
什么是IOC
Inversion Of Control 控制反转
程序中需要某个对象时,由原来的new的方式 变成了由容器来进行 创建 管理 和 维护组件关系。
这样做的好处是可以大大降低组件之间的耦合度。
Spring IOC概念和实现原理
概念: 技术解释-->个人理解-->优缺点-->项目应用
IOC 控制反转、反向控制;将组件对象创建、对象管理、对象关系交给第三方IOC容器负责;实现了组件关系解耦,缺点大量配置;项目中Dao、Service、Controller、连接池等组件都交给IOC容器管理实现解耦。
原理: 技术结构-->关键技术运用-->源码组件及作用
IOC主要采用DI技术实现,DI依赖注入,依赖注入有3种,分别是构造器注入、set注入、接口注入等,目前还有注解注入应用方式。 DI技术底层是基于反射技术实现,利用反射可以动态创建对象、动态调用构造器或set等方法将值注入。Class、Method、Field、Annotation等
Spring 容器的作用
任何java类 都可以在Spring 创建对象 并交给容器来进行管理和维护
Spring 容器实现了IOC 和 AOP 机制
Spring 容器对应的类型 有 BeanFactory 和 ApplicationContext 类型
Spring 容器完成IOC的使用步骤
案例:使用 Spring 容器 获取一个日期类型的对象:
建立一个项目 导入jar包(ioc)
拷贝spring容器配置文件(xml)到src下
在配置文件中 配置java类的说明
<bean id="java对象引用名" class="包名.类名" />
构建Spring 容器对象 从容器中获取对应的java对象
// 创建Spring 容器对象 并关联配置文件 ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//相对路径
abstractApplicationCont app.close();可以关闭容器 (对Spring容器中的对象即将销毁)
// 从容器中获取对象 Date date = (Date)app.getBean("date"); Date date2 = app.getBean("date", Date.class);
Spring创建容器的三种方式
构造器方式实例化
<bean id="java对象引用名" class="包名.类名" /> 默认调用 类型对应的无参构造
静态工厂方法实例化
<bean id="bean引用名" class="包名.工厂类名" factory-method="静态工厂方法名"/> 实际就是通过工厂的类名 调用对应的静态方法
实例工厂方法实例化
<bean id="bean引用名" factory-bean="工厂对象引用名" factory-method="工厂类对应的实例(成员)方法名" /> 使用工厂对象调用对应的工厂类对应的实例化方法得到另外一个类型对象
Spring 容器中对象的作用域
Spring 容器中创建的对象默认是 单例的 可以通过 bean标记的 scope="prototype"属性来指定成非单例的 以及 request session 等. 现在只涉及到单例和非单例。
Spring 容器中对象的初始化和销毁
初始化
对Spring 容器中的对象初始化
可以通过beans标记中的 default-init-method="初始化方法名" 这样容器中所有的对象都会受到影响,这种方式影响的范围比较大 所以当某个类型中没有对应的初 始化方法时程序也不会报错。
也可以在bean 标记中 加 init-method="初始化方法名" 这样只针对一个具体的类型 所以这个类型没有对应的初始化方法时 程序会报错。
销毁
对Spring容器中的对象即将销毁
可以通过beans标记中的default-destroy-method="销毁方法名" 这样容器中所有的对象都会受到影响,这种方式影响的范围比较大 所以当某个类型中没有对应的 销毁方法时程序也不会报错。
也可以在bean 标记中 加 destroy-method="销毁方法名" 这样只针对一个具体的类型 所以这个类型没有对应的销毁方法时 程序会报错。 当然销毁方法只针对单例模式
bean对象的延迟实例化
Sping容器中 单例对象默认是容器启动时创建 在bean中可以通过lazy-init="true" 让其使用到的时候再去创建 .因为lazy-init默认是false
什么是DI
Dependence Injection 依赖注入 依赖注射
解决的问题是组件的装配问题
DI的实现方式
setter注入(基于set方法的注入)
<bean id="" class="" > <property name="属性名(把set去掉首字母小写之后去容器中查找对应的对象id)" ref="容器中组件id"></property> </bean>
注意如果属性的值是简单值(8种基本类型和封装类String 枚举) 则把ref换成 value自己赋值
构造器注入
参考的是构造方法的参数(可以是参数的名字 也可以是参数的位置)
<bean id="" class="" > <constructor-arg name="属性名" ref="容器中组件id"></constructor-arg> </bean>
必须有合适的构造方法
如果参考的是参数的位置 则把name 写成index 编号从0开始
自动化注入(了解)
默认自动化注入是关闭的 可以在bean 标记中加 autowire="byName | byType | construct"
byName
通过名字补全,参考的是属性名 和setter注入相似
byType
按照成员变量的类型加载
contructor
按照构造器匹配去加载 当然可以使用 constructor-arg 占参数位置 剩余的参数 可以自动注入
参数的注入
简单值的注入
八种基本类型 和封装类 String 枚举
枚举:
//在java里 :枚举名.常量 Suit s=Suit.SPADE; sysout(s)
提供getset构造方法
在Spring :常量
我们定义常量都是: public static final.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
练习: 创建一个连接池对象 并获取连接池对象 以及还有从连接池中获取连接
1.导入包
<!-- 创建一个连接池对象 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"></property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </bean>
复杂值
只要把上面的value 换成ref
集合类型的参数
java中的常见集合
List Set Map Properties 在Spring 配置文件中 都有对应的标记
List : <list> <value>值</value> </list> Set : <set> <value>值</value> </set> Map : <map> <entry key="" value="值" /> </map> Properties:<props> <prop key="">值 </prop> </props>
集合类型参数的单独定义
<util:list <util:set <util:map <util:properties
Properties 单独定义时 可以关联一个 .properties 文件
<!-- 单独定义Properties 时 关联一个配置文件 --> <util:properties id="ref_db" location="classpath:db.properties"> </util:properties>
Spring EL表达式
他是从Spring 容器中获取值 (id标签)
语法是把之前的$换成#
组件扫描(composenent scan)
它是Spring 框架提供的基于基础的一套技术 目的是为了简化xml的配置
组件扫描的实现步骤
创建一个项目 导入jar包(ioc aop) 拷贝配置文件到src
在配置文件中开启组件扫描
<context:component-scan base-package="包结构名(com.xdl)"/>
编写一个java类
在这个类上 打对应的标注
Spring创建容器的三种方式的简化
@Component
通用层标注
默认组件名是类名首字母小写
可以通过value 属性 指定名字
@Component(value="cc")
如果组件中只有1个value 属性时 value可以省略
@Component"cc")
@Repository
持久层标注
内存数据存入磁盘dao
@Controller
控制层标注
servlet
@Service
服务层标注
业务逻辑层
创建Spring容器 从容器中获取组件
组件扫描相关的其他标注
控制作用域
@Scope ("singleton |prototype") 单例 非单例
Spring 容器中对象的作用域的简化
控制初始化
@PostConstruct
加在初始化方法上
对Spring 容器中的对象初始化的简化
控制销毁的
@PreDestroy
加在销毁方法上
对Spring容器中的对象即将销毁的简化
和DI相关的标注
@Value()
可以用在成员变量 set方法上 如果是基本值直接在标注写值 如果是复杂值需要使用Spring El表达式赋值
DI的实现方式的简化
@Autowired
可以用在成员变量 set方法 构造方法上 它一般用来解决复杂值赋值的
这个标注 优先使用类型进行匹配 如果类型有冲突 则启用名字进行匹配
冲突:在xml文件配置
@Qualifier("容器中的对象名")
用来指定名字进行查找 这个标注不能用在构造方法上
@Autowired
默认对组件强依赖 可以通过request=false 代表尽量去查找组件 找不到也不不报错
@Resource
可以用在成员变量 set方法上 它也是解决复杂值的
这个标注 优先使用名字进行匹配 如果匹配不上 会启动类型进行匹配
这个标注不是 Spring框架的 是jdk中的标注
这个标注可以使用 name指定名字进行查找 不能解除组件依赖关系
DAO 数据访问对象 它是Spring 对JDBC的简化和封装
Spring Dao 对jdbc做了哪些改进
简化和封装了jdbc的API 可以更方便的编写DAO实现类组件
提供了基于AOP模式的事务管理
对jdbc中的异常 做了封装 把原来的检查异常封装成了一个继承自RuntimeException的DataAccessException
Spring DAO的核心类 jdbcTemplate
可以用来自动加载驱动 获取连接 获取执行环境 释放资源
jdbcDaoSupport 这个类 可以提供jdbc Template 模板对象
采用继承jdbcDaoSupport 的方式 完成对xdl_bank_account的记录数查询
1.建立一个项目 导入jar包( ioc aop dao 连接池和数据库驱动)并拷贝配置文件到src下
2.编写dao接口
编写dao接口的实现类 采用继承jdbcDaoSupport的方式
3.1需要给jdbcDaoSupport 类注入一个dataSoure(dataSoure需要在xml配置)
@Autowired public XdlBankAccount(DataSource dataSource) { // 把 dataSource设置给父类 super.setDataSource(dataSource); }
3.2开启组件扫描
<context:component-scan base-package="com.xdl"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:xe"></property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </bean>
3.3使用模板完成查询
编写sql语句
super.getJdbcTemplate().queryForInt(sql);
super.getJdbcTemplate().queryForInt(sql, acc_no);
super.getJdbcTemplate().queryObject(sql,String.class ,id );
要求返回结果集时 需要我们来写 结果集转换成对象的过程
需要写一个类实现 RowMapper 接口
@Override public XdlBankAccount mapRow(ResultSet rs, int index) throws SQLException { // 如何把结果集转换成对象 XdlBankAccount account=new XdlBankAccount(); account.setId(rs.getInt("id")); account.setAcc_no(rs.getString("acc_no")); account.setAcc_money(rs.getInt("acc_money")); return account; }
super.getJdbcTemplate().queryForObject(sql, new XdlBankAccountMapper(), id);
List<XdlBankAccount> datas = super.getJdbcTemplate().query(sql, new XdlBankAccountMapper(),acc_no,acc_password); return datas.isEmpty()?null:datas.get(0);
super.getJdbcTemplate().query(sql,new XdlBankAccountMapper());
如何完成增 删 改
使用模板对应的update 方法
super.getJdbcTemplate().update(sql,id);
4.从spring容器中获取dao 测试查询
采用不继承jdbcDaoSupport方式
1.建立一个项目 导入jar包( ioc aop dao 连接池和数据库驱动)并拷贝配置文件到src下
2.编写dao接口
编写dao接口的实现类 只实现dao接口
不继承jdbcDaoSupport的话 需要我们自己创建jdbcTemplate 对象注入给dao的实现类. djbcTemplate 对象也是需要dataSource
<!-- 扫描组件 --> <context:component-scan base-package="com.xdl"/> <!-- 创建一个模板对象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg index="0" ref="dataSource"></constructor-arg> </bean> <!-- 创建一个连接池对象 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url"><value>jdbc:oracle:thin:@127.0.0.1:1521:xe</value></property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </bean>
开启组件扫描 注入模板 把dao的实现类加载到容器 使用自己的模板完成查询
@Autowired private JdbciTemplate jdbcTemplate;
return jdbcTemplate.queryForObject(sql, Integer.class);
从Spring容器获取组件 测试
service加get set方法
如何实现转账
底层dao 的两个更新操作
运行时异常 回滚
throw new RuntimeException("转账失败")
检查时异常不回滚
throw new Exception("转账失败")
Spring 的声明式事务管理
通过配置形式 将事务管理纳入程序之中
正常业务逻辑代码和事务代码进行了分离 形成了低耦合设置
事务管理代码 在不需要时 可以随时移除 实现了可插拔式编程
Spring 声明式事务的实现步骤
开启声明式事务
<tx:annotation-driven transaction-manager="事务管理器ID" proxy-target-class="false|true"/>
创建事务管理器
这个管理器依赖于 dataSource
<bena id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> // 注入dataSource <property ref="dataSource" name="dataSource"/> </bean>
在业务类 或者业务方法上加@Transactional
@Transactional的属性
rollbackFor
Spring 的事务管理 默认只针对运行时异常进行回滚 可以通过属性 rollbackFor 来设置针对的检查异常回滚。
@Transactional( rollbackFor={Exception.class})
noRollbackFor
针对指定的运行时异常不回滚。
readOnly
代表事务只读 如果是true 代表事务中不能有增删改 只要事务中有增删改 则该值必须为false 否则程序报错。
readOnly =true
isolation 设置事务的隔离级别
隔离级别有 未读提交 READ_UNCOMMITTED 读提交 READ_COMMITTED 可重复读 REPEATABLE_READ 序列化 SERIALIZABLE
(isolation=isolation.隔离级别)
隔离级别是解决数据库中的三大读问题的:
脏读
一个事务读取到了另外一个事务 没有提交的数据
读提交解决了脏读问题默认读提交
不可重复读
一个事务在开始时读取了一份数据,在事务进行的过程中 另外一个事务 修改了这份数据 并进行了提交, 当第一个事务再次读取到这份数据时 发现数据发送了改变
可重复读解决了不可重复读问题(也可以解决脏读问题)
幻读
一个事务统计了整张表的所有数据, 这个时候另外一个表对数据进行了增加 当第一个事务再次统计数据时,发生了数据的改变
序列化级别解决幻读问题
propagation事务的传播特性
一个方法 去调用事务方法时 应该具有的表现
Propagation=Propagation.REQUIRED
当前方法如果没有事务则会开启新事务,如果当前方法有事务 则把事务方法中的事务加入当前的事务之中
S
Web MVC Spring 对web部分 以及 MVC设计模式的支持
5大核心组件
DIspatcherServlet
控制器 请求入口
HandlerMapping
控制器 请求的派发 和让请求路径和控制器建立一一对应的关联关系
Controller
控制器 处理请求流程
ModelAndView
模型和视图 用来封装数据信息和视图信息
viewResolver
视图处理器找到对应的视图
运行流程
请求到达DispathcherServlet,然后把请求交给HandlerMapping ,然后会让请求和控制器建立一一对应关系,然后由请求找到对应的控制器 控制器会对请求做处理 然后返回ModelAndView ,然后交给viewResolver 找到对应的视图对应的页面
使用SpringMVC 编写程序的步骤(2.3)(无标注)
建立一个项目 在WEB-INF建立一个hello.jsp 导入jar包(ioc mvc) 拷贝配置文件到src下
在web.xml 配置DispatcherServlet 并通过 contextConfigLocation这个初始化参数 指定Spring 配置文件
<!-- 配置DispatcherServlet --> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
在Spring配置文件中配置HandlerMapping的实现类 SimpleUrlHandlerMapping 指定请求路径和控制器的对应关系
<!-- 配置HandlerMapping --> <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- 让请求和控制器建立一一对应的关联关系 --> <prop key="/toHello.do">和控制器id一致</prop> </props> </property> </bean>
编写一个类实现 Controller接口 实现接口方法 返回ModelAndView 并在配置文件中 配置Controller 对象
ModelAndView mav = new ModelAndView(); mav.setViewName("hello"); return mav;
(有标注中控制器返回ModelAndView)
</bean> <!-- 配置 控制器 --> <bean id=" " class=控制器包名.类名"> </bean
Sub Topic
配置视图处理器 ViewResolver的实现类InternalResourceViewResolver 配置prefix suffix
<!-- 配置视图处理器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"></property> <property name="suffix" value=".jsp"></property> </bean>
基于标注的Spring MVC(2.3)(访问WEB-INF下的login.jsp)
新建一个项目 导入jar包(ioc aop mvc)拷贝配置文件到src下
配置DispatcherServlet 并通过ContextConfigLocation 指定配置文件位置
开启组件扫描 和开启标注形式mvc
<context:component-scan base-package="" />
<mvc:annotation-driven/>
相当于配置了一个HandlerMapping组件的实现类RequestMappingHandlerMapping
编写一个类 不用实现Controller 接口 控制器方法的返回值 方法名(参数) 就自由了 返回值:可以返回String 和 ModelAndView
使用@Controller
在spring容器创建对象(可以普通类变成了控制器)
使用@RequestMapping(/路径) 加在控制器方法上
请求路径和控制器建立了连接
配置视图处理器 配置前缀和后缀
Spring MVC控制器中如何接受页面请求参数(2.3)
使用原来的方式
request.getParameter();
直接在控制器方法中定义和请求参数名相同的控制器参数即可
当页面请求参数和控制器请求参数不一致时(2.3)
@Requestparam("页面参数名)
直接定义对象类型的参数
SpringMVC中如何把数据传递给页面(转发)(2.3)
使用域对象进行传输
使用ModelAndView进行传输
控制器返回值类型必须是ModelAndView
//先获取模型对象 ModelAndView mav //方式一.然后赋值 mav.getModel().put("K",V); //方式二..然后赋值 mav.getModelMap().addAttribute("K,V")
//设置视图信息 mav.setViewName("main")
只能放在request
使用Model来进行参数传递
//先获取模型对象 ModelMap mm //方式一 mm.put("K",V); //方式二 mm.addAttribute("K",V);
使用复杂的对象类型参数自动传递
直接定义对象类型的参数
取值:${类名首字母小写.属性}
用@ModelAttribute("")
取值:${属性名.属性}
页面用${ } jsp接收
SpringMVC中如何实现重定向和转发(2.3)
当控制器方法返回String类型时
只要在返回值前面加redirect:
重定向
@RequestMapping("/toMain.do") public String toMain(){ return "main"; } @RequestMapping("/login11.do") public String login11(String acc_no,String acc_password){ return "redirect:toMain.do"; }
重定向无法传数据
只要在返回值前面加forward:
转发
@RequestMapping("/toMain.do") public String toMain(){ return "main"; } @RequestMapping("/login11.do") public String login11(String acc_no,String acc_password,Model m){ m.addAttribute("acc_no", acc_no); return "forward:toMain.do"; }
虽然默认转发是因为只有1层动作直接到jsp,但是如果经过多个.do请求才能到达页面的话 需要用forward:
当控制器方法返回ModelAndView时 RedirectView来完成重定向
@RequestMapping("/toMain.do") public String toMain(){ return "main"; } @RequestMapping("/login12.do") public ModelAndView login12(String acc_no,String acc_password){ // 重定向到 toMain.do RedirectView rv = new RedirectView("toMain.do"); mav.setView(rv); return mav; }
SpringMVC中文参数乱码问题(2.3)
tomcat8下 get方式中文没有乱码
如何处理哦post方式下的乱码问题
之前的方式依然可用 但必须完全遵守之前的方式
先设置乱码格式 再接收值
使用编码配置(web.xml)过滤器(2.3)
<!-- 配置编码过滤器 --> <filter> <filter-name>XldFilter</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>XldFilter</filter-name> <url-pattern>*.do</url-pattern><!-- /login.do 只针对过滤一个请求,处理过滤很多请求 *.do /*过滤所有请求 --> </filter-mapping>
Spring 拦截器(2.3)
作用
和过滤器类似 具有登录验证 身份认证 资源加密访问 编码设置等功能 可以在不修改源代码的情况下 对请求和响应增加功能进行可插拔式编程
实现HandlerInterceptor接口
preHandle()
这个方法返回值类型boolean 返回true代表继续调用后续逻辑 一般是指调用下一个拦截器 如果没有拦截器 则调用控制器方法. 如果返回false 则终止后续逻辑
HandlerMapping之间Controller
postHandle()
控制器 调用之后 视图处理器之前 返回void
Controller之间ModelAndView
afterCompletion()
视图处理器之后 响应之前执行 返回值void
ModelAndView之间viewResolver
使用步骤
写一个java类 实现HandlerInterceptor接口
实现对应的拦截器方法
在Spring 配置文件中配置拦截器(2.3)
<!-- 配置拦截器 --> <mvc:interceptors><!-- 多个拦截器 --> <mvc:interceptor> <mvc:mapping path="/**"/><!-- 拦截哪些请求 --><!--/**拦截一级或多级请求 --> <mvc:exclude-mapping path="/tologin.do"/><!--不拦截哪些请求 --> <bean class="cn.lt.interceptor.XdlLoginInterceptor"></bean><!--路径 --> </mvc:interceptor>
练习:如果session 中有acc_no 则放行需要进行登录的请求 如果session中没有acc_no 则需要用户去登录.默认不过拦截器 请求有 tologin.do login.do
Object obj=request.getSession().getAttribute("acc_no"); if(obj!=null){return true;} response.sendRedirect("tologin.do"); return false;
异常处理(2.3)
全局的异常处理
框架提供的异常处理器
SimpleMappngExceptionResolver
<!--配置异常处理 器 --> <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!--配置对应的异常 跳转到对应的页面--> <property name="exceptionMappings"> <props> <prop key="java.lang.Exception">error</prop> <prop key="java.lang.RuntimeException">rerror</prop> </props> </property> </bean>
if(1==1){throw new RuntimeException("出现了运行异常");}*/ if(1==1){throw new Exception("出现了检查异常");}
添加要出现异常的控制器中
创建2个jsp error和 rerror
自定义异常处理器
HandlerExceptionResolver
创建一个类实现这个接口
@Controller public class XdlMyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2,Exception e) { ModelAndView mav = new ModelAndView(); // 判断不同的异常 跳转到不同的页面 if(e instanceof RuntimeException){ mav.setViewName("rerror");}else{ mav.setViewName("error"); } return mav; } }
创建2个jsp error和 rerror
局部异常处理
@ExceptionHandler
这个异常处理只针对这一个控制器 控制器方法上 这个控制器方法上必须有一个异常类型的参数
@ExceptionHandler public String processError(Exception e){ return "merror"; }
文件上传(2.3)
1.编写一个文件上传的界面
1.新建一个jsp form表单属性
method="post" enctype="multipart/form-data"
input属性type="file"
2.编写一个文件上传的控制器
使用MultiPartFile 类型接收文件数据 需要借助第三方jar解析请求
@Controller public class FileUploadController { @RequestMapping("/toUpload.do") public String toUpload(){ return "upload"; } //局部异常 @ExceptionHandler public String processError(Exception e){ return "ferror"; } @RequestMapping("/upload.do") public String upload(String acc_no,MultipartFile mf,HttpServletRequest request){ System.out.println(acc_no + ":" + mf.getName() + ":" +mf.getOriginalFilename()+ ":" + mf.getSize() ); String fileName=mf.getOriginalFilename();//获取文件名字 String suffix= fileName.substring(fileName.lastIndexOf("."));//最后一个.的位置切下来拿到后缀 String fname=UUID.randomUUID().toString()+suffix;//用UUID得到一个不重复的名字 String fpath=request.getServletContext().getRealPath("imgs");//获取webContent下的imgs文件夹路径 File file=new File(fpath+"/"+fname); try{ mf.transferTo(file);//把这个文件数据转移到文件里 }catch(Exception e){e.printStackTrace();} request.setAttribute("img", "imgs/"+fname); return "show"; } }
<!--图片上传配置文件解析器 --> id必须是这个 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> //如果太大需要抛出异常 添加下面配置 <property name="maxUploadSize" value="10240"></property>//文件最大多少KB <property name="resolveLazily" value="true"></property> <!-- 异常延迟抛出 当用到局部异常的时候使用 --> </bean>
Spring MVC中如何返回json (就可以用ajax接收)
前提搭建完了标注型MVC
对控制器方法做改进
public 要返回的是数据类型 方法名(参数){ //把什么数据变成json 就返回什么数据 }
在控制器类上加@ResponseBody或加在控制器方法上
告知框架这个返回值不走viewResolver还会把数据变成json
变成json时需要依赖于 第三方jar包
rest架构
什么是rest
REST即表达性状态传递 Representational State Transfer,他是一个抽象的概念,主要基于http协议的一种软件架构风格 由于底层以json进行通信 所以大大降低了应用之间的耦合 提高了系统的可伸缩性 便于分布式程序开发.
rest具体做了哪些规范
对请求路径,由原来基于操作的设计改成了 基于资源的设计
/account/1
对http的请求方式做了规范
get查询
post增加更新
/new
put更新
delete 删除
什么是restful
符合rest风格 和约束的应用程序 或者设计 叫restful
rest 对 Spring MVC的支持
首先要搭建一个基于标配的mvc 并且可以支持控制器中的方法返回json
方法的设计根据基于返回json设计即可 返回json加@ResponseBody 不返回就不加
设计请求路径在@RequestMapping中设计请求路径 {变量}叫路径变量 @RequestMapping(value="/account/{id},method=RequestMethod.枚举值") public 返回值 方法(@PathVariable int id){ }
由于请求路径没有后缀则需要吧web.xml 中url-parttern 改成 / 但是这样会拦截所有的静态资源 需要对静态资源放行
<!-- 放行静态资源 --> <mvc:default-servlet-handler/>
使用rest风格完成account增删改查(ajax)
查询
@RequestMapping(value="/account/{id}",method=RequestMethod.GET) @ResponseBody public XdlBankAccount findAccountById(@PathVariable int id){ System.out.println(account); return account; }
function getAccount() { var id = $("#id").val(); $.ajax({ url : "account/" + id, type : "get", success : function(account) { $("#acc_no").val(account.acc_no); $("#acc_passwrod").val(account.acc_passwrod); $("#acc_money").val(account.acc_money); }}); }
添加
@RequestMapping(value = "account/new", method = RequestMethod.POST) @ResponseBody public boolean addAccount(XdlBankAccount account) { System.out.println(account); return true; }
function addAccount(){ var id=$("#id").val(); var acc_no=$("#acc_no").val(); var acc_passwrod=$("#acc_passwrod").val(); var acc_money=$("#acc_money").val(); $.ajax({ url:"account/new", type:"post", success:function(f){ alert(f) }, data:{id:id,acc_no:acc_no,acc_passwrod:acc_passwrod,acc_money:acc_money} }); }
删除
@RequestMapping(value = "account/{id}", method = RequestMethod.DELETE) @ResponseBody public boolean del(@PathVariable int id) { System.out.println(id); return true; }
function delAccount(){ var id=$("#id").val(); $.ajax({ url:"account/"+id, type:"delete", success:function(f){ alert(f) } }); }
更新
jsp中的设置
参考post方式
jsp中设置有 把post改成put
提交数据必须以jsion字符串提交
contentType:"application/json"
把json对象转换成json字符串
JSON.stringify(json对象)
data:
控制器中的设置
@RequestBody 把json转换java对象
加在参数前面
ID:<input id="id"> user:<input id="acc_no"> pass:<input id="acc_passwrod"> money:<input id="acc_money">
S
AOP 面向切面编程 它是面向对象的高度扩展
什么是aop
spect Oriented Programming 面向切面(方面)编程 ,它可以在不修改原有组件代码逻辑情况下追加新增功能。
Spring AOP概念和实现原理
概念 AOP 面向切面编程;将多个组件共同的业务抽离出来独立封装,然后通过配置再作用到那些组件中;重用性好,将共同业务和传统业务解耦,通过配置动态调用;项目中事务控制、日志记录都可以采用AOP实现。
原理 AOP主要采用动态代理技术实现,代理技术分为静态代理和动态代理。动态代理技术可以采用Cglib或JDK Proxy API实现,Spring底层采用这两种结合方式,默认有接口的组件采用JDK Proxy创建代理对象;没有接口的组件采用Cglib创建代理对象。
什么是切面
共通的业务逻辑
封装共通的业务逻辑的类 叫切面类
用这个类创建对象叫切面对象
AOP 中的核心概念
切面 Aspect
封装共同业务逻辑的
连接点 JoinPoint
共同业务逻辑 作用的位置 一般是一个方法位置
切点 Pointcut
它是一群连接点的集合
目标对象 Target
代理对象 Proxy
增加之后的对象
通知 Advice
指的是共同业务逻辑调用的时机
方法调用来时之前
调用之后
调用前后
最终
出现异常
Spring APO中五中通知类
<aop:fore 前置通知
目标方法执行之前调用切面方法
@Before
<aop:after 最终通知
目标方法执行之后 肯定会调用切面方法
@After
<aop:after-returning 后置通知
目标方法执行之后 调用切面方法目标方法出现异常就不调用了
@AfterReturning
运行时异常
throw new RuntimeException("")
检查时异常
throw new Exception("")
<aop:after-throwing 异常通知
目标方法抛出异常之后调用
@AfterThrowing
获取异常对象 需要使用throwing 属性 指定的名字和 切面方法中的参数一致 并且切面方法中异常参数 必须出现在最后。 使用JoinPoint 可以获取目标方法的信息。
@AfterThrowing(pointcut="within(com.xdl.service.*)",throwing="e")//异常对象 public void printSixStarts(JoinPoint jp//连接点,Exception e ){//异常参数必须放最后 System.out.println(e.getMessage()//得到异常信息jp.getSignature()//得到异常的方法名 );}(切面类)
可以用来做就监控 出了什么异常 哪个方法出的异常
<aop:around 环绕通知
目标方法执行的前后调用
@Around
统计方法的执行时间
@Around("within(com.xdl.service.*)") public Object callMethodTimes(ProceedingJoinPoint pjp) throws Throwable{ //1970到现在的毫秒数 long start=System.currentTimeMillis(); //调用目标方法 Object obj= pjp.proceed(); long stop=System.currentTimeMillis(); System.out.println("该方法用时:"+(stop-start)); return obj; } (切面类)
没有标准的AOP
先一个XdlUserService 类 其中定义 登录 和 注册 两个方法(伪代码即可) 从Spring 容器中创建对象 并获取对象 调用它的登录和注册的方法 。 在不修改源代码的情况下 给 这两个方法 调用开始前 输出 ******。(2.3无标注)(步骤如下)
建立一个项目 导入jar包(ioc aop) 拷贝配置文件到src下
开发一个XdlUserService类 定义方法
在Spring 配置文件中 配置 XdlUserService类
<!-- 配置目标对象 --> <bean id="userService" class="com.xdl.Service.XdlUserService"></bean>
创建Spring 容器 从容器中获取 对象 测试方法
定义一个切面类 XdlLogAspect 定义切面方法
在Spring 配置文件中 配置 XdlLogAspect类
<!-- 配置一个切面对象 --> <bean id="logAspect" class="com.xdl.aspect.XdlLogAspect"></bean>
在Spring 配置文件中 通过配置 将切面 切入到 对应的目标方法上
切面--通知--切点
<!-- AOP 的配置 --> <aop:config> //切面 //切面对象ID <aop:aspect ref="logAspect"> //切面共通逻辑方法名 //切点 //目标切点表达式 <aop:before method="printSixStarts" pointcut="bean(userService)"/> </aop:aspect> </aop:config>
再次测试 Service 类 看逻辑是否嵌入成功
切点表达式写法
bean限定表达式
bean(容器中组件的id) 容器中组件的id的支持统配写法如
bean(accountService) accountService中所有的方法都被切入共通逻辑
bean(account*) account开头的组件 中所有的方法都被切入共通逻辑
类型限定表达式 --最后一部分必须表达类型
within(com.xdl.service.XdlAccountService)对XdlAccoubntService这个类型对应的方法 都将切入共通逻辑
within(com.xdl.service.* ) 支持统配写法 对service 包中所有类型都起作用
within(com.xdl.*) xdl包下所有类型 对子包无效
within(com.xdl..*)
xdl包下 所有的类型 对子包有效
方法限定表达式
execution (权限修饰 方法返回值类型 方法名(参数) throws异常 )
其中 方法返回值 方法名(参数) 是必须的 其他不是必须的
基于标注的AOP
先一个XdlUserService 类 其中定义 登录 和 注册 两个方法(伪代码即可) 从Spring 容器中创建对象 并获取对象 调用它的登录和注册的方法 。 在不修改源代码的情况下 给 这两个方法 调用开始前 输出 ******。(2.3标注)(步骤如下)
建立一个项目 导入jar包(ioc aop) 拷贝配置文件到src下
开发一个XdlUserService类 定义方法
@Service("userService")
开启组件扫描 并在类上打对应的标注
!-- 开启组件扫描 --> <context:component-scan base-package="com.xdl"></context:component-scan>
创建Spring容器 从容器中获取对象 测试方法
编写一个切面类 里面定义切面方法
在切面类上加组件创建的标注 和开启标注形式的aop
@Component
<!-- 开启标注形式的 aop --> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
在切面类上打一个标注@Aspect(切面) 通知标注 切点表达式
@Component @Aspect -------------------------- public class XdlLogAspect { @Before/@After/ @AfterReturning("within(com.xdl.srvicee.*)") public void printSixStarts(){ System.out.println("******"); } }
测试功能
ORM 对象关系映射 它是以面向对象的思想 去操作数据库
对象关系映射(Object Relational Mapping,简称ORM) 为了解决面向对象与关系数据库存在的互不匹配的现象的技术 ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中
MyBatis的简介
封装了jdbc操作 可以完成普通的普通的sql(DQL DNL DDL DCL TCL)操作 存储过程和ORM(对象关系映射) 简化了jdbc的操作 简化了参数的设置以及结果集的遍历
MyBatis的核心构成
实体类
根据表设计的类
主配置文件
定义连接数据库的信息 Mybatis自带连接池 和加载SQL定义文件
sql定义文件
定义sql语句的
Mybatis框架API
主要通过sqlSession 来体现
使用Mybatis完成一个根据ID查询银行账户
建立一个项目 导入jar包 (mybatis.jar ojdbc6.jar ) 把主配置文件拷贝到src 下 并修改内容
日志sqlmap-config.xml
根据表 设计实体类
拷贝sql定义文件到一个包结构中 并定义sql语句
<!-- namespace指定和哪个Mapper映射器接口对应 --> <mapper namespace="abc"> <!-- 定义SQL语句 --> <!-- 参数类型 --> <select id="getAccountById" parameterType="int" resultType="com.xdl.bean.XdlBankAccount"> <!--返回值类型 --> select * from xdl_bank_account where id = #{单值里面随便写} </select> (根据id查询银行账户)
<select id="getAccount" parameterType="com.xdl.bean.XdlBankAccount" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account where acc_no = #{acc_no} and acc_password=#{acc_password} (根据账号密码查询用户第一种方式 多参)
XdlBankAccount acc=new XdlBankAccount(); acc.setAcc_no("litao"); acc.setAcc_password("5191264"); XdlBankAccount account = sqlSession.selectOne("getAccount", acc);
<select id="getAccount" parameterType="map" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account where acc_no = #{acc_no} and acc_password=#{acc_password} (根据账号密码查询用户的第二种方式 多参)
Map<String,String> map=new HashMap<>(); map.put("acc_no", "litao"); map.put("acc_password", "5191264"); XdlBankAccount account = sqlSession.selectOne("getAccount", map);
</select> <select id="getAll" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account </select> (查找所有账户)
System.out.println(sqlSession.selectList("getAll"));
<select id="selectAccount" parameterType="int" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account where id>#{s} </select> (查询ID大于X的银行账户)
System.out.println(sqlSession.selectList("selectAccount",6));
XML不支持< $lt;代表< 或者<![CDATA[<]]>
构建sqlSession 对象 并通过这个对象完成对应的功能
// SqlSession工厂构建器对象 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder(); // 获取SqlSession 工厂对象 InputStream inputStream = XdlBankAccountTest.class.getClassLoader().getResourceAsStream("sqlmap-config.xml"); SqlSessionFactory ssf = ssfb.build(inputStream); SqlSession sqlSession = ssf.openSession(); |// 使用sqlSession 完成查询 XdlBankAccount account = sqlSession.selectOne("getAccountById", "1"); System.out.println(account); sqlSession.close();
封装成工具类com.xdl.util
private static SqlSessionFactory ssf; static{ SqlSessionFactoryBuilder ssfb =new SqlSessionFactoryBuilder(); // 获取SqlSession 工厂对象 InputStream inputStream=test.class.getClassLoader().getResourceAsStream("sqlmap-config.xml"); ssf=ssfb.build(inputStream); } public static SqlSession getSqlSession(){ return ssf.openSession(); }
如果按照一定规则编写DAO 接口 则sqlSession 可以自动生成实现类
Mapper 映射器规则(dao接口)
返回值
接口的返回值类型 和resultType 保存一致 对dml语句可以返回void 也可以返回int 配置里不用些返回值 对select语句返回单值和resultType 保持一致 否则加List<类型>
返回list 配置里也写包名.类名
自动提交,没有事务管理
方法名
接口中的方法名 和sql定义文件中语句id保持一致
参数
接口中方法的参数 要和parameterType 保持一致 如果没有parameterType 则参数任意
0 1 2 3代表参数顺序
sql定义文件中的namepace必须是 包名.接口名
除了select语句都要commit;
//自动生成实现类 SqlSession ss = SqlSessionUtil.getSqlSession(); XdlBankAccountDAO dao = ss.getMapper(XdlBankAccountDAO.class);
根据mer映射器的规则 编写根据账号和密码进行查询
建立一个项目 导入jar包 (mybatis.jar ojdbc6.jar ) 把主配置文件拷贝到src 下 并修改内容
根据表 设计实体类
拷贝sql定义文件到一个包结构中 并定义sql语句
<!-- namespace指定和哪个Mapper映射器接口对应 --> <mapper namespace="abc"> <!-- 定义SQL语句 --> <!-- 参数类型 --> <select id="getAccountById" parameterType="int" resultType="com.xdl.bean.XdlBankAccount"> <!--返回值类型 --> select * from xdl_bank_account where id = #{单值里面随便写} </select> (根据id查询银行账户)
<select id="getAccount" parameterType="com.xdl.bean.XdlBankAccount" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account where acc_no = #{acc_no} and acc_password=#{acc_password} (根据账号密码查询用户第一种方式 多参)
XdlBankAccount acc=new XdlBankAccount(); acc.setAcc_no("litao"); acc.setAcc_password("5191264"); XdlBankAccount account = sqlSession.selectOne("getAccount", acc);
<select id="getAccount" parameterType="map" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account where acc_no = #{acc_no} and acc_password=#{acc_password} (根据账号密码查询用户的第二种方式 多参)
Map<String,String> map=new HashMap<>(); map.put("acc_no", "litao"); map.put("acc_password", "5191264"); XdlBankAccount account = sqlSession.selectOne("getAccount", map);
</select> <select id="getAll" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account </select> (查找所有账户)
System.out.println(sqlSession.selectList("getAll"));
<select id="selectAccount" parameterType="int" resultType="com.xdl.bean.XdlBankAccount"> select * from xdl_bank_account where id>#{s} </select> (查询ID大于X的银行账户)
System.out.println(sqlSession.selectList("selectAccount",6));
XML不支持< $lt;代表< 或者<![CDATA[<]]>
构造sqlSession对象 封装成工具
private static SqlSessionFactory ssf; static{ SqlSessionFactoryBuilder ssfb =new SqlSessionFactoryBuilder(); // 获取SqlSession 工厂对象 InputStream inputStream=test.class.getClassLoader().getResourceAsStream("sqlmap-config.xml"); ssf=ssfb.build(inputStream); } public static SqlSession getSqlSession(){ return ssf.openSession(); }
定义接口 根据Mapper 映射器的规则
测试
//自动生成实现类 SqlSession ss = SqlSessionUtil.getSqlSession(); XdlBankAccountDAO dao = ss.getMapper(XdlBankAccountDAO.class);
当数据库中的字段名 和实体类中的属性不一致
使用sql 中字段的别名
使用resultMap 来解决 这样sql语句就不应该有resultType
借助插件多页查询简化
只需要查询所有字段 按照某个字段排序就好
把分页插件jar包导入工程 然后再主配置文件配置分页插件
<plugins> <plugin interceptor="com.github.pagehelper.PageHelper"></plugin> </plugins>
sqlmap-config.xml
使用分页插件的api 设置分页相关数据
PageHelper.startPage(pageNumber(第几页), pageSize(几个数据));
返回集合需要先遍历再查询
一次查询只对当前有效
Spring+Mybatus
sqlSessionFactoryBean
是在spring配置文件中创建sqlSession的
MapperFactoryBean
根据Mapper接口(dao) 生产 实现类的
从spring 中获取到 dao的实现类 根据id查询银行账户(第一种方式)
建立项目导入jar包(ioc aop dao mybatis 连接池 驱动 mybatis-spring) 拷贝spring配置文件到src下
根据表 编写实体类
编写sql定义文件
根据sql定义文件 编写DAO接口(遵守Mapper映射器规则)
在Spring 容器中创建 SqlSessionFactoryBean 让其产生sqlSession 。 这个类会用到dataSource 并加载sql定义文件
<!-- 提供 sqlSession 通过 SqlSessionFactoryBean --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--指定连接资源--> <property name="dataSource" ref="dataSource"></property> <!--指定sql文件--> <property name="mapperLocations" value="classpath:com/xdl/mapper/*.xml"></property> </bean> <!-- 创建一个连接池对象 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url"> <value>jdbc:oracle:thin:@127.0.0.1:1521:xe</value> </property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </bean>
在Spring 容器中创建 MapperFactoryBean 会使用sqlSession对象 并结合DAO 接口 产生实现类
<!-- 配置产生 DAO 实现类 --> <bean id="accountDao" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="sqlSessionFactory" ref="sqlSession"></property> <property name="mapperInterface" value="com.xdl.dao.XdlBankAccountDAO"></property> </bean> (一次只能产生一个 通过属性 sqlSessionFactory 加载)
MapperScannerConfigurer
可以批量生产DAO(Mapper)的实现类
通过basePackage来指定对应的包
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xdl.dao"></property> </bean>
生成的DAO实现类 在容器中的id是 接口名首字母小写
从容器中获取dao 测试
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); XdlBankAccountDAO dao = app.getBean("accountDao", XdlBankAccountDAO.class); System.out.println(dao.getXdlBankAccountById(5));
针对dao 包中的接口 我想有一部分生成实现类 有一部分不生成实现类 可以使用自定义标注
创建一个接口@interface
想让谁产生实现类 在谁接口上打标注
告诉扫描器
<!-- 带有标注的接口生成实现类 --> 自定义标注包名.类名 <property name="annotationClass" value="com.xdl.annotation.MyAnnotation"></property>
主配置文件 (不是必须的)
<!-- 加载主配置文件 --> 主配置文件名 <property name="configLocation" value="classpath:sqlmap-config.xml"></property>
可以用来加载日志 可以用来加载分页插件
可以弄 别名简写
//类型别名 <typeAliases> //类型 //别名 <typeAlias type="com.xdl.bean.XdlBankAccount" alias="account"/> </typeAliases>
写在applicationContext.xml bean里
使用SqlSessionTemplate 完成mybatis+Spring(第二种方式)类似模板
使用SqlSessionTemplate 完成dao的实现类 这就需要在spring 容器中创建sqlSessionTemplate 对象,这个对象依赖于SqlSessionFactory(这个依赖 dataSource 和sql定义文件)
根据银行账户的id 查询银行账户
建立一个项目 导入jar包(ioc aop dao mybatis 连接池 驱动 mybatis-spring)拷贝Spring配置文件到src下
根据表 建立实体类
编写sql定义文件
根据mapper 映射器规则 编写dao接口
编写dao的实现类 注入SqlSessionTemplate 开启组件扫描 使用对应的标注创建dao对象 并注入SqlSessionTemplate 对象使用 sqlSessionTemplate 完成对应的功能
<!-- 开启组件扫描 --> <context:component-scan base-package="com.xdl"></context:component-scan>
<!-- 创建一个sqlSession的模板对象 --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" ></constructor-arg> </bean>
<!-- 提供 sqlSession 通过 SqlSessionFactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="mapperLocations" value="classpath:com/xdl/mapper/*.xml"></property> </bean> <!-- 创建一个连接池对象 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url"> <value>jdbc:oracle:thin:@127.0.0.1:1521:xe</value> </property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </bean>
实现:return sqlSessionTemplate.selectOne("方法名", id);
从容器中获取dao对象 测试
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); XdlBankAccountDao dao = app.getBean("accdao", XdlBankAccountDao.class); System.out.println(dao.selectAccountid(4));
M
JEE java的消息服务 远程调用 邮件等 (了解)
搭建SSM(Spring+SpringMVC+MyBatis)
搭建Mybatis+Spring (登录) (为了使用Mybatis在Spring容器中完成DAO实现类)
建立项目导入jar包(ioc aop dao mybatis 连接池 驱动 mybatis-spring) 拷贝spring配置文件到src下
根据表 编写实体类
编写sql定义文件
#{写参数名}要 在参数前面加@Param("参数")
或者写 0 1 2..
根据sql定义文件 编写DAO接口(遵守Mapper映射器规则)
使用MapperScannerConfigurer实现DAO
<!-- 提供 sqlSession 通过 SqlSessionFactoryBean --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--指定连接资源--> <property name="dataSource" ref="dataSource"></property> <!--指定sql文件--> <property name="mapperLocations" value="classpath:com/xdl/mapper/*.xml"></property> </bean> <!-- 创建一个连接池对象 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="oracle.jdbc.OracleDriver"></property> <property name="url"> <value>jdbc:oracle:thin:@127.0.0.1:1521:xe</value> </property> <property name="username" value="system"></property> <property name="password" value="123456"></property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xdl.dao"></property> </bean>
包装一个service 类 测试
@Service("accountservice") public class XdlBankAccountService { @Autowired private XdlBankAccountDao accountdao; public XdlBankAccount login(String acc_no,String acc_password){ return accountdao.getAccountid(acc_no, acc_password); } }
搭建基于标注的mvc
企业级框架