Java入门(十)Spring框架 Mybatis框架 Ajax

📢:哈喽~☀️欢迎加入程序🐒大家庭,快点开始✒️自己的黑客帝国吧 ~🌊🌊

内容简述:Spring简介、Spring容器、Spring IOC/DI、Spring 五大组件、Spring MVC、Spring JDBC、MyBatis、AJAX。

一、Spring简介、Spring容器

1. Spring是什么?

  • 开源的,用来简化企业级应用开发的应用开发框架。

(1)简化开发

  • Spring对常用的api(比如jdbc) 做了封装,这样,可以大大简化这些api的使用。(比如使用springjdbc访问数据库,就不用考虑如何获取连接和关闭连接了)。

(2)解耦

  • Spring帮我们建立对象之间的依赖关系,这样,对象之间的耦合度会大大降低,代码的维护性会大大提高。(代码要求:高内聚(类的功能要单一),低耦合。)

(3)集成其它框架

  • Spring可以将其它的一些框架集成进来(比如用于定时任务处理的Quartz框架等),方便这些框架的使用。

    (因为spring可以集成其他框架,所以spring又叫做一站式框架)

2.Spring容器

(1)什么是Spring容器?

  • Spring框架中的一个核心模块,用于管理对象。

(2)启动Spring容器

  • step1.导包。

    spring-webmvc(org.springframework),junit

  • step2. 添加spring配置文件。

  • step3. 启动容器。

String config = "applicationcontext.xml";

/*
 * ApplicationContext 是接口
 * ClassPathXmlApplicationContext 是一个实现类,该类会依据类路径去查找spring配置文件,然后启动容器。
 */
ApplicationContext ac = new ClassPathXmlApplicationContext(config); 

(3)创建对象

  • 1)方式一: 无参构造器

    • step1. 为类添加无参构造器(或者缺省构造器)

    • step2. 在配置文件里面,添加bean元素。(注意:与javabean无关)

      注:bean就是容器所创建的对象。

    • step3. 启动容器,调用容器的getBean方法。

<!-- 使用无参构造器创建对象 -->
<!-- 
	id: bean的名字,要求唯一。
	class: 完整的类名(包括包名)
-->
<bean id="stu1" class="first.Student"/> 
  • 2)方式二: 静态工厂方法 (了解)
<!-- 使用静态工厂方法创建对象 -->
<!-- 
	factory-method: 指定一个静态方法。
	容器会调用该类的静态方法来创建一个对象。
-->
<bean id="cal1" class="java.util.Calendar" factory-method="getInstance"/> 
  • 3)方式三: 实例工厂方法(了解)
<!-- 使用实例工厂方法创建对象 -->
<!--
	factory-bean: 指定一个bean的id,容器会调用该bean的示例方法来创建一个对象。
-->
<bean id="time1" factory-bean="cal1" factory-method="getTime" /> 

(4)作用域

  • 1)默认情况下,容器对于每个bean元素,只会创建一个实例。

  • 2)如果将作用域设置为"prototype",则每调用一次getBean方法,就会创建一个新的实例。

<!-- 指定作用域 -->
<!--
	scope: 用来指定作用域,缺省值是singleton(单例,即只会创建一个对象),
		如果值是prototype(每调用一次getBean方法创建一个新的对象)。
	lazy-init: 如果值为true,标识延迟加载。
-->
<bean id="t1" class="basic.Teacher" scope="singleton" lazy-init="true" /> 

(5)延迟加载 (了解)

  • 1)默认情况下,容器启动之后,会将作用域为"singleton"的bean创建好。

  • 2)延迟加载指的是,容器启动之后,对作用域为"singleton"的bean不再创建,直到调用了getBean方法才会创建。

(6)生命周期

  • 1)初始化方法
    • 容器创建好bean的实例之后,会立即调用初始化方法。
  • 2)销毁方法
    • 容器关闭之前,会调用销毁方法。
<!-- 指定初始化方法和销毁方法 -->
<!--
	init-method: 指定初始化方法名。
	destroy-method: 指定销毁方法名。
	注意:销毁方法只对作用域为singleton的bean有效。
-->
<bean id="ms1" class="basic.MessageService" init-method="init" destroy-method="destroy"/> 

二、Spring IOC、参数值注入

1. IOC/DI

(1)IOC(Inversion Of Controll 控制反转)

  • 对象之间的依赖关系由容器来建立。

(2)DI(Dependency Injection 依赖注入

  • 容器可以通过调用set方法或者构造器来建立对象之间的依赖关系。

总结: IOC是目标,DI是手段。

在这里插入图片描述

(3)依赖注入的两种方式

  • 1)方式一: set方法注入
    • step1. 添加set方法;
    • step2. 在配置文件中,使用<property>元素来配置。
<bean id="b1" class="ioc.B"/>
<!-- 
	property: 让容器调用set方法来建立依赖关系。
	其中,name属性指定属性名,ref指定被注入的bean的id。
 -->
<bean id="a1" class="ioc.A">
	<!-- b为属性名,spring会调用将属性名首字母大写,前面添加set的方法,比如setB()-->    
	<property name="b" ref="b1" />
</bean>
  • 2)方式二: 构造器注入
    • step1. 添加构造器;
    • step2. 在配置文件当中,使用<constructor-arg>元素来配置。
<!-- 构造器注入 -->
<!-- 
	constructor-arg: 容器会采用构造器来建立依赖关系。其中,index指定参数的下标。
 -->
<bean id="cp1" class="ioc.Computer" />
<bean id="mg1" class="ioc.Manager">
	<constructor-arg index="0" ref="cp1"/>
</bean> 

(4)自动装配

  • 自动装配,指的是容器依据某些规则,自动建立对象之间的依赖关系。

    (底层仍然是需要调用set方法或者构造器)

  • 1)默认情况下,容器不会自动装配。

  • 2)设置autowire属性

    • autowire: 表示让容器自动建立对象之间的依赖关系。

    • byName: 依据属性名查找对应的bean(就是以属性名作为bean的id来查找),找到之后,调用set方法来建立依赖关系。

      :如果找不到,则不注入。

    • byType: 依据属性类型来查找对应的bean,找到之后,调用set方法来建立依赖关系。

      :如果找到多个,则会出错。

    • constructor: 与byType类似,只不过,调用构造器来注入。

(5)注入基本类型的值

  • 使用value属性来注入,spring容器会帮我们做一些类型的转换工作,比如将字符串转换成数字。

(6)注入集合类型的值 (List,Set,Map,Properties)

  • 方式一: 直接注入

    :list的value值可以重复,set的value值不可以重复(重复的话只存一遍)。

xml代码

<list>
	<value>台球</value>
    <value>钓鱼</value>
    <value>看电视</value>
    <value>看电视</value>
</list>
<set>
	<value>北京</value>
    <value>上海</value>
    <value>武汉</value>
    <value>武汉</value>
</set>
<map>
	<entry key="english" value="70"/>
    <entry key="math" value="90"/>
</map>
<props>
	<prop key="username">Sally</prop>
    <prop key="password">1234</prop>
</props>

java代码

public class ValueBean {
	private String name;
	private int age;
	private List<String> interest;
	private Set<String> city;
	private Map<String, Double> score;
	private Properties db;
    getXXX(){};
    setXXX(){};
    toString(){};
}

注意:Properties是键值对,值只能是字符串

  • 方式二: 引用的方式注入
    • step1. 将集合类型的值先配置成一个bean。
    • step2. 再将这个bean注入到对应的bean里面。
<util:list id="interestBean">
	<value>喝酒</value>
    <value>烫头</value>
    <value>抽烟</value>
</util:list>
<!-- 采用引用的方式注入集合类型的值 -->
<bean id="eb1" class="value.ExampleBean">
	<property name="interest" ref="interestBean"/>
</bean> 

注意:util是命名空间,namespace,是为了区分同名的元素而添加的限定

(7)读取.properties文件的内容

<!-- 读取.properties文件的内容 -->
<!--
	location: 指定属性文件的位置。
	注:classpath,表示让容器依据类路径去查找属性文件。
	容器回读取指定位置的文件的内容,并且将这些内容存放到Properties对象里面。
 -->

文件位置:

在这里插入图片描述

文件内容:

在这里插入图片描述

测试:

@Test
// 测试 读取属性文件的内容
public void test8(){
    String config = "value.xml";
    AbstractApplicationContext ac = new ClassPathXmlApplicationContext(config);
    Properties props = ac.getBean("config", Properties.class);
    System.out.println(props);
    ac.close();
}

结果:

在这里插入图片描述

三、基于注解的组件扫描、SpringMVC、五大组件

注意:javaBean和bean一点关系都没有。

(8)spring表达式

  • 读取bean的属性

在这里插入图片描述

1.使用注解来简化配置文件

(1)什么是组件扫描?

  • 容器会扫描指定的包及其子包下面的所有的类,如果该类前面有特定的注解比如@Component),则容器会将其纳入容器进行管理(相当于在配置文件里面有一个bean元素)。

(2)如何进行组件扫描?

  • step1. 在类前面添加特定的注解,比如 @Component

    (注:默认的id是首字母小写之后的类名。)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • step2. 在配置文件当中,配置组件扫描。

在这里插入图片描述

(3)依赖注入相关的注解

  • 1)@Autowired @Qualifier–(依赖于spring,@Autowired先根据类型查找(byType,byType默认使用set方法注入),如果找到一个接口下面有多个实现,则再根据名称查找(byName,或者直接使用@Qualifier实现byName方式),如果还找不到就会抛出异常)

    (注:该注解支持set方法和构造器注入。)

注意:@Autowired不需要手动显式地声明set方法和构造器方法。

注意

  1. bean配置文件中的set注入和构造器注入指的是将容器中创建好的bean实例通过set方法和构造器方法注入到相应的属性中;
  2. @Autowired,@Resource注解是将容器中创建好的bean实例直接注入到相应的变量中,然后调用修饰的方法给类的属性赋值。其中,@Autowired支持修饰set方法和构造器方法,@Resource只支持修饰set方法。

在这里插入图片描述

在这里插入图片描述

  • 2)@Resource–(依赖于javaee,包为javax.annotation-api-1.2.jar)

    (设定项目tomcat依赖的时候会自动导入)

    (注:该注解只支持set方法注入。)

在这里插入图片描述

在这里插入图片描述

(4)注入基本类型的值和spring表达式的值

在这里插入图片描述

在这里插入图片描述

SpringMVC

(1)什么是SpringMVC?

  • 用来简化基于MVC架构的web应用程序开发的框架。

    (注:SpringMVC是spring中的一个模块。)

在这里插入图片描述

(2)五大组件

  • 1)有哪五大组件?

    • DispatcherServlet 前端控制器(在web.xml文件中配置)
    • HandlerMapping 映射处理器(在Spring配置文件中配置)
    • Controller 处理器(在Spring配置文件中配置+代码实现)
    • ModelAndView 处理结果和视图名(在Spring配置文件中配置)
    • ViewResolver 视图解析器
  • 2)它们之间的关系

    • a.请求发送给DispatcherServlet来处理,DispatcherServlet会依据HandlerMapping的配置调用对应的Controller来处理。

    • b.Controller将处理结果封装成ModelAndView对象,然后返回给DispatcherServlet。

    • c.DispatcherServlet会依据ViewResolver的解析调用对应的视图对象(比如jsp)来生成相应的页面。

      (注:视图部分可以使用jsp,也可以使用其它的视图技术,比如 freemarker,velocity 等等。)

在这里插入图片描述

(3)编程步骤

  • step1. 导包 spring-webmvc
  • step2. 添加配置文件。
  • step3. 配置DispatcherServlet。
  • step4. 写Controller。
  • step5. 写jsp。
  • step6.在配置文件当中,添加HandlerMapping, ViewResolver的配置。
<!-- 配置HandlerMapping映射处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
	<property name="mappings">
		<props>
			<prop key="/hello.do">helloController</prop>
		</props>
	</property>
</bean>

<!-- 配置Controller处理器 -->
<bean id="helloController" class="controller.HelloController" />
 
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/" /><!-- 前缀 -->
	<property name="suffix" value=".jsp" /><!-- 后缀 -->
</bean>

在这里插入图片描述

练习: http://localhost:8080/springmvc-lab/toLogin.do 返回一登录页面。

四、SpringMVC应用

1. 基于注解的SpringMVC应用

(1)编程步骤

  • step1.导包 spring-webmvc
  • step2.添加spring配置文件。
  • step3.配置DispatcherServlet。
  • step4.写Controller
    • 1.不用实现Controller接口;
    • 2.方法签名不做要求,返回值可以是ModelAndView,也可以是String;
    • 3.可以添加多个方法;
    • 4.使用@Controller;
    • 5.可以在方法前或者类前添加@RequestMapping,相当于HandlerMapping。
  • step5.写jsp
  • step6.在配置文件当中,添加ViewResolver配置,添加组件扫描,添加MVC注解扫描。
<!-- 配置组件扫描 -->
<context:component-scan base-package="controller"/>
<!-- 配置MVC注解扫描 -->
<mvc:annotation-driven />
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/" /><!-- 前缀 -->
    <property name="suffix" value=".jsp" /><!-- 后缀 -->
</bean>

注意:需要添加相应的注解,比如@RequestMapping,MVC注解扫描才会扫描到。

(2)读取请求参数值

  • 1)方式一:通过request提供的方法
public String login(HttpServletRequest request){
    System.out.println("login()");
    String adminCode = request.getParameter("adminCode");
} 
  • 2)方式二:通过@RequestParam注解
public String login2(String adminCode, @RequestParam("pwd")String password){
    // 当请求的参数和实际的参数名不一致的时候,使用@RequestParam注解
} 
  • 3)方式三:通过javabean

    • step1. 先写一个java类

      /**
       * 用于封装请求参数值,属性名与请求参数名一致
       * 		注:
       * 			名称要一样,类型要匹配
       * 			(数字会自动进行相应的类型转换,比如将String转换成int)
       * 		提供相应的get/set方法
       * @author ACGkaka
       */
      public class AdminParam {
      	private String adminCode;
      	private String pwd;
      	private int phone;
      	
      	public int getPhone(){
      		return phone;
      	}
      	public void setPhone(int phone){
      		this.phone = phone;
      	}
      	public String getAdminCode(){
      		return adminCode;
      	}
      	public void setAdminCode(String adminCode){
      		this.adminCode = adminCode;
      	}
      	public String getPwd(){
      		return pwd;
      	}
      	public void setPwd(String pwd){
      		this.pwd = pwd;
      	}
      }
      
    • step2. 将该类作为方法参数

      public String login3(AdminParam ap){
          System.out.println("login3()");
          System.out.println("adminCode:" + ap.getAdminCode());
          return "index";
      } 
      

(3)向页面传值

  • 1)方式一:将数据绑订到request

    @RequestMapping("/login4.do")
    public String login4(AdminParam ap,HttpServletRequest request){
        System.out.println("login4()");
        String adminCode=ap.getAdminCode();
        request.setAttribute("adminCode", adminCode);
        //默认情况下,DispatcherServlet
        //会使用转发。
        return "index";
    }
    
  • 2)方式二:返回ModelAndView

    @RequestMapping("/login5.do")
    public ModelAndView login5(AdminParam ap){
        System.out.println("login5()");
        String adminCode=ap.getAdminCode();
        //step1.将数据添加到一个Map对象里面
        Map<String,Object> data=new HashMap<String, Object>();
        //相当于执行了request.setAttribute
        data.put("adminCode", adminCode);
        //step2.将Map对象添加到ModelAndView中
        ModelAndView mav=new ModelAndView("index",data);
        return mav;
    }
    
  • 3)方式三:将数据添加到ModelMap

    @RequestMapping("/login6.do")
    public String login6(AdminParam ap,ModelMap mm){
        System.out.println("login6()");
        String adminCode=ap.getAdminCode();
        mm.addAttribute("adminCode",adminCode);
        return "index";
    } 
    
  • 4)方式四:将数据绑订到session

    @RequestMapping("/login7.do")
    public String login7(AdminParam ap,HttpSession session){
        System.out.println("login7()");
        String adminCode=ap.getAdminCode();
        session.setAttribute("adminCode", adminCode);
        return "index";
    }
    

(4)重定向

  • 1)方法的返回值是String,比如: return “redirect:toIndex.do”;

    @RequestMapping("/login8.do")
    public String login8(){
    	System.out.println("login8()");
    	return "redirect:toIndex.do";
    }
    
    @RequestMapping("/toIndex.do")
    public String toIndex(){
    	System.out.println("toIndex()");
    	return "index";
    }
    
  • 2)方法的返回值是ModelAndView,比如:

    @RequestMapping("/login9.do")
    public ModelAndView login9(){
        System.out.println("login9()");
        RedirectView rv=new RedirectView("toIndex.do");
        ModelAndView mav=new ModelAndView(rv);
        return mav;
    }
    

五、系统分层、登录案例

1.系统分层

(1)为什么要分层?

  • 为了系统好维护,系统的设计应该要做到“高内聚,低耦合”。
  • 高内聚”:指的是类的职责要单一,这样,一个类就可以会拆分成多个类(比如AccountService拆分成了AccountService和AccountDAO),这样,就形成了分层的概念。
  • 低耦合”:指的是类与类之间不要直接依赖。(AccountService要调用AccountDAO,应该使用依赖注入)。

(2)如何分层?

  • 表示层:数据展现和操作界面,以及请求分发。(Controller)

  • 业务层:封装了业务逻辑。 (Service)

  • 持久层: 封装了数据访问逻辑。(DAO)

:表示层调用业务层,业务层调用持久层。上一层通过接口来调用下一层提供的服务(这样,下一层的实现发生了改变,不影响上一层)。

在这里插入图片描述

在这里插入图片描述

六、中文乱码处理、拦截器、Spring处理异常

1. 表单包含有中文参数值,如何读取?

  • springmvc提供了一个过滤器(CharacterEncodingFilter),只需要配置该过滤器即可。

注意

a. 表单的提交方式必须是"post"。

b. 编码与浏览器端的一致。

在这里插入图片描述

2.拦截器

(1)什么是拦截器?

  • DispatcherServlet收到请求之后,如果有拦截器,会先调用拦截器,然后再调用Controller。

补充:过滤器属于servlet规范,而拦截器属于spring框架。

在这里插入图片描述

在这里插入图片描述

(2)如何写一个拦截器?

  • step1. 写一个java类,实现HandlerInterceptor接口。

  • step2. 在接口方法里面,实现拦截处理逻辑。

  • step3. 配置拦截器。

在这里插入图片描述

面试题:过滤器和拦截器在验证登录功能方面有什么区别?

  • 过滤器更通用一些,拦截器是依赖于spring框架的!

面试题:过滤器和拦截器的区别?

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调

2、过滤器依赖于servlet容器,而拦截器依赖于Spring容器

3、Filter是Servlet规范固定的,只能用于Web程序中,而拦截器既可以用户Web程序,也可以用于Application、Swing程序中

4、Filter在只在Servlet启动前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用弹性更大一些,所以在使用Spring架构的程序中,要优先使用拦截器。

5、过滤器和拦截器触发时机不一样,过滤器是在【请求进入容器后,但请求进入servlet之前】进行预处理的。请求结束返回也是,是【在servlet处理完后,返回给前端之前】。

6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。

详细链接:https://www.iteye.com/blog/uule-2442198

3.让spring框架帮我们处理异常

  • 即:将异常抛给spring框架,让spring框架来处理。

  • 默认情况下,spring框架会将异常直接抛给最终的用户。

(1)方式一:配置简单异常处理器。

  • step1.在spring配置文件当中,配置简单异常处理器。

在这里插入图片描述

  • step2.添加相应的异常处理页面。 注:简单异常处理器,不能够对异常做复杂的处理。

(2)方式二: @ExceptionHandler。

  • step1. 在处理器当中添加一个异常处理方法。该方法前面需要添加@ExceptionHandler注解。

  • step2. 在异常处理方法里面,依据异常类型做不同的处理。

/**
  * 这是一个异常处理方法
  * e:处理器方法所抛出的异常。
  * @return
  */
@ExceptionHandler
public String handlerEx(Exception e,HttpServletRequest request){
    System.out.println("handleEx()");
    if(e instanceof NumberFormatException){
        e.printStackTrace();
        request.setAttribute("msg", "亲,请输入正确的数字");
        return "error3";
    }else if(e instanceof StringIndexOutOfBoundsException){
        e.printStackTrace();
        request.setAttribute("msg", "下标越界啦");
        return "error3";
    }
    return "error";
}

七、SpringJDBC、Mybatis

1.SpringJdbc、Mybatis

(1)SpringJdbc是什么?

  • Spring框架对jdbc的封装。

(2)编程步骤

  • step1.导包 spring-webmvc,spring-jdbc,ojdbc,dbcp,junit。
  • step2.添加spring配置文件。
  • step3.配置JdbcTemplate。

:JdbcTemplate把一些重复性的代码(比如获取连接,关闭 连接,异常处理等等都写好了),我们只需要调用该对象的方法就可以很方便的访问数据库。

在这里插入图片描述

  • step4.调用JdbcTemplate的方法来访问数据库。

:通常将JdbcTemplate注入到DAO。

@Respository("employeeDAO")
public class EmployeeDAO {
    @Autowired
    @Qualifier("jt")
    private JdbcTemplate jt;
} 
create table t_emp(
  id number(8)primary key,
  name varchar2(20),
  age number(3)
);

create sequence t_emp_seq;

总结:

(1)Spring提供的JdbcTemplate对jdbc做了封装,大大简化了数据库的操作。

(2)Spring提供的JdbcTempate能直接数据对象映射成实体类,不再需要获取ResultSet去获取值/赋值等操作,提高开发效率。

(3)调用的还是javaweb中的jdbc,是对原生jdbc的封装,代码量更小,如同DBUtils一样。

2.MyBatis

(1)MyBatis是什么?

  • 开源的持久层框架。

:MyBatis底层仍然是jdbc。

  • Jdbc

    • 优点:性能高,易掌握;
    • 缺点:代码繁琐。
  • Hibernate

    • 优点:不用写sql,代码简洁;
    • 缺点:性能不好,复杂自动生成的sql效率低下,不容易掌握。
  • MyBatis

    • 优点:代码简洁,容易掌握;
    • 缺点:还得写sql,性能一般。

(2)编程步骤

  • step1. 导包。 mybatis,ojdbc,junit

  • step2. 添加配置文件。

:主要是连接池的配置和映射文件的位置。

在这里插入图片描述

  • step3. 写实体类。

:实体类的属性名与表的字段名要一样(大小写可以忽略)。

  • step4. 添加映射文件。

:里面主要是sql语句。

<mapper namespace="test">
	<!--
		id: 要求唯一
		parameterType: 参数类型,这儿填写实体类的完整的名字。
	-->
	<insert id="save" parameterType="entity.Employee">
		insert into t_emp values(t_emp_seq.nextval,#{name},#{age})
	</insert>
</mapper>

注意:当parameterType为基本类型时,也就是说参数为一个值的时候(比如findById的参数id),#{}里面写什么变量都可以。

  • step5. 调用SqlSession对象提供的方法来访问数据库。

TestCase.java

public class TestCase {
	@Test
	public void test1(){
		String config="SqlMapConfig.xml";
		// step1.创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder ssfb=new SqlSessionFactoryBuilder();
        // step2.创建SqlSessionFactory对象
        SqlSessionFactory ssf=ssfb.build(TestCase.class.getClassLoader().getResourceAsStream(config));
        // step3.获得SqlSession对象
        SqlSession session=ssf.openSession();
        // 调用SqlSession对象提供的方法访问数据库
        Employee e=new Employee();
        e.setName("Eric");
        e.setAge(33);
        session.insert("test.save",e);
        // 添加,修改,删除都需要提交事务
        session.commit();
        // 关闭SqlSession
        session.close();
	}
}

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
	<environments default="environment">
		<environment id="environment">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="oracle.jdbc.driver.OracleDriver" />
				<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
				<property name="username" value="system" />
                <property name="password" value="root" />
			</dataSource>
		</environment>
	</environments>
	<!-- 指定映射文件的位置 -->
	<mappers>
		<mapper resource="entity/EmpMapper.xml" />
	</mappers>
</configuration> 

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="test">
	<!-- 
		id:要求唯一
		parameterType:参数类型,这儿填写实体类的完整的名字。
	-->
	<insert id="save" parameterType="entity.Employee">
		insert into t_emp values(t_emp_seq.nextval,#{name},#{age})
	</insert>
</mapper>

(3)工作原理

在这里插入图片描述

  1. SqlSessionFactory读取SqlMapConfig.xml文件,文件中包含了EmpMapper.xml文件的地址;

  2. 然后,SqlSessionFactory会创建一系列预编译的Map对象,key是sql的id,value是对应的statement;

  3. 通过SqlSessionFactory获得SqlSession;

  4. 通过向SqlSession的相应方法中传入sqlid和相应的参数;

  5. SqlSession会自动根据sqlid去预编译好的Map对象中查找对应的statment,然后执行,完成相应的功能。

八、Mybatis基本应用、Mapper映射器、Spring Mybatis(方式一)

练习:

使用MyBatis完成对部门表的增删改查操作。

a.添加部门信息。

b.查询出所有部门信息

c.依据id查询某个部门信息

d.修改某个部门信息

e.删除某个部门。

create table t_dept(
  id number(8)primary key,
  deptName varchar2(20),
  addr varchar2(50)
);
create sequence t_dept_seq;

1.返回Map类型的结果

  • (1)MyBatis会将记录中的数据先放到一个Map对象里面

    (以字段名作为key,以字段值作为value,一条记录对应一个Map对象),

    然后 再将Map中的数据放到对应的实体对象里面。

在这里插入图片描述

  • (2)返回Map类型的结果,好处是不用实体类了,但是不方便

    (因为要获得字段值,还需要调用Map对象提供的get方法,

注意:oracle数据库中,字段名统一都是大写,其他数据库不一定这样,很难确定map的key值)。

2.解决字段名与实体类的属性名不一致

  • (1)方式一: 使用别名。(就是让别名与属性名一样)。

    select ename as name …

  • (2)方式二: 使用resultMap解决。

在这里插入图片描述

3.Mapper映射器

(1)什么是Mapper映射器?

  • 符合映射文件要求的接口。

:MyBatis会生成符合该接口要求的对象。

(2)接口具体要求

  • a.方法名要与sql的id一致。

  • b.方法的参数类型要与parameterType一致。

  • c.方法的返回类型要与resultType一致。

  • d.映射文件的namespace要等于接口的完整的名字。

在这里插入图片描述

在这里插入图片描述

(3)如何使用Mapper映射器

// MyBatis会返回一个符合
// Mapper映射器要求的对象。
EmployeeDAO dao = session.getMapper(EmployeeDAO.class);

4.Spring集成MyBatis (方式一 使用Mapper映射器)

(1)集成步骤

  • step1.导包。spring-webmvc,mybatis,mybatis-spring,dbcp,ojdbc,spring-jdbc,junit。

在这里插入图片描述

  • step2.添加spring配置文件。

:不再需要MyBatis的配置文件,可以在spring的配置文件里面添加SqlSessionFactoryBean来代替。

<!-- 配置SqlSessionFactoryBean -->
<bean id="ssfb" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注入连接池 -->
    <property name="dataSource" ref="ds"/>
    <!-- 注入映射文件的位置 -->
    <property name="mapperLocations" value="classpath:entity/*.xml" />
</bean> 
  • step3.实体类
  • step4.映射文件

:mapper.xml文件的namespace要求等于接口名。

  • step5.Mapper映射器

  • step6.配置MapperScannerConfigurer

:该bean会扫描指定包及其子包下面的所有的Mapper映射器(即接口),然后调用getMapper方法获得映射器的实现(比如,调用 EmployeeDAO dao = SqlSession.getMapper(EmployeeDAO.class))。并且,将这些对象添加到Spring容器里面(默认的id是首字母小写之后的接口名,可以使用@Repository重命名)。

<!-- 配置MapperScannerConfigurer -->
<!-- id默认是类名首字母小写 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 注入映射器所在的包名 -->
    <property name="basePackage" value="dao"/>
</bean>

(2)只扫描特定的接口。

  • step1. 开发一个注解。

在这里插入图片描述

  • step2. 将该注解添加到需要扫描的接口之上。

在这里插入图片描述

  • step3. 修改MapperScannerConfigurer的配置。
<!-- 配置MapperScannerConfigurer -->
<!-- id默认是类名首字母小写 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 注入映射器所在的包名 -->
    <property name="basePackage" value="dao"/>
    <!-- 只扫描带有特定注解的接口 -->
    <property name="annotationClass" value="annotation.MyBatisRepository"/>
</bean>

九、Spring MyBatis(方式二)

1.Spring集成MyBatis (方式二)

(1)集成步骤

  • step1.导包。spring-webmvc,mybatis,mybatis-spring,dbcp,ojdbc,spring-jdbc,junit。

  • step2.添加spring配置文件。

:不再需要MyBatis的配置文件,可以在spring的配置文件里面添加SqlSessionFactoryBean来代替。

  • step3.实体类
  • step4.映射文件

:namespace不再要求等于接口名。

  • step5.DAO接口

:接口方法没有特定要求

  • step6.写一个DAO接口的实现类

:可以注入SqlSessionTemplate。

<!-- 配置SqlSessionTemplate -->
<bean id="sst" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="ssfb"/>
</bean>
@Repository("empDAO")
public Class EmployeeDAOMyBatisImpl implements EmployeeDAO {
	@Autowired
    @Qualifier("sst")
    private SqlSessionTemplate sst;
}

2.使用Spring集成MyBatis的方式重写AdminDAO

SSM(SM):SpringMVC+Spring+Mybatis

  • step1. 导包,需要添加 mybatis,mybatis-spring,spring-jdbc

  • step2. 在配置文件当中,添加 SqlSessionFactoryBean

  • step3. 实体类Admin,要注意属性与表的字段名不一样,建议用别名解决

  • step4. 映射文件,放在entity包下面

    AdminMapper.xml

<mapper namespace="cn.tedu.netctoss.dao.AdminDAO">
    <select id="findByAdminCode" parameterType="java.lang.String"
            resultType="cn.tedu.netctoss.entity.Admin">
        SELECT ...
    </select>
</mapper>
  • step5. Mapper映射器 (AdminDAO)

  • step6. 配置MapperScannerConfigurer

  • step7. 测试 AdminDAO

十、AJAX简介

3.ajax (asynchronous javascript and xml 异步的javascript和xml)

(1)ajax是什么?

  • 是一种用来改善用户体验的技术,本质上是利用浏览器提供的一个特殊对象(XMLHttpRequest对象;
  • 一般也可以称之为ajax对象)向服务器发送异步请求;服务器返回部分数据,浏览器利用这些数据对当前页面做部分更新;
  • 整个过程,页面无刷新,不打断用户的操作。

:异步请求,指的是,当ajax对象发送请求时,浏览器不会销毁当前页面,用户仍然可以对当前页面做其它操作。

在这里插入图片描述

(2)如何获得ajax对象?

  • 需要考虑一些ie老版本的用户,因为ie是ActiveXObject对象,其他浏览器是XMLHttpRequest对象,所以要分情况讨论:
function getXhr(){
	var xhr = null;
	if(window.XMLHttpRequest){
		//非ie浏览器
		xhr = new XMLHttpRequest();
	}else{
		xhr = new ActiveXObject('MicroSoft.XMLHttp');
	}
	return xhr;
}

(3)ajax对象的几个重要属性

  • onreadystatechange: 绑订事件处理函数,用来处理readystatechange事件。

    注:当ajax对象的readyState属性值发生了任何的改变,比如从0变成了1,就会产生readystatechange事件。

  • readyState:有5个值(分别是0,1,2,3,4),用来获取ajax对象与服务器通信的进展。其中,4表示ajax对象已经获得了服务器返回的所有的数据。

  • responseText:获得服务器返回的文本数据。

  • responseXML:获得服务器返回的xml数据。

  • status:获得状态码。(例如200,404,500…)

(4)编程步骤

  • step1. 获得ajax对象,比如 var xhr = getXhr();

  • step2. 调用ajax对象的方法,发送请求

    • 方式一 get请求
    // (请求方式,请求地址,boolean)
    xhr.open('get','check.do?adminCode=king',true);
    xhr.onreadystatechange = f1; // f1为事件处理函数
    xhr.send(null); // 把数据打包发送到服务器
    

    :

    • true: 异步 (浏览器不会销毁当前页面,用户仍然可以对当前页面做其它操作)
    • false:同步 (浏览器不会销毁当前页面,但是会锁定当前页面,用户不能够对当前页面做任何操作,尽量不用)。
    • 方式二 post请求
    xhr.open('post','check.do',true);
    // 设置请求头(消息头)
    xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
    // f1为事件处理函数
    xhr.onreadystatechange=f1;
    xhr.send('adminCode=king');
    

    :按照http协议要求,如果发送的是post请求,应该包含有Content-type消息头,但是,ajax默认不会带这个消息头,所以,需要调用setRequestHeader方法来添加这个消息头。

  • step3. 编写服务器端的程序

:不需要返回完整的页面,只需要返回部分数据。

  • step4. 编写事件处理函数
if(xhr.readyState == 4 && xhr.status == 200){
	// ajax对象已经获得了服务器返回的所有数据,
	// 而且服务器处理正确。
	var txt = xhr.responseText;
	// 页面更新...
}

十一、AJAX编码问题、缓存问题、JSON

1.编码问题

(1)GET请求

  • 1)为什么会有乱码?

    • ie浏览器提供的ajax对象,在发送get请求时,会对中文参数值使用"gbk"来编码,其它浏览器会使用"utf-8"来编码。服务器端默认会使用"iso-8859-1"来解码。所以会有乱码。
  • 2)如何解决?

    • step1. 服务器端,统一使用"utf-8"来解码。可以修改:

      <Connector URIEncoding="utf-8" />
      
    • step2.客户端,使用encodeURI函数对中文参数值进行编码。

    :encodeURI函数是javascript内置的函数,会使用"utf-8"来编码。

(2)POST请求

  • 1)为什么会有乱码?

    • 浏览器提供的ajax对象在发送post请求时,对中文参数值会使用"utf-8"来编码,而服务器端会使用"iso-8859-1"来解码。
  • 2)如何解决?

    • request.setCharacterEncoding(“utf-8”)

2.缓存问题

(1)什么是缓存问题?(GET请求才有缓存问题)

  • 如果使用ie浏览器提供的ajax对象发送get请求,会比较请求地址是否访问过,如果访问过,则不再发送新的请求,而是将第一次访问的结果显示出来(也就是说,第一次访问时,会将服务器返回的结果缓存下来了)。

(2)如何解决?

  • 在请求地址后面添加一个随机数。

    例:“getNumber.do?”+Math.random()

3.JSON (javascript object notation)

(1)json是什么?

  • 是一种轻量级的数据交换格式。(json借鉴了javascript的部分语法)
  • 数据交换:指的是将要交换的数据转换成一种与平台无关的数据格式(比如xml),然后发送给接收方来处理。
  • 轻量级:json相对于xml而言,文档更小,解析速度更快。

(2)语法

  • 1)表示一个对象

    {属性名:属性值,属性值:属性值…}

    • a.属性名必须使用双引号括起来。
    • b.属性值可以string,number,true/false,null,object。
    • c.属性值如果是string,必须使用双引号括起来。
  • 2)表示对象组成的数组

    [{},{},{}…]

(3)使用json

  • 1)java对象如何转换成json字符串?

    • 导包:在这里插入图片描述

    • 使用jackson提供的api(ObjectMapper)。

    • 例1:

    ObjectMapper om=new ObjectMapper();
    String jsonStr=om.writeValueAsString(stocks);
    
    • 例2:
    List<Stock> stocks=new ArrayList<Stock>();
    for(int i=0;i<3;i++){
    	Stock s=new Stock();
    	s.setCode("600977"+i);
    	s.setName("中国嘉陵"+i);
    	s.setPrice(8+i);
    	stocks.add(s);
    }
    ObjectMapper om=new ObjectMapper();
    String jsonStr=om.writeValueAsString(stocks);
    System.out.println(jsonStr);
    
  • 2)将json字符串转换成javascript对象?

    • 使用javascript内置对象JSON提供的parse()函数。

    • 例1:

      var str='{"name":"Sally","age":22}';
      // 使用javascript内置对象JSON提供的方法来转换
      var obj=JSON.parse(str);
      alert(obj.name);
      
    • 例2:

      var str='[{"name":"Sally","age":22},' + '{"name":"Eric","age":32}]';
      var arr=JSON.parse(str);
      // 返回的是由多个javascript对象组成的数组
      alert(arr[0].name);
      

在这里插入图片描述

案例:

在这里插入图片描述

十二、JQuery对ajax的支持、load方法

1.jQuery对ajax编程的支持

(1)$.ajax方法

  • 1)用法:

    $.ajax({});

    :{}是一个对象,其属性用来控制ajax对象如何向服务器

    • 发送请求,常见的属性如下:

      • url: 请求地址

      • sync: 是否为异步访问,有两个值:

        “true” 异步访问(默认)

        “false” 同步访问

      • type: 请求类型

      • data: 请求参数(可以是请求字符串形式,比如:“adminCode=king&age=22”,还可以是对象形式,比如{“adminCode”:“king”,“age”:22})

      • dataType: 服务器返回的数据类型,有如下类型:

        “json” json字符串

        “text” 文本

        “html” html文档

        “xml” xml文档

        “script” javascript脚本

      • success: 绑订事件处理函数(服务器已经返回了所有数据,并且没有出错)。

      • error: 绑订事件处理函数(服务器出错了)

  • 比如:

$.ajax({//用不到的参数可以不写
	url:"check.do",
	(sync: "true",)
	type:"get",
	data: "adminCode=king",
	dataType:"text",
	success: function(obj){
		// 处理服务器返回的数据
		// obj就是服务器端返回的数据。如果返回的是json字符串,会自动转换成javascript对象。 
		// 前提是必须要设置dataType为json格式
    },
	error: function(){//用于处理服务器出错时的函数
	}      
});

(2)load方法

  • 1)该方法会向服务器发送异步请求,并且将服务器返回的数据直接添加到符合要求的节点之上。

  • 2)用法

    $obj.load(url,[data]);

    • url : 是请求地址。
    • data: 是请求参数。有两种写法(请求字符串和对象的形式)
    • (比如“adminCode=king&age=22”或{“adminCode”:“king”,“age”:22})

:$obj,是jQuery对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不愿放下技术的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值