框架
2017-09-06 14:28:22 0 举报UserService us =(UserService) c.getBean("userService");//这里是接口,如果一个类没有实现接口,那就写类名
<property name="person">
<value>武松说:</value>
</property>
<property name="say">
<value>上山打老鼠</value>
</property>
</bean>
<bean id="helloo" class = "bgs.Hello">
<property name="person">
<value>梁爽说:</value>
</property>
<property name="say">
<value>我快热死了</value>
</property>
</bean>
// 通过ClassPathXmlApplicationContext实例化Spring的上下文
ApplicationContext c = new ClassPathXmlApplicationContext("mySpring.xml");
// 通过ApplicationContext的getBean()方法,根据id来获取bean的实例
Hello bean = (Hello) c.getBean("hello");
System.out.println(bean.getPerson()+bean.getSay());
Hello bean2 = (Hello) c.getBean("helloo");
System.out.println(bean2.getPerson()+bean2.getSay());
}
<bean id ="service" class="UserService.UserServiceImpl">
<constructor-arg ref="find" index="0"></constructor-arg>
</bean>
index="0"表示第一个形参,1表示第二个形参
UserService us = (UserService) c.getBean("service");
us.findUser();
private UserDao userDao;
public UserServiceImpl(){
}
public UserServiceImpl(UserDao userDao){
this.userDao = userDao;
}
//方法
@Override
public void findUser(User user) {
userDao.findUser(user);
}
private UserDao userDao;
构造方法
public UserServiceImpl(){
}
public UserServiceImpl(UserDao userDao){
this.userDao = userDao;
}
调Dao层方法
@Override
public void findUser(User user) {
userDao.findUser1(user);
}
<bean name="userimpl" class="UserService.UserServiceImpl" p:userDao-ref="userDao2">//p:属性名-ref=bean的id,需要setter方法
<!-- <constructor-arg ref="userDao2"></constructor-arg> 通过构造方法不需要setter方法,上面通过setter方法-->
</bean>
<bean id ="user" class="pojo.User" p:id="1" p:username="凉爽" p:password="12345" p:email="292933@qq.com"></bean>
ApplicationContext c = new ClassPathXmlApplicationContext("mySpring.xml");
UserService us = (UserService) c.getBean("userimpl");
User bean = (User) c.getBean("user");
us.findUser(bean);
}
private String specialCharacter2;//特殊字符值2
private User innerBean;//JavaBean类型
private List<String> list;//List类型
private String [] array;//数组类型
private Set<String> set;//Set类型
private Map<String,String> map;//Map类型
private Properties props;//Properties类型
private String emptyValue;//注入空字符串值
private String nullValue ="init value";//注入null值
//省略getter&setter
public void showValue() {
System.out.println("特殊字符1:" + this.specialCharacter1);
System.out.println("特殊字符2:" + this.specialCharacter2);
System.out.println("内部Bean:" + this.innerBean.getUsername());
System.out.println("List属性:" + this.list);
for (int i = 0; i < array.length; i++) {
System.out.println("数组属性["+i+"]:" + this.array[i]);
}
System.out.println("Set属性:" + this.set);
System.out.println("Map属性:" + this.map);
System.out.println("Properties属性:" + this.props);
System.out.println("注入空字符串:[" + this.emptyValue + "]");
System.out.println("注入null值:" + this.nullValue);
}
<!-- 使用<![CDATA[]]>标记处理XML特 殊字符 -->
<property name="specialCharacter1">
<value><![CDATA[P&$#G]]></value>
</property>
<!-- 把XML特殊字符替换为实体引用 -->
<property name="specialCharacter2">
<value>P>G</value>
</property>
<!-- 定义内部Bean -->
<property name="innerBean">
<bean class="pojo.User">
<property name="username">
<value>Mr.Inner</value>
</property>
</bean>
</property>
<!-- 注入List类型 -->
<property name="list">
<list>
<value>足球</value>
<value>篮球</value>
</list>
</property>
<!-- 注入数组类型 -->
<property name="array">
<array>
<!-- 定义数组中的元素 -->
<value>足球</value>
<value>篮球</value>
<value>乒乓球</value>
</array>
</property>
<!-- 注入Set类型 -->
<property name="set">
<set>
<!-- 定义Set或数组中的元素 -->
<value>足球</value>
<value>篮球</value>
</set>
</property>
<!-- 注入Map类型 -->
<property name="map">
<map>
<!-- 定义Map中的键值对 -->
<entry>
<!--map.put("football", "足球");-->
<key>
<value>football</value>
</key>
<value>足球</value>
</entry>
<!--map.put("basketball", "篮球");-->
<entry>
<key>
<value>basketball</value>
</key>
<value>篮球</value>
</entry>
</map>
</property>
<!-- 注入Properties类型 -->
<property name="props">
<props>
<!-- 定义Properties中的键值对 driver=com.mysql.jdbc.Driver-->
<prop key="driver">com.mysql.jdbc.Driver</prop>
<prop key="url">jdbc:mysql://localhost:3306/0518</prop>
</props>
</property>
<!-- 注入空字符串值 -->
<property name="emptyValue">
<value></value>
</property>
<!-- 注入null值 -->
<property name="nullValue"><null/></property>
</bean>
特殊字符1:P&$#G
特殊字符2:P>G
内部Bean:Mr.Inner
List属性:[足球, 篮球]
数组属性[0]:足球
数组属性[1]:篮球
数组属性[2]:乒乓球
Set属性:[足球, 篮球]
Map属性:{football=足球, basketball=篮球}
Properties属性:{url=jdbc:mysql://localhost:3306/0518, driver=com.mysql.jdbc.Driver}
注入空字符串:[]
注入null值:null
- 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。
- 注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd"
<!-- 扫描包中注解标注的类 -->
<context:component-scan base-package="service,dao" />
* 用户DAO类,实现UserDao接口,负责User类的持久化操作
*/
@Repository("userDao")
//<bean id="userDao" class="dao.impl.UserDaoImpl"></bean>
public class UserDaoImpl implements UserDao {
public void save(User user) {
// 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");
System.out.println(user.getUsername());
System.out.println(user.getEmail());
}
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
@Autowired
// UserDao dao = (UserDao) ctx.getBean("userDao");
@Qualifier("userDao")
// @Resource(name="userDao")
private UserDao dao;
// dao 属性的setter访问器,会被Spring调用,实现设值注入,注解自动装配
// public void setDao(UserDao dao) {
// this.dao = dao;
// }
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
Spring 不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct以及@PreDestroy。
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分别是name和type,Spring将@Resource注解的name属性 解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使 用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配(见2);如果没有匹配,则回退为一个原始类型(UserDao)进行匹配,如果匹配则自动装配;
1.6. @PostConstruct(JSR-250)
在方法上加上注解@PostConstruct,这个方法就会在Bean初始化之后被Spring容器执行(注:Bean初始化包括,实例化Bean,并装配Bean的属性(依赖注入))。
Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
<bean id="AopTryCatch" class="Aop.AopTryCatch"></bean>
<aop:config>
<aop:pointcut expression="execution(* UserService.UserServiceImpl.*User(..))" id="pointcut"/>
<aop:aspect ref="AopTryCatch">
<aop:before method="bef" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
<aop:after method="after" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
System.out.println("这是前置增强");
System.out.println("jp.getTarget()"+jp.getTarget());
System.out.println("jp.getSignature().getName()"+jp.getSignature().getName());
System.out.println("jp.getSignature()"+jp.getSignature());
System.out.println("Arrays.toString(jp.getArgs())"+Arrays.toString(jp.getArgs()));
System.out.println("jp.getKind()"+jp.getKind());
}
public void afterReturning(Object result){
System.out.println("这是后置增强:afterReturning");
System.out.println("切面类取得的返回值"+result);
}
public void afterThrowing(Exception e){
System.out.println(e.getStackTrace());
System.out.println("这里是后置增强:afterThrowing");
}
public void after (){
System.out.println("这里是最终增强");
}
public class UserServiceImpl implements UserService{
@Autowired
@Qualifier("saveUser")
private saveUser saveUser;//这个不用
@Autowired
@Qualifier("userDao")
private UserDao userDao;
@Override
public String findUser() {
userDao.findUser();
return "这里是findUser的返回值";
}
<bean class="Aop.AopZhujie"></bean>
<aop:aspectj-autoproxy />//自动扫描
public class AopZhujie {
private static final Logger log= Logger.getLogger(AopZhujie.class);
@Pointcut("execution(* UserService.UserServiceImpl.find*(..))")
public void pointcut(){}
@Before("pointcut()")
public void before (JoinPoint jp){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法入参:"+Arrays.toString(jp.getArgs()));
}
@AfterReturning(pointcut="pointcut()",returning = "returnValue")
public void afterRetruning (JoinPoint jp,Object returnValue){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。方法返回值:"+returnValue);
}
@After("pointcut()")
public void after(){
System.out.println("这是最终增强");
}
继承Conttroller抽象类
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
System.out.println("Hello,SpringMVC! from controller");
return new ModelAndView("Demo");
}
}
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
<!-- /WEB-INF/jsp/abc.jsp -->
</bean>
@RequestMapping("/RequestMapping")//路径名为:工程名+RequestMapping+index,如果空值,则工程名+index
public class IndexController extends AbstractController{
@Override
@RequestMapping("/index")
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
System.out.println("Hello,SpringMVC! from controller");
return new ModelAndView("Demo");
}
}
<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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- <bean name="/index.html" class="bgs.Controller.IndexController"></bean> -->
<context:component-scan base-package="bgs.Controller"></context:component-scan>
<mvc:annotation-driven/>//将@Controller自动注册,上面是扫描,这里是实例
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
<!-- /WEB-INF/jsp/abc.jsp -->
</bean>
</beans>
@RequestMapping("RequestMapping")
public class RequestMappingController {
//value属性执行映射路径或URL模板
//@RequestMapping(value="/welcome")如果只指定value属性时可以把value略去
@RequestMapping("/welcome")
//同时注解类与方法,需要先指定类的路径再指定方法的路径:http://localhost:8080/requestMapping/welcome
public String action1(Model model){
//在模型中添加属性message值,渲染页面时使用
model.addAttribute("message", "注解Spring MVC");
return "requestMapping";
}
@RequestMapping
public String action2(Model model){
//在模型中添加属性message值,渲染页面时使用
model.addAttribute("message","@RequestMapping为空,这是默认的方法");
return "requestMapping";
}
@RequestMapping(value="/action3",method={RequestMethod.POST,RequestMethod.GET})
public String action3(Model model){
model.addAttribute("message", "请求类型只能是post与get");
return "requestMapping";
}
@RequestMapping(value="/action4",consumes="text/html")
public String action4(Model model){
model.addAttribute("message","请求的提交内容类型(Context-Type)是text/html");
return "requestMapping";
}
@RequestMapping(value="/action5",params={"id=215","name!=abc"})
public String action5(Model model){
model.addAttribute("message","请求的参数必须包含id=215与name不等于abc");
return "requestMapping";
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>
//处理请求且返回一个模型与视图对象
@Override
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
//返回一个模型视图,指定路径,指定模型的形成为message,值为一段字符串
return new ModelAndView("interface","message","Hello,我是通过实现接口定义");
}
}
<context:component-scan base-package="bgs.Controller"></context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
<!-- /WEB-INF/jsp/abc.jsp -->
</bean>
@RequestMapping("/request")
public class RequestController {
@RequestMapping("/action1")
//方法得参数可以是任意基本数据类型
//如果方法参数名与http中请求的参数名称相同时会进行自动映射
//包装类型也一样,但如果参数中没有对应名称与类型的数据则会异常。
//基本数据类型不能为空,否则会出现400,如int id的值不能为空
public String action1(Model model,int id,String name,Integer age,String sex){
model.addAttribute("message", "id="+id+",name="+name+",age="+age);
return "request";
}
}
id:<input type="text" name="id">
name:<input type="text" name="name">
age:<input type="text" name="age">
sex:<input type="text" name="sex">
<input type="submit" value="提交">
</form>
//除了基本数据类型,也可以自定义的数据类型,如一个自定义的pojo对象,
//Spring MVC会通过反射把其中的参数设置到对象中,转换类型
public String action2(Model model,User user){
model.addAttribute("message",user);
System.out.println(user.toString());
return "request";
}
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
//复杂数据类型
//复杂数据类型指的是一个自定义类型中还包含另外一个对象类型
public String action3(Model model,User user){
model.addAttribute("message",user+";"+user.getBill());
return "request";
}
id:<input type="text" name="id">
name:<input type="text" name="name">
age:<input type="text" name="age">
sex:<input type="text" name="sex">
BillId:<input type="text" name="bill.billId">
BillName:<input type="text" name="bill.billName">
<input type="submit" value="提交">
</form>
//List集合类型
//不能直接在action的参数中指定List<T>类型,必须定义一个类型包装List集合
//Map与List的实现方式基本一样
//集合类型基本都一样,set也差不多,问题是如果为了获得一个集合需要刻意去包装会很麻烦
//可以通过@RequestParam结合@RequestBody等注解完成
public String action4(Model model,ParamList paramList){
model.addAttribute("message",paramList);
return "request";
}
private List<User> userList;
。。省略
}
<script>
$(document).ready(function () {
var num = 0;
$("#but").click(function () {
$("#user").append("id:<input type=\"text\" name=\"userList[" + num + "].id\"/>
name:<input type=\"text\" name=\"userList[" + num + "].name\"/>
age:<input type=\"text\" name=\"userList[" + num + "].age\"/>
sex:<input type=\"text\" name=\"userList[" + num + "].sex\"/><br>");
num ++;
alert($("#user").html());
})
});
</script>
<form action="/SpringMvc0911/request/action4" method="post">
<input type="button" id="but" value="添加记录">
<div id="user">
</div>
<button type="submit" value="提交">提交</button>
</form>
//基本数据类型绑定与注解属性
//@RequestParam共有3个注解属性
//required属性表示是否为必须传参,默认值为true
//defaultValue用于设置参数的默认值,如果不指定值则使用默认值,只能是String类型的
//value用于指定传入参数的名称
public String action5(Model model,@RequestParam(required=false,defaultValue="250",value="userId") Integer id){
model.addAttribute("message", id);
return "request";
}
id:<input type="text" name="userId">
name:<input type="text" name="name">
<input type="submit" value="提交">
</form>
//List与数组绑定基本数据类型
//表单同样可行,但是@RequestParam("name")是必须的,name为页面中的表单的name,如果和参数同名则可以省去
public String action6(Model model,@RequestParam("phone")List <String> strings){
model.addAttribute("message",strings.get(0) + "," + strings.get(1) + "," + strings.get(2));
return "request";
}
phone:<input type="text" name="phone"/><br>
phone:<input type="text" name="phone"/><br>
phone:<input type="text" name="phone"/><br>
<button type="submit" value="提交">提交</button>
</form>
* 定义控制器
*/
@Controller
@RequestMapping("/response")
public class ResponseController {
@RequestMapping("/action1")
//方法返回值为String:String作为视图名称
//默认如果action返回String,此时的String为视图名称
//会去视图解析器的设定的目录下查找,查找的规则是:URL= prefix前缀+视图名称 +suffix后缀组成
public String action1(Model model) {
User user = new User();
user.setName("zhangsan");
model.addAttribute("message",user);
return "request";
}
//String作为内容输出
@ResponseBody
//如果方法声明了注解@ResponseBody ,将内容或对象作为 HTTP 响应正文返回
//并调用适合HttpMessageConverter的Adapter转换对象,写入输出流
//些时的String不再是路径而是内容
public String action2(Model model){
model.addAttribute("message", "aaaaaaa");
return "aaaaaaa";
}
//返回值为void,存在如下两种情况:
//1.方法名默认作为视图名:
// 当方法没有返回值时,方法中并未指定视图的名称,则默认视图的名称为方法名
// URL= prefix前缀+控制器路径+方法名称 +suffix后缀组成(/WEB-INF/jsp/response/action3.jsp)
public void action3(Model model){
User user = new User();
user.setName("zhangsan");
model.addAttribute("message",user);
}
//返回值为void,存在如下两种情况:
//2.直接响应输出结果
// 当方法的返回值为void,但输出流中存在输出内容时,则不会去查找视图,而是将输入流中的内容直接响应到客户端
// 响应的内容类型是纯文本
public void action4(HttpServletResponse response) throws IOException {
String s ="直接响应输出结果";
response.setContentType("text/html;charset=utf-8");
//response.setContentType(“text/html; charset=utf-8”); html
//response.setContentType(“text/plain; charset=utf-8”); 文本
// response.setContentType(“text/javascript; charset=utf-8”); json数据
// response.setContentType(“application/xml; charset=utf-8”); xml数据
response.getWriter().write(s);
}
//返回值为ModelAndView
//可以同时指定须返回的模型与视图对象或名称
//ModelAndView有个多构造方法重载,单独设置属性也很方便
public ModelAndView action5(){
//1.只指定视图
return new ModelAndView("responseMapping");
//2.分别指定视图与模型
// Map<String, Object> model=new HashMap<String,Object>();
// model.put("message", "ModelAndView action5");
// return new ModelAndView("responseMapping",model);
//3同时指定视图与模型
// return new ModelAndView("responseMapping","message","action5 ModelAndView ");
//4分开指定视图与模型
// ModelAndView modelAndView=new ModelAndView();
// //指定视图名称
// modelAndView.setViewName("responseMapping");
// //添加模型中的对象
// modelAndView.addObject("message", "<h2>Hello ModelAndView</h2>");
// return modelAndView;}
//返回值为Map
//当返回结果为Map时,相当于只是返回了Model,并未指定具体的视图
//返回视图的办法与void是一样的,即URL= prefix前缀+控制器路径+方法名称 +suffix后缀组成(/WEB-INF/jsp/response/action6.jsp)
public Map<String,Object> action6(){
Map<String, Object> model=new HashMap<String,Object>();
model.put("message", "Hello Map");
model.put("other", "more item");
return model;
}
//返回值为任意类型
//1.返回值为基本数据类型
// 当返回结果直接为int,double,boolean等基本数据类型时,会出现Unknown return value type异常
@ResponseBody
// 如果确实需要直接将基本数据类型返回,则可以使用注解@ReponseBody
public int action7(){
return 325;
}
//返回值为任意类型
//2.当返回值为自定义类型
//TODO 返回值为任意类型-2.返回值为自定义类型
//TODO 返回值为Model类型、view等
}
@RequestMapping(value="getproviderlist",produces="application/json;charset=utf-8")//
@ResponseBody
public String getProviderlist(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("getproviderlist ========================= ");
List<Provider> providerList = new ArrayList<Provider>();
ProviderService providerService = new ProviderServiceImpl();
providerList = providerService.getProviderList("","");
return JSONArray.toJSONString(providerList);
在controller中捕捉异常
// TODO Auto-generated method stub
//Connection connection = null;
List<User> userList = null;
System.out.println("queryUserName ---- > " + queryUserName);
System.out.println("queryUserRole ---- > " + queryUserRole);
System.out.println("currentPageNo ---- > " + currentPageNo);
System.out.println("pageSize ---- > " + pageSize);
throw new RuntimeException("异常了");
}
public String handlerException(RuntimeException e,HttpServletRequest req){
req.setAttribute("e", e.getMessage());
return "../error";
}
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.RuntimeException">../error</prop>//总共有两个error.jsp页面
<prop key="java.lang.SQLException">error</prop>
<prop key="java.lang.Exception">error</prop>
</props>
</property>
</bean>
2、局部异常的优点:可以携带request请求,可以处理特殊的异常问题,而全局异常不能携带request请求,只能在JSP页面写共用异常处理文字
3、局部异常的缺点:需要对每个controller编写异常方法。
总结:如果对异常不需要特殊处理,则配置全局异常即可
String path1=request.getContextPath();//获得工程名,/uploadFile0801
String path2=request.getServletPath();//除工程名以外路径名,/Request/upload
String path3=request.getRequestURI();//path3=path1+path2,/uploadFile0801/Request/upload
String path= request.getServletContext().getRealPath("/images/");
String path4=request.getSession().getServletContext().getRealPath("/images/");//这两个路径都是下面
E:\apache-tomcat-7.0.53\webapps\uploadFile0801\images
@RequestMapping("Request")
public class upload0926 {
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String upload(HttpServletRequest request,
@RequestParam("description") String description,
@RequestParam("file")MultipartFile file) throws IllegalStateException, IOException{
System.out.println(description);
if(!file.isEmpty()){
//上传文件路径
String path1=request.getContextPath();
String path2=request.getServletPath();
String path3=request.getRequestURI();
String path= request.getServletContext().getRealPath("/images/");//与path4一样
String path4=request.getSession().getServletContext().getRealPath("/images/");
System.out.println("getContextPath()"+path1);
System.out.println("getServletPath()"+path2);
System.out.println("getRequestURI()"+path3);
System.out.println("getServletContext().getRealPath()"+path);
//上传文件名
String filename=file.getOriginalFilename();
File filepath = new File(path);
if(!filepath.exists()){
filepath.mkdirs();
}
//File filepath=new File(path,filename);
//判断路径是否存在,如果不存在就创建一个
/*if(!filepath.getParentFile().exists()){
filepath.getParentFile().mkdirs();
}*/
//将上传文件保存到一个目标文件当中
file.transferTo(new File(path+File.separator+filename));
return "success";
}else{
return "error";
}
}
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- 自动扫描包,实现支持注解的IOC -->
<context:component-scan base-package="UploadFileMvc"/>
<!-- Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!-- 支持mvc注解驱动 -->
<mvc:annotation-driven/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件大小上限,单位为字节(10MB) -->
<property name="maxUploadSize" value="10485760"/>
<!-- 请求的编码格式,必须和JSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<form action="${pageContext.request.contextPath}/Request/upload" enctype="multipart/form-data" method="post">
<table>
<tr>
<td>文件描述:<td>
<td><input type="text" name="description"/><td>
</tr>
</table>
<div>
<label for="uploadfile">请选择文件:</label>
<input type="file" name="file" id= "uploadfile"/>
<font color="red"></font>
</div>
<div><input type = "submit" value="上传"/></div>
</form>
throws ServletException, IOException {
//判断文件是否为空
if(!attach.isEmpty()){
String path = request.getContextPath()+File.separator+"statics"+File.separator+"uploadfiles";//这个路径不要了
String realPath= request.getSession().getServletContext().getRealPath("statics"+File.separator+"uploadfiles");
String oldFileName = attach.getOriginalFilename();//原文件名
String suffix = FilenameUtils.getExtension(oldFileName);//原文件后缀
int filesize=500000;
if(attach.getSize()>filesize){
request.setAttribute("uploadFileError", "上传大小不得超过500k");
return "useradd";
}else if(suffix.equalsIgnoreCase("jpg")||suffix.equalsIgnoreCase("png")
||suffix.equalsIgnoreCase("jpeg")||suffix.equalsIgnoreCase("pneg")){//上传图片格式不正确
String fileName = System.currentTimeMillis()+RandomUtils.nextInt(1000000)+"_Personal.jpg";
File targetFile = new File(realPath,fileName);
// 判断路径是否存在,不存在就新建这个路径
if(!targetFile.exists()){
//targetFile.getParentFile();
targetFile.mkdirs();
}
//保存
try {
attach.transferTo(targetFile);
} catch (IllegalStateException e) {
e.printStackTrace();
request.setAttribute("uploadFileError", "上传失败!");
return "useradd";
}
//文件相对路径
idPicPath = path+File.separator+fileName;
//文件绝对路径
idPicRealPath = realPath+File.separator+fileName;
}else{
request.setAttribute("uploadFileError", "上传图片格式不正确");
return "useradd";
}
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5000000"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
1、全局配置文件 XML
2、映射文件 XML
3、创建工厂 SqlSessionFactory 会话工厂
4、通过SqlSession会话进行增删改查
步骤:
1、导jar包
2、在Java Resource下建一个文件夹(config),在里面建一个全局配置文件XML(SqlMapConfig)
1)把文件头复制过来
<!DOCTYPE configuration PUBLIC
"-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
2)把参数复制过来
<configuration>
<!-- 配置mybatis的环境信息,与spring集成后该部分拿掉,设置默认调用default="development -->
<environments
default="development">
<!-- 可以有多个默认是用哪个就写那个 -->
<environment
id="development">
<!-- 配置jdbc事物由mybatis进行管理 -->
<transactionManager
type="JDBC" />
<!-- 配置数据源,采用dbcp连接池 -->
<dataSource
type="POOLED">
<property
name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/数据库连接的名字" />
<property
name="username" value="root" />
<property
name="password" value="数据库密码" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper
resource="sqlmap/User.xml"/>
</mappers>
</configuration>
3、在Java Resources的src下建实体(User)
4、配置映射文件,(config)下建XML(User)
1)把头文件粘上
<!DOCTYPE mapper
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
2)把参数复制过来
<mapper namespace="命名空间">//不同一实体的命名空间不同
<select id="命名空间唯一标识(一条语句一个标识)" parameterType="java.lang.String(输入参数类型)" resultType="bgs.com.entity.User(输出参数类型)">
select * from user where id =#{id}
</select>
</mapper>
5、log4j.properties文件放在工程下(config文件夹中)
(测试时用DEBUG,上线后用error)
6、写测试
@Test
public void
findUser() throws IOException{
//1、加载配置文件
String res = "SqlMapConfig.xml(全局配置文件)";
//2、获取xml路径
InputStream inputStream = Resources.getResourceAsStream(res);
//3、创建sqlsessionFactory
SqlSessionFactory s = new SqlSessionFactoryBuilder().build(inputStream);//SqlSessionFactory是接口;SqlSessionFactoryBuilder是实现类
SqlSession session = s.openSession();//SqlSession是接口;openSession是实现类
//4、SqlSession执行statement
User user = session.selectOne("test.findUser"(命名空间.空间标识), "2(输入参数类型)");
System.out.println(user.getName())
多个测试时:
1、一个实体,多个查询语句:
1)在映射文件XML下添加select语句
2)在测试单元中添加测试
2、不同实体:
1)配实体
2)在全局映射文件下加上新的映射文件路径
3)在映射文件下配select语句
4)写测试
SQL语句:
1、select * from user where id = #{id}
#{}:表示一个占位符
#{id}:#{}内的id表示接受输入参数的名称,该参数类型是简单类型(包括八种基本数据类型,String,Integer),那么参数名称可以任意
2、
<select id="findListUser"
parameterType="java.lang.String"
resultType="bgs.com.entity.User">
select * from user where name like '%${value}%'
</select>
模糊查询时,占位符${value}
//@Select("select * from easybuy_user where userName like concat ('%',#{name},'%')")
//@Select("select * from easybuy_user where userName like '%${name}%' and mobile=#{mobile}")
//public List<User> likeUser(@Param("name")String name,@Param("mobile")String mobile);
3、<select
id="findListUsers" resultType="bgs.com.entity.User">
select * from user
</select>
没有输入参数时,就不写输入参数类型
<properties resource="db.properties">
<property name="db.driver" value="123"></property>注意:优先加载行内配置文件!!!!外部如果有配置文件将覆盖行内value=“123”的值
</properties>
db.driver = com.mysql.jdbc.Driver
db.url = jdbc:mysql://localhost:3306/0518
db.username=root
db.password=123
<TypeAliases>
<!-- 单个自定义类型别名-->
<typeAlias type = "entity.User" alias="user"></typeAlias>//很少用
<!-- 批量自定义类型别名-->
<package name ="entity"></package>//包名
</TypeAliases>
2、mapper接口的方法名称要和mapper映射文件的statement的id一致。
3、mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致。
4、mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。
<selectKey keyProperty="id" resultType="string" order="BEFORE">
select UUID()//函数名要大写,order的值,也就是BEFORE也要大写
</selectKey>
insert into users0728 (id,userName) values(#{id},#{userName})
</insert>
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()//在数据库中要点自增属性,再用此方法
</selectKey>
insert into users0728 (userName) values(#{userName})
</insert>
<mapper resource="sqlmap/User.xml"/>这是加载xml文件,与不在一个包下,注意这是斜杠////
加载单个
<mapper class="bgs.com.mapper.UserMapper(接口与映射文件放在同一个包下,并且同名才行)">
加载多个
<package name="bgs.com.mapper">
</mappers>
<resultMap type="user" id="resultId"> //resultType被移动到这里
<result column="_userName" property="userName" />
<result column="_sex" property="gender" />
</resultMap>
<select id="findUser" parameterType="string" resultMap="resultId">//resultMap的值与上面的ID一致
select _userName,_sex from users0807 where id = #{id}
</select>
</mapper>
<!-- <select id="UserList" parameterType="user" resultMap="resultId">
select * from users0807 where
动态sql拼接
<if test="gender!=null and userCode!=''">
_sex=#{gender}
</if>
<if test="userName!=null and userName!=''">
and _userName=#{userName}
</if>
</select> -->
<!-- <select id="UserList" parameterType="user" resultMap="resultId">
select * from users0807
<where>
<if test="gender!=null and userCode!=''">
and _sex=#{gender}
</if>
<if test="userName!=null and userName!=''">
and _userName=#{userName}
</if>
</where>
</select> -->
<sql id="includeId">
<if test="gender!=null and userCode!=''">
and _sex=#{gender}
</if>
<if test="userName!=null and userName!=''">
and _userName=#{userName}
</if>
</sql>
<select id="UserList" parameterType="user" resultMap="resultId">
select * from users0807
<where>
<include refid="includeId"></include>
</where>
</select>
select * from users0807
<where>
id in
<if test="list!=null and list!=''">
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
select * from users0807
<where>
id in
<if test="listId!=null and listId!=''">
<foreach collection="listId" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
private String userName;
private String userCode;
}
<result column="user_Name" property="userName"/>
<result column="user_Code" property="userCode"/>
</resultMap>
一对一简单的平铺关系
<select id="findUser" resultMap="resultMaps">
select s_bill.id,
s_bill.productName,
s_user.user_Name,
s_user.user_Code
FROM
s_bill,s_user
WHERE
s_bill.userId=s_user.id;
</select>
private sUser user;
//get,set方法省略了
}
<resultMap type="billUser" id="resultId" autoMapping="true">
<id column="id" property="id"/> //一个查询主表的id,后者是对象中id属性
<!-- 一对一属性对象映射 -->
<association property="user" javaType="suser"> //前者是属性 后者是类型
<result column="user_Name" property="userName"/>
<result column="user_Code" property="userCode"/>
</association>
</resultMap>
<select id="findUser" resultMap="resultId">
select s_bill.id,
s_bill.productName,
s_user.user_Name,
s_user.user_Code
FROM
s_bill,s_user
WHERE
s_bill.userId=s_user.id;
</select>
private List<sInfo> listInfo;//get,set省略
}
<resultMap type="BillInfo" id="resultBill" autoMapping="true">
<id column="id" property="id"/>
<collection property="listInfo" ofType="sInfo" autoMapping="true">
<result column="creat_By" property="creatBy" />
</collection>
</resultMap>
<select id="queryBill" resultMap="resultBill">
select
a.id,
a.productName,
b.creat_By,
b.total
from
s_bill as a,
s_info as b
where
a.id=b.billid
</select>
private List<packBill> billList;
}
public class packBill extends sBill{
private List<packInfo> InfoList;
}
public class packInfo extends sInfo{
private sProduct pro;
}
<resultMap type="packUser" id="List">
<id column="id" property="id"/>
<result column="user_Name" property="userName"/>
<collection property="billList" ofType="packBill" autoMapping="true">
<collection property="InfoList" ofType="packInfo" autoMapping="true">
<result column="creat_By" property="creatBy"/>
<association property="pro" javaType="sProduct" autoMapping="true">
</association>
</collection>
</collection>
</resultMap>
<select id="UserList" resultMap="List">
select
s_user.id,
s_user.user_Name,
s_bill.productName,
s_info.creat_By,
s_info.total,
s_pro.proName
FROM
s_user,
s_bill,
s_info,
s_pro
WHERE
s_user.id = s_bill.userId
and s_bill.id = s_info.billid
and s_info.pro_id = s_pro.id
</select>
mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。
mybaits提供一级缓存,和二级缓存。
mybatis默认开启一级缓存。
如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。
执行insert,update,delete后执行session.commit()会清空一级缓存
执行session.clearCache();也是用来清空一级缓存
1.在核心配置文件中加入
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.<!-- 开启本mapper的namespace下的二级缓存-->
<cache />
3.调用pojo类实现序列化接口Serializable
UserMapper有一个二级缓存区域(按namespace分),其它mapper也有自己的二级缓存区域(按namespace分)。每一个namespace的mapper都有一个二缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同的二级缓存区域中。
二级缓存作用域为 Mapper(Namespace);(整个项目期间application)
一级缓存和二级缓存的使用顺序 :
二级缓存———> 一级缓存——> 数据库
<setting name="aggressiveLazyLoding" value="false">//积极懒加载默认是true,改为false,否则不能按需加载
第一种:通过SqlSessionTemplate和dao层实现类的方式
<!-- 配置数据源 -->
<bean id ="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><!-- 当数据库连接不使用的时候,就把该连接重新放到数据池中,方便下次使用调用 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/0518"></property>
<property name="username" value="root"></property>
<property name="password" value="123"></property>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations">
<list>
<value>classpath:bgs/Dao/**/*.xml</value>
</list>
</property>
</bean>
<!-- 配置SqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
</bean>
<!-- 配置Dao,使用Template需要多个实现类,使用较少 -->
<bean id="userMapper" class="bgs.Dao.UserDaoImpl">
<property name="sqlSession" ref="sqlSessionTemplate"></property>//注入的目的是调用getMapper方法,如右边所示(→)
</bean>
<!-- 配置业务bean(Service) -->
<bean id ="userService" class="bgs.Service.UserServiceImpl">
<property name="userMapper1" ref="userMapper"></property>
</bean>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="bgs.pojo"></package>
</typeAliases>
</configuration>
private SqlSessionTemplate sqlSession;
public SqlSessionTemplate getSqlSession() {
return sqlSession;
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> findUser() {
return sqlSession.getMapper(UserDao.class).findUser();//看过来
}
}
第二种:通过MapperFactoryBean和接口的方式
<bean id ="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations">//若接口与xml在一个包下(同层),则可不设置这个属性
<list>
<value>classpath:bgs/Dao/**/*.xml</value>
</list>
</property>
</bean>
<bean id="productDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="bgs.Dao.ProductDao"></property>//这里有一个问题,如果Dao接口比较多,那就要多写几个Bean了,所以不推荐
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<bean id ="productService" class="bgs.Service.ProductServiceImpl">
<property name="ProductDao" ref="productDao"></property>
</bean>
public class ProductServiceImpl implements ProductService{
private ProductDao productDao;
public ProductDao getProductDao() {
return productDao;
}
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
@Override
public List<Product> findProduct() {
List<Product> findProduct;
try {
findProduct = productDao.findProduct();
return findProduct;
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
}
}
}
第三种:通过MapperScannerConfigurer递归扫描的方式
<bean id ="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>//同上
<property name="mapperLocations">
<list>
<value>classpath:bgs/Dao/**/*.xml</value>
</list>
</property>
</bean>
<context:component-scan base-package="bgs.Service"></context:component-scan>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="bgs.Dao"></property>//包名,自动递归扫描
</bean>
</beans>
public class ProductServiceImpl implements ProductService{
@Autowired
private ProductDao productDao;
@Override
public List<Product> findProduct() {
List<Product> findProduct;
try {
findProduct = productDao.findProduct();
return findProduct;
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw e;
}
}
}
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
<context:property-placeholder location="classpath:db.properties" system-properties-mode="FALLBACK"/>
<bean id ="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!-- 通过MapperScannerConfigurer递归扫描的方式 -->//自动把接口注册为Bean
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="bgs.Dao"></property>
</bean>
<!-- 定义事务,注入数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务增强,针对不同方法定义事务规则 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" propagation="SUPPORTS"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* bgs.Service..*.*(..))" id="serviceMethod"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>
public List<Product> findProduct();
@Insert("insert into s_pro values(#{id},#{proName})")
public int addPro(Product pro);
}
public class ProductServiceImpl implements ProductService{
@Autowired
private ProductDao productDao;
public int addPro(Product pro) {
pro.setId("5");
pro.setProName("事务管理");
int addPro=0;
try {
addPro = productDao.addPro(pro);
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw e;
}
return addPro;
}
ApplicationContext c = new ClassPathXmlApplicationContext("shiwu.xml");
ProductService bean = (ProductService) c.getBean("productService");
Product pro = new Product();
int addPro = bean.addPro(pro);
}
通过注解配置生命式事务
<context:property-placeholder location="classpath:db.properties" system-properties-mode="FALLBACK"/>
<bean id ="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!-- 通过MapperScannerConfigurer递归扫描的方式 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="bgs.Dao"></property>
</bean>
<!-- 定义事务管理器,注入数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
public List<User> findUser();
@Insert("insert into users0817 values(#{id},#{userName},#{userPassword},#{gender})")
public int addUser(User user);
}
@Service("UserService")
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
@Transactional(propagation= Propagation.REQUIRED,noRollbackFor=RuntimeException.class)//事务传播行为类型
public int addUser(User user) {
user.setId("5");
user.setGender("男");
user.setUserName("王伏");
user.setUserPassword("12345");
int addUser = 0;
try {
addUser=userDao.addUser(user);
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw e;
}
return addUser;
}
}
public void addUser() throws IOException{
ApplicationContext c = new ClassPathXmlApplicationContext("shiwuzhujie.xml");
UserService bean = (UserService) c.getBean("UserService");
User user = new User();
int addUser = bean.addUser(user);
System.out.println(addUser);
}
E:\apache-tomcat-7.0.53\webapps\SMBSM\WEB-INF\classes部署
改为String configFile = "/database.properties";因为配置文件在Tomcat根目录下
经过第二部build path后会多出/resources
账户:root
密码:自个想
粘贴内容:
#set java environment
JRE_HOME=$JAVA_HOME/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH
四、source /etc/profile(无任何反应,则继续第五步)
五、java -version 查看JDK安装版本
# tar -xvf apache-tomcat-8.0.26.tar.gz // 解压压缩包
# rm -rf apache-tomcat-8.0.26.tar.gz.tar.gz // 删除压缩包
# mv apache-tomcat-8.0.26 tomcat//重命名
# /usr/local/apache-tomcat-8.5.20/bin/startup.sh //启动tomcat
systemctl disable firewalld.service #禁止firewall开机启动
firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running)
说明tomcat启动成功
tail -f 日志名 //ctrl+C退出
tail -fn 500 日志名