Spring、SpringMVC、MyBatis学习笔记

Spring

1. spring的注入方式

a . bean配置
  • 设值注入

    • setXxx()方法,
  • 构造注入

    • 标签
  • p命名空间

    • xmlns:p=“http://www.springframework.org/schema/p” 并在标签中 P:name=""
  • 自动装配 (只适用于引用类型)autowire=“byName | byType | constructor | no” (不建议多次使用)

    • 在< bean id="" autowire=“byName” /> ,当id的类中有和IOC容器中bean的id相同时,自动装配
      • byName : bean的id值=类的属性名
      • byType : 其他bean的类型(class)是否与该类的ref属性类型一致(当前IOC容器中只能有一个bean满足条件)
      • constructor : 其他bean的类型(class)是否与该类的构造方法参数的类型一致,本质是byType
    • 在头文件的beans标签中添加统一自动装配:default-autowire=“byName”
    • 自动装配虽然可以减少代码量,但是会降低程度的可读性,使用时需要谨慎
b . 注解方式
  • @Component细化:

    • @Repository Dao层
    • @Service service层
    • @Controller controller层
  • 配置包扫描器:

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context  
      http://www.springframework.org/schema/context/spring-context.xsd  
<context:component-scan base-package="com.test.pojo" />  
  • 在声明前加上 @Value("")

2. 使用注解实现声明式事务

1.需要的包:

  • spring-tx.jar
  • ojdbc.jar 驱动
  • commons-dbcp.jar 连接池使用到的数据源
  • commons-pool.jar 连接池
  • spring-jdbc.jar
  • aopalliance.jar aop相关

2.增加事务tx的命名空间

3.增加对事务的支持(核心):

<tx:annotation-driven transaction-manager=“txManager” />

配置事务管理器:

配置数据库相关:

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
    <property name="url" value="" />
    <property name="username" value="system" />
    <property name="password" value="123456" />
    <property name="maxIdle" value="10" />
    <property name="maxWaitMillis" value="1000" />
</bean>

4.将需要成为事务的方法 前增加注解:

@Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollBackFor=...)

3. AOP

需要的jar:

  • aopliance.jar
  • aspectjweaver.jar

通知类型:org.springframework.aop.

  • 前置通知:MethodBeforeAdvice 接口方法 before()
  • 后置通知:AfterReturningAdvice 接口方法 afterReturning()
  • 异常通知:ThrowsAdvice 接口方法 无
  • 环绕通知:MethodInterceptor 接口方法 invoke()
<!-- 配置前置通知  切面 -->  
<bean id="logBefore" class="com.test.aop.LogBefore"></bean>  
<!-- 关联切入点和切面 -->
<aop:config >
    <!-- 配置切入点 -->
    <aop:pointcut id="pointcut" expression="execution(public void com.test.service.demoService.DemoServiceImpl.addUser())" />
    <!-- 连接线 -->
    <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut" />
</aop:config>

异常通知必须实现方法:

public void afterThrowing(Throwable ex)
or
public void afterThrowing(Method method, Object[] args, Object target, Throwable ex)

环绕通知:

 @Override
public Object invoke(MethodInvocation mi) throws Throwable {
    Object result = null;
    try {
        System.out.println("环绕-前置通知");

        //在此之前的为前置通知
        result = mi.proceed();      //控制目标方法是否执行
        
		//在此之后的为后置通知
        System.out.println("环绕-后置通知:目标对象:" + mi.getThis() + ",调用的方法:" + mi.getMethod().getName() +
                ",参数个数:" + mi.getArguments().length + ",返回值:" + result);
    }catch (Exception e){
        //异常通知
        System.out.println("环绕-异常通知");
    }
    return result;
}

注解实现AOP

  • 前置: @Before
  • 后置: @AfterReturning
  • 异常: @AfterThrowing
  • 环绕: @Around
  • 最终: @After

注解形式AOP,需设置扫描器,扫描器会将指定的包中的 @Component @Service @Repository @Controller修饰的类产生的对象增加到IOC容器

通过注解形式实现的AOP,若要获取目标对象的一些参数,则需要使用一个对象:JoinPoint

@Component("logAnnotation")
@Aspect //表示此类是一个AOP通知
public class LogAnnotation {

    // 前置通知
    @Before("execution(public void addUser())")           // 属性定义触发时机(切点)
    public void myBefore(JoinPoint jp){
        System.out.println("《注解》-前置通知:目标对象:" + jp.getTarget() + ",方法名:" + jp.getSignature().getName() +
        ",参数个数:" +jp.getArgs().length );
    }

    // 后置通知
    @AfterReturning(pointcut = "execution(public void deleteUser())", returning = "returningValue")    // 属性定义触发时机(切点)
    public void myAfter(JoinPoint jp, Object returningValue){   //需要声明该方法有返回值, returningValue 是返回值
        System.out.println("《注解》-后置通知:目标对象:" + jp.getTarget() + ",方法名:" + jp.getSignature().getName() +
                ",参数列表:" + Arrays.toString(jp.getArgs()) + ",返回值:" + returningValue );
    }

    // 异常通知:如果只捕获特定类型的异常,则可以通过第二个参数实现:e
    @AfterThrowing(pointcut = "execution(public void addUser())", throwing = "e")
    public void myException(JoinPoint jp, NullPointerException e){
        System.out.println("《注解》-异常通知: " + e.getMessage());
    }

    // 环绕通知
    @Around("execution(public void addUser())")
    public void myAround(ProceedingJoinPoint pjp){
        //前置通知
        System.out.println("《注解-环绕》-前置通知");
        try{
            pjp.proceed();          // 执行方法,抛出的是Throwable

            System.out.println("《注解-环绕》-后置通知");
        }catch (Throwable e){
            // 异常通知
            System.out.println("《注解-环绕》-异常通知");
        }finally {
            // 最终通知
            System.out.println("《注解-环绕》-最终通知");
        }
    }
	//单独的最终通知
	@After("execution(public void addUser())")
    public void myAfter(){
        System.out.println("《注解-环绕》-【单独的最终通知】");
    }
}

开启注解对AOP的支持

< aop:aspectj-autoproxy></aop:aspectj-autoproxy>

通过Scheme配置AOP

xmlns:aop=“http://www.springframework.org/schema/aop”

类似于实现接口的方式

  • 编写一个普通的类
// Schema实现的AOP不需要实现接口,只需要在xml里配置
public class LogSchema {
    // 前置通知
    public void before(JoinPoint jp){
        System.out.println("【Schema】前置通知");
    }
    //后置通知
    public void afterReturning(JoinPoint jp, Object returnValue){
        System.out.println("【Schema】后置通知:目标对象:" + jp.getThis() + ",方法名:" + jp.getSignature().getName() + ",参数个数:"
         + jp.getArgs().length + ", 返回值:" + returnValue);
    }
	// 环绕通知
    public Object around(ProceedingJoinPoint pjp){
        System.out.println("【Schema】环绕-前置通知");

        Object result = null;
        try {
            //在此之前的为前置通知
            result = pjp.proceed();      //控制目标方法是否执行
            //在此之后的为后置通知

            System.out.println("【Schema】环绕-后置通知:目标对象:" + pjp.getThis() + ",调用的方法:" + pjp.getSignature().getName() +
                    ",参数个数:" + pjp.getArgs().length + ",返回值:" + result);
        }catch (Throwable e){
            //异常通知
            System.out.println("【Schema】环绕-异常通知");
        }
        return result;
    }
}
  • 将该类通过配置,转为一个通知

如果要获取目标对象的信息

  • 注解schema:JoinPoint
  • 接口:Method method, Object[] args, Object target
<!-- 通过Schema实现AOP -->
    <bean id="logSchema" class="com.test.aop.LogSchema">
    </bean>
    <!-- 关联切入点和切面 -->
    <aop:config>
        <!-- 配置切入点 -->
        <aop:pointcut id="pcSchema"
                      expression="execution(public void com.test.service.demoService.DemoServiceImpl.addUser())"/>
        <!-- 连接线  Schema方式不需要这个
            <aop:advisor advice-ref="logSchema" pointcut-ref="pcSchema" />
        -->
        <aop:aspect ref="logSchema">
            <!-- pointcut-ref:连接线      returnValue: 返回值 -->
            <aop:before method="before" pointcut-ref="pcSchema"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pcSchema" returning="returnValue"/>
            <aop:around method="around" pointcut-ref="pcSchema"/>
        </aop:aspect>
    </aop:config>

Spring 开发Web项目

Java项目中从main开始启动,可以初始化IOC容器,在Web项目中从服务器启动时,需通过监听器初始化IOC容器

需要用到 spring-web.jar ,并在web.xml中进行配置

<!-- 配置spring-web.jar 提供的监听器,可以在服务器启动时初始化IOC容器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <!--
        1. 必须告诉监听器此容器的位置:context-param
        2. 默认约定的位置:WEB-INF/applicationContext.xml
    -->
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param> 

配置时必须告诉监听器此容器的位置,或者用默认的名称放在默认约定的位置:
WEB-INF/applicationContext.xml

拆分Spring配置文件

Web项目拆分配置:

  • 三层结构
    • UI(html/css/jsp/servlet)
    • Service
    • Dao
    • 公共 数据库
  • 功能结构
    • 学生管理系统的功能结构:学生相关配置、班级相关配置…

Web项目合并配置:

1.在web.xml的context-param的classpath:中配置

<param-value>
	classpath:applicationContext.xml,
	classpath:applicationContext-1.xml,
	classpath:applicationContext-2.xml
</param-value>	

或

(推荐)
<param-value>
	classpath:applicationContext.xml,
	classpath:applicationContext-*.xml
</param-value>

2.在主配置文件applicationContext.xml中引入其他文件

<import resource="applicationContext-*.xml" />
...
springIOC容器与Servlet容器搭建通道,传递数据 (servlet与service)

在Servlet的init初始化方法中,获取SpringIOC容器中的bean对象

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext("");
	xxxService  = (xxxxService) context.getBean("");

SpringMVC

SpringMVC流程:

  1. 用户发送请求至前端控制器DispatcherServlet。

  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。

  3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

  4. DispatcherServlet调用HandlerAdapter处理器适配器。

  5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

  6. Controller执行完成返回ModelAndView。

  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

  9. ViewReslover解析后返回具体View。

  10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

  11. DispatcherServlet响应用户。

SpringMVC简介:

SpringMVC是一种基于Java,实现了Web MVC设计模式,请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦。基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,SpringMVC也是要简化日常Web开发。(处理业务数据的对象和显示业务数据的视图之间存在紧密耦合)。

MVC设计模式:

MVC即Model-View-Controller,将应用按照Model(模型)、View(视图)、Controller(控制)这样的方式分离。

  • 视图(View):代表用户交互界面,对于Web应用来说,可以是HTML,也可能是jsp、XML和Applet等。一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理。业务流程的处理交予模型(Model)处理。

  • 模型(Model):是业务的处理以及业务规则的制定。模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计是MVC最主要的核心。MVC设计模式告诉我们,把应用的模型按一定的规则抽取出来,抽取的层次很重要,抽象与具体不能隔得太远,也不能太近。MVC并没有提供模型的设计方法,而只是组织管理这些模型,以便于模型的重构和提高重用性。

  • 控制(Controller):可以理解为从用户接收请求, 将模型与视图匹配在一起,共同完成用户的请求。划分控制层的作用也很明显,它清楚地告诉你,它就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层并不做任何的数据处理。

适配器的作用

SpringMVC涉及的映射器负责将前端请求的url映射到配置的处理器,视图解析器将最终的结果进行解析,但中间为什么要经过一层适配器呢,为什么不经映射器找到controller后直接执行返回呢?

那是因为SpringMVC为业务处理器提供了多种接口实现(例如实现了Controller接口),而适配器就是用来根据处理器实现了什么接口,最终选择与已经注册好的不同类型的Handler Adapter进行匹配,并最终执行,例如,SimpleControllerHandlerAdapter是支持实现了controller接口的控制器,如果自己写的控制器实现了controller接口,那么SimpleControllerHandlerAdapter就会去执行自己写的控制器中的具体方法来完成请求。

SpringMVC的特点:
  • 清晰的角色划分:控制器(controller)、验证器(validator)、 命令对象(command object)、表单对象(formobject)、模型对象(model object)、 Servlet分发器(DispatcherServlet)、处理器映射(handler mapping)、视图解析器(view resolver)等。每一个角色都可以由一个专门的对象来实现。
  • 强大而直接的配置方式:将框架类和应用程序类都能作为JavaBean配置,支持跨多个context的引用,例如,在web控制器中对业务对象和验证器(validator)的引用。
  • 可适配、非侵入:可以根据不同的应用场景,选择合适的控制器子类 (simple型、command型、form型、wizard型、multi-action型或者自定义),而不是从单一控制器 (比如Action/ActionForm)继承。
  • 可重用的业务代码:可以使用现有的业务对象作为命令或表单对象,而不需要去扩展某个特定框架的基类。
  • 可定制的绑定(binding) 和验证(validation):比如将类型不匹配作为应用级的验证错误, 这可以保存错误的值。再比如本地化的日期和数字绑定等等。在其他某些框架中,你只能使用字符串表单对象,需要手动解析它并转换到业务对象。
  • 可定制的handlermapping和view resolution:Spring提供从最简单的URL映射, 到复杂的、专用的定制策略。与某些webMVC框架强制开发人员使用单一特定技术相比,Spring显得更加灵活。
  • 灵活的model转换:在Springweb框架中,使用基于Map的 键/值对来达到轻易地与各种视图技术的集成。
  • 可定制的本地化和主题(theme)解析:支持在JSP中可选择地使用Spring标签库、支持JSTL、支持Velocity(不需要额外的中间层)等等。
  • 简单而强大的JSP标签库(SpringTag Library):支持包括诸如数据绑定和主题(theme) 之类的许多功能。
  • JSP表单标签库:在Spring2.0中引入的表单标签库,使得在JSP中编写 - 表单更加容易。
    Spring Bean的生命周期可以被限制在当前的HTTP Request或者HTTP Session。
SpringMVC的优点:
  • 让我们能非常简单的设计出干净的Web层和薄薄的Web层
  • 进行更简洁的Web层的开发
  • 天生与Spring框架集成(如IoC容器、AOP等)
  • 提供强大的约定大于配置的契约式编程支持
  • 非常灵活的数据验证、格式化和数据绑定机制
  • 支持Restful风格
SpringMVC入门程序:

web.xml

<web-app>
    <servlet>
        <!-- 加载前端控制器 -->
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 
  	       加载配置文件
  	       默认加载规范:
  	       * 文件命名:servlet-name-servlet.xml====springmvc-servlet.xml
  	       * 路径规范:必须在WEB-INF目录下面
  	       修改加载路径:
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>   
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

springmvc.xml

<beans>
	<!-- 配置映射处理器:根据bean(自定义Controller)的name属性的url去寻找handler;springmvc默认的映射处理器是BeanNameUrlHandlerMapping-->
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
	
	<!-- 配置处理器适配器来执行Controller ,springmvc默认的是SimpleControllerHandlerAdapter
	-->
	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
	
	<!-- 配置自定义Controller -->
	<bean id="myController" name="/hello.do" class="org.controller.MyController"></bean>
	
	<!-- 配置sprigmvc视图解析器:解析逻辑视图; 
		后台返回逻辑视图:index
		视图解析器解析出真正物理视图:前缀+逻辑视图+后缀====/WEB-INF/jsps/index.jsp
	-->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsps/"></property>
		<property name="suffix" value=".jsp"></property>		
	</bean>
</beans>

自定义处理器

public class MyController implements Controller{
 
	public ModelAndView handleRequest(HttpServletRequest arg0,
			HttpServletResponse arg1) throws Exception {
		ModelAndView mv = new ModelAndView();
		//设置页面回显数据
		mv.addObject("hello", "欢迎学习springmvc!");
		
		//返回物理视图
		//mv.setViewName("/WEB-INF/jsps/index.jsp");
		
		//返回逻辑视图
		mv.setViewName("index");
		return mv;
	}
}
SpringMVC常用注解及其作用

@Controller:标识这个类是一个控制器

@RequestMapping:给控制器方法绑定一个uri

@ResponseBody:将java对象转成json,并且发送给客户端

@RequestBody:将客户端请求过来的json转成java对象

@RequestParam:当表单参数和方法形参名字不一致时,做一个名字映射

@PathVarible:用于获取uri中的参数,比如user/1中1的值

Rest风格的新api:

@RestController相当于@Controller+ @ResponseBody

@GetMapping@DeleteMapping@PostMapping@PutMapping

其他注解:

@SessionAttribute:声明将什么模型数据存入session

@CookieValue:获取cookie值

@ModelAttribute:将方法返回值存入model中

@HeaderValue:获取请求头中的值

SpringMVC和Struts2的对比

框架机制:SpringMVC的入口是servlet,而Struts2是filter。

Filter在容器启动后就初始化,服务停止后销毁,晚于Servlet;Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。

拦截机制

Struts2:
1、Struts2框架是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype(否则会出现线程并发问题),然后通过setter,getter吧request数据注入到属性;

2、一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,说明属性参数是让多个方法共享的;

3、Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。

SpringMVC:
1、SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架;

2、在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改;

Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。

性能方面:SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。而Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,所以,SpringMVC开发效率和性能高于Struts2。

配置方面:spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少);
SpringMVC可以认为已经100%零配置。

设计思想:Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。

集成方面:SpringMVC集成了Ajax。

注意:springmvc是单例模式的框架,但它是线程安全的,因为springmvc没有成员变量,所有参数的封装都是基于方法的,属于当前线程的私有变量. 因此是线程安全的框架。所以效率高。

struts action是多例的。所以可以使用成员变量获取参数。所以效率低。


Mybatis

MyBatis 可以简化JDBC操作,实现数据持久化

  • ORM: Object Relational Mapping
  • ORM概念:MyBatis是ORM的一个实现 / Hibernate
  • ORM可以使得开发人员,像操作对象一样操作数据库表
开发Mybatis步骤:

配置Mybatis

  1. jar包: mybatis.jar ojdbc6.jar
  • config.xml : 配置数据库信息 和 需要加载的映射文件
  • 表 - 类
  • 映射文件xxxMapper.xml : 增删改查标签 < select>
  • 测试类:sqlSession.selectOne(“需要查询的SQL的namespace.id”,“SQL的参数值”);

config.xml

<?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">

	<!--
    default和id值保持一致,通过default找到id
  	-->
	<configuration>
    <environments default="development">   <!-- 默认环境,即环境的id -->
        <environment id="development">
            <!-- 配置事务的提交方式:
                    1.用JDBC方式进行事务处理(commit  rollback  close)
                    2.MANAGER:将事务交由其他组件去托管(spring, jobss),默认会关闭连接
                         <property name="closeConnection" value="false" />  // 设置为不关闭
             -->
            <transactionManager type="JDBC"/>

           <!-- 连接方式 UNPOOLED: 传统的连接方式(每次访问数据库都需要打开和关闭等操作)
                          POOLED: 使用数据库连接池
                            JNDI: 从tomcat获取一个内置的数据库连接池
            -->
           <dataSource type="POOLED">
               <property name="driver" value="oracle.jdbc.OracleDriver"/>
               <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"/>
               <property name="username" value="system"/>
               <property name="password" value="123456"/>

           </dataSource>
       </environment>
 	<mappers>
        <!-- 在配置文件中加载映射文件 -->
        <mapper resource="personMapper.xml"/>
    </mappers>
</configuration>

xxxMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
	<!DOCTYPE mapper  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	<!--
	    namespace       映射文件路径
	    id              区分查询语句
	    resultType      返回值
	    parameterType   传入参数的类型,这里是id的类型int
	-->
	<mapper namespace="com.pojo.personMapper">
   	 	<select id="queryPersonById" resultType="com.pojo.Person" parameterType="int">
      		select * from person where id = #{id}
   		</select>
	</mapper>

Mybatis的CRUD:

// 加载Mybatis文件,访问数据库
Reader reader = Resources.getResourceAsReader("config.xml");
// 当config.xml里的default不是所需的时,可以在build里强行切换数据库环境
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader, "development");
// SqlSessionFactory -- Connection
SqlSession sqlSession = sessionFactory.openSession();

//  通过配置文件personMapper.xml里的namespace和id获得sql语句
String statement = "com.pojo.personMapper.addPerson";
Person person = new Person(8, "cui8", 27);
//  insert 插入一个person
int count = sqlSession.insert(statement, person);
//需要 commit
sqlSession.commit();

System.out.println("增加" + count + "个成功");
sqlSession.close();

Mybatis 约定
输入参数parameterType 和 输出参数resultType,在形式上都只能有一个
如果输入参数是简单类型(8个基本+String),是可以使用任何占位符#{xxx}的;
如果是对象类型,则必须是对象的属性:#{属性名}
如果使用的事务方式为 jdbc,则需要手动提交:sqlSession.commit()

Mybatis动态代理方式的CRUD

原则:约定优于配置

硬编码方式:abc.java
Configguration conf = new Configuration();
con.setName(“myProject”);
配置方式:abc.xml
< name>myProject< /name>
约定:默认值就是myProject

具体实现步骤:

  1. jar包,config.xml ,mapper.xml…

(不同处)约定的目标

省略掉Statement,即根据约定直接定位出SQL语句

建立一个接口PersonMapper
约定
1. 方法名和mapper.xml 文件中标签的id值一样
2. 方法的输入参数类型和parameterType一样
3. 方法的返回值和resultType一样
如: Person queryPersonById(int id);

要实现接口中的方法 和 Mapper.xml中的SQL标签一 一对应,还需要:

namespace的值,就是接口的全类名(接口–mapper.xml一 一对应)

匹配的过程:(约定过程)

  1. 根据接口名 找到mapper.xml文件 (根据的是namespace=接口全类名)
  2. 根据接口的方法名 找到mapper.xml文件中的SQL标签(方法名=SQL标签id值)

根据以上两点可以保证:当调用接口中的方法时,程序能自动定位到某一个Mapper.xml文件中的SQL标签

习惯:SQL映射文件 和 接口放在同一位置(注意修改config.xml中加载mapper.xml文件的路径)

以上,可以通过接口的方法————> 映射到SQL语句

 // 通过约定接口的方式
PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);
personMapper.updatePerson(person);      //  根据接口的方法 --->  自动查找到SQL语句

优化:

  1. 可以将数据库信息放入db.properties,再通过 ${key} 动态引入
<configuration>
<properties resource="db.properties" />
  1. Mybatis 全局参数
//开启缓存
<settings>
	<setting name="cacheEnabled" value="true" />
	<setting name="" value="" />
	...
</settings>
  1. 设置类的别名(忽略大小写)

    • a. 设置单个别名

      在config.xml中,

< typeAliases> < typeAlias type="org...Person" alias="Person" />...
- b. 批量设置别名,别名就是不带包名的类名
// 包名  
< typeAliases> < package name="org.test" />...  

// Mybatis 还内置了一些常见类的别名:_integer/_byte/_long/int/boolean...  
  1. 类型处理器 (类型转换器)(将Java类型转换为JDBC类型,如int转换为oracle的number类型)

    • a. Mybatis 自带一些常见的类型处理器

      如:BooleanTypeHandler:Boolean/boolean --> 任何兼容的布尔值
      IntegerTypeHandler:Integer/int --> 任何兼容的数字和整形

    • b. 自定义Mybatis 类型处理器

      Java类型 --> 数据库(JDBC类型)
      示例:
      实体类Student: boolean stuSex true:男 false: 女
      表student:number stuSex 1:男 0:女

自定义类型转换器(boolean – number) 步骤:

a. 创建类型转换器,要实现 TypeHandler接口 或继承BaseTypeHandler(更简单)
b. 在config.xml 中配置转换器

<!-- 类型处理器,将java的boolean类型 转换为 jdbc的number类型 -->
<typeHandlers>
    <typeHandler handler="com.mybatis.MyTypeHandler" javaType="Boolean" jdbcType="INTEGER" />
</typeHandlers>

c. 更改映射文件

<!-- 验证类型转换器
     1.如果类的属性 和 表的字段类型 能够合理识别(String - varchar2),则可以使用resultType,否则使用resultMap(boolean-number)
     2.如果类的属性名 和 表的字段名 能够合理识别(String - varchar2),则可以使用resultType,否则使用resultMap(boolean-number)
-->

<select id="queryPersonByIdWithConverter" resultMap="resultPerson" parameterType="int">
    select * from person where id = #{id}
</select>
<!-- 建立Person属性和表的字段的对应关系  主键id,非主键result , 再设置需要转换的类型-->
<resultMap id="resultPerson" type="person">
    <id property="id" column="id" />
    <result property="sex" column="sex" javaType="boolean" jdbcType="INTEGER" />
</resultMap>
类型转换的增加
// 更改SQL语句中需要转换的字段
#{sex,javaType=boolean,jdbcType=INTEGER}

注意:

1. 映射文件路径

	 <!-- 在配置文件中加载映射文件 IDEA里无法加载src下的xml文件 因此改用url class package等方式(接口与映射文件名称相同),
	        或将xml文件放到resources目录-->
	 <!-- 通过包名设置路径 -->
	 <package name="com.mybatis.myInter" />

2. 映射文件和config.xml的jdbcType的类型

integer 必须写成大写形式:INTEGER

5. 取值符号

  1. 简单类型
    #{任意值} // 自动给String类型加上单引号’’ (自动类型转换)
    ${value} // 原样输出,但适合于动态排序(动态字段),其中的标识符只能是value
  2. 对象类型
    #{属性名}
    ${属性名}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值