zoukankan      html  css  js  c++  java
  • Spring/Spring MVC/MyBatis整合详解

    本文引用自:《Java EE企业级应用开发教程》

    由于Spring MVC只是Spring框架中的一个模块,所以Spring MVC与Spring之间不存在整合的问题,只需要引入相应Jar包就可以直接使用。因此,Spring/Spring MVC/MyBatis的整合,只涉及Spring与MyBatis的整合,以及Spring MVC与MyBatis的整合。

    首先,定义三大框架的版本:

    • Spring 5.2.3(注意:Spring框架的所有Jar包版本必须保持一致,否则会发生不可预料的错误!
    • Spring MVC 5.2.3
    • MyBatis 3.5.2

    其它附件的版本:

    • log4j  1.2.17
    • mysql  5.1.49
    • mybatis-spring  1.3.1

    这些Jar包的引入地址,可以参考:https://mvnrepository.com/

    一、准备所需要的Jar包

    1.1 Spring核心包

        commons-logging-1.2.jar        Spring需要用它记录日志(第三方包)
        spring-beans-5.2.3.RELEASE.jar    SpringIoC(依赖注入)的基础实现
        spring-context-5.2.3.RELEASE.jar    Spring提供在基础IoC功能上的扩展服务,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等
        spring-core-5.2.3.RELEASE.jar        Spring核心包
        spring-expression-5.2.3.RELEASE.jar    Spring表达式语言
        spring-aop-5.2.3.RELEASE.jar        Spring的面向切面编程,提供AOP(面向切面编程)实现

    1.2 Spring的JDBC相关包

        spring-jdbc-5.2.3.RELEASE.jar        JDBC驱动包
        spring-tx-5.2.3.RELEASE.jar        事务管理
        commons-dbcp2-2.1.1.jar        数据源所需
        commons-pool2-2.4.2.jar        数据源所需

    1.3 Spring的aspectj相关包(可选 ,本节用不到)

        aopalliance-1.0.jar        AspectJ包(三个)
        aspectjrt-1.9.5.jar
        aspectjweaver-1.8.7.jar

    1.4 Spring MVC相关包

        spring-webmvc-5.2.3.RELEASE.jar
        spring-web-5.2.3.RELEASE.jar

    1.5 MyBatis相关包

        mybatis-3.5.2.jar
        ant-1.10.3.jar
        ant-launcher-1.10.3.jar
        asm-7.0.jar
        cglib-3.2.10.jar
        commons-logging-1.2.jar
        javassist-3.24.1-GA.jar
        log4j-1.2.17.jar
        log4j-api-2.11.2.jar
        log4j-core-2.11.2.jar
        ognl-3.2.10.jar
        slf4j-api-1.7.26.jar
        slf4j-log4j12-1.7.26.jar

    1.6 其它包

    mysql-connector-java-5.1.49-bin.jar    MySQL数据库驱动
    mybatis-spring-1.3.1.jar        Spring与MyBatic整合包

    1.7 pom.xml文件参考

    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>ssm</groupId>
        <artifactId>ssm</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <name>ssm</name>
        <description />
        <properties>
            <webVersion>4.0</webVersion>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-api</artifactId>
                <version>8.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.glassfish.web</groupId>
                <artifactId>javax.servlet.jsp.jstl</artifactId>
                <version>1.2.4</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/log4j/log4j -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <!-- spring-context这个包囊括:spring-aop/spring-beans/spring-core/spring-expression -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.3.RELEASE</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>5.2.17.RELEASE</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.8.7</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.7</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
            <dependency>
                <groupId>aopalliance</groupId>
                <artifactId>aopalliance</artifactId>
                <version>1.0</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>5.2.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.17.RELEASE</version>
            </dependency>        
            
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
            <!-- spring-jdbc这个包囊括: spring-beans/spring-core/spring-tx -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.2.3.RELEASE</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <!-- mybatis这个包囊括: cglib (optional)/commons-logging (optional)
            /log4j (optional)/ognl (optional)/log4j-core (optional)
            /javassist (optional)/slf4j-api (optional)/slf4j-log4j12 (optional) -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.2</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.20</version>
                <scope>provided</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <!-- junit这个包囊括: hamcrest-core -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-dbcp2</artifactId>
                <version>2.9.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>2.11.1</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.49</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.12.5</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.12.5</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>2.12.5</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
            <dependency>
                <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
                <version>1.3.3</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.6</version>
            </dependency>
            
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.3.3</version>
            </dependency>
    
            <dependency>
                <groupId>oraclejdbc</groupId>
                <artifactId>oraclejdbc</artifactId>
                <version>4.0</version>
                <scope>system</scope>
                <systemPath>${project.basedir}/lib/ojdbc6.jar</systemPath>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.3</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
            </plugins>
            <resources>
                <resource>
                    <directory>lib</directory>
                    <targetPath>/WEB-INF/lib/</targetPath>
                    <includes>
                        <include>**/*.jar</include>
                    </includes>
                </resource>
            </resources>
        </build>
    </project>
    View Code

    注意:本配置文件额外引用lombok、junit、jackson、fileupload、oraclejdbc(本地引用)等相关包;不需要的,请自行删除。

    二、创建配置文件

    2.1 创建db.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/xuejia?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
    jdbc.username=root
    jdbc.password=admin
    jdbc.maxTotal=30
    jdbc.maxIdle=10
    jdbc.initialSize=5

    2.2 创建log4j.properties

    # Global logging configuration
    log4j.rootLogger=ERROR, stdout
    # MyBatis logging configuration...
    log4j.logger.com.itheima=DEBUG
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

    2.3 创建applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
        <!-- 读取db.properties -->
        <context:property-placeholder
            location="classpath:db.properties" />
        <!-- 配置数据源 -->
        <bean id="dataSource"
            class="org.apache.commons.dbcp2.BasicDataSource">
            <!--数据库驱动 -->
            <property name="driverClassName" value="${jdbc.driver}" />
            <!--连接数据库的url -->
            <property name="url" value="${jdbc.url}" />
            <!--连接数据库的用户名 -->
            <property name="username" value="${jdbc.username}" />
            <!--连接数据库的密码 -->
            <property name="password" value="${jdbc.password}" />
            <!--最大连接数 -->
            <property name="maxTotal" value="${jdbc.maxTotal}" />
            <!--最大空闲连接 -->
            <property name="maxIdle" value="${jdbc.maxIdle}" />
            <!--初始化连接数 -->
            <property name="initialSize" value="${jdbc.initialSize}" />
        </bean>
        <!-- 事务管理器,依赖于数据源 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
        <!-- 开启事务注解 -->
        <tx:annotation-driven
            transaction-manager="transactionManager" />
        <!-- 配置MyBatis工厂SqlSessionFactory -->
        <bean id="sqlSessionFactory"
            class="org.mybatis.spring.SqlSessionFactoryBean">
            <!--注入数据源 -->
            <property name="dataSource" ref="dataSource" />
            <!--指定核MyBatis心配置文件位置 -->
            <property name="configLocation"
                value="classpath:mybatis-config.xml" />
        </bean>
        <!-- 配置mapper扫描器 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.itheima.dao" />
        </bean>
        <!-- 扫描Service -->
        <context:component-scan
            base-package="com.itheima.service" />
    </beans>

    该文件中,首先根据db.properties的信息配置数据源;然后配置事务管理器并开启事务注解;接下来配置整合MyBatis框架的MyBatis工厂信息,最后定义mapper扫描器来扫描DAO层以及扫描Service层的配置。

    2.4 创建mybatis-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">
    <configuration>
        <!-- 别名定义 -->
        <typeAliases>
            <package name="com.itheima.po" />
        </typeAliases>
    </configuration>

    由于在Spring中已经配置数据源信息以及mapper接口文件扫描器,所以在MyBatis的配置文件中只需要根据POJO类路径进行别名配置即可。

    2.5 创建springmvc-config.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
      http://www.springframework.org/schema/mvc 
      http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-4.3.xsd">
        <!-- 配置包扫描器,扫描@Controller注解的类 -->
        <context:component-scan base-package="com.itheima.controller" />
        <!-- 加载注解驱动 -->
        <mvc:annotation-driven />
        <!-- 配置视图解析器 -->
        <bean class=
        "org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean>
    </beans>

    该文件中,主要配置用于扫描@Controller注解的包扫描器、注解驱动器以及视图解析器。

    2.6 创建web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
          http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
          id="WebApp_ID" version="3.1">
          <!-- 配置加载Spring文件的监听器-->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
        <listener>
            <listener-class>
                 org.springframework.web.context.ContextLoaderListener
            </listener-class>
        </listener>
        <!-- 编码过滤器 -->
        <filter>
            <filter-name>encoding</filter-name>
            <filter-class>
                 org.springframework.web.filter.CharacterEncodingFilter
            </filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <url-pattern>*.action</url-pattern>
        </filter-mapping>
        <!-- 配置Spring MVC前端核心控制器 -->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>
                 org.springframework.web.servlet.DispatcherServlet
            </servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-config.xml</param-value>
            </init-param>
            <!-- 配置服务器启动后立即加载Spring MVC配置文件 -->
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <!--/:拦截所有请求(除了jsp)-->
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>

    该文件中,配置Spring的文件监听器、编码过滤器以及Spring MVC的前端控制器等信息。

    三、创建各种程序

    3.1 创建PO类 

    package com.itheima.po;
    /**
     * 客户持久化类
     */
    public class Customer {
        private Integer id;       // 主键id
        private String username; // 客户名称
        private String jobs;      // 职业
        private String phone;     // 电话
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getJobs() {
            return jobs;
        }
        public void setJobs(String jobs) {
            this.jobs = jobs;
        }
        public String getPhone() {
            return phone;
        }
        public void setPhone(String phone) {
            this.phone = phone;
        }
    }

    此实体类对应的数据库SQL语句为:

    CREATE TABLE `t_customer` (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `USERNAME` varchar(45) NOT NULL,
      `JOBS` varchar(45) DEFAULT NULL,
      `PHONE` varchar(45) DEFAULT NULL,
      PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

    3.2 创建Dao类,及其对应的映射文件(同一个package)

    CustomerDao.java

    package com.itheima.dao;
    import com.itheima.po.Customer;
    /**
     * Customer接口文件
     */
    public interface CustomerDao {
        /**
         * 根据id查询客户信息
         */
        public Customer findCustomerById(Integer id);
    }

    CustomerDao.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">
    <mapper namespace="com.itheima.dao.CustomerDao">
        <!--根据id查询客户信息 -->
        <select id="findCustomerById" parameterType="Integer"
                                           resultType="Customer">
            select * from t_customer where id = #{id}
        </select>
    </mapper>

    说明:配置文件applicationContext.xml,已经配置mapper扫描器扫描com.itheima.dao包下的所有接口及映射文件,所以此处完成DAO层接口及映射文件开发后,工作即告一段落。

    3.3 创建service接口类,及其实现类

    CustomerService.java

    package com.itheima.service;
    import com.itheima.po.Customer;
    public interface CustomerService {
        public Customer findCustomerById(Integer id);
    }

    CustomerServiceImpl.java

    package com.itheima.service.impl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import com.itheima.dao.CustomerDao;
    import com.itheima.po.Customer;
    import com.itheima.service.CustomerService;
    @Service
    @Transactional
    public class CustomerServiceImpl implements CustomerService {
        //注解注入CustomerDao
        @Autowired
        private CustomerDao customerDao;
        //查询客户
        public Customer findCustomerById(Integer id) {
            return this.customerDao.findCustomerById(id);
        }
    }

    该文件中,使用@Service注解来标识业务层的实现类,使用@Transactional注解来标识类中所有方法都纳入Spring的事务管理,并使用@Autowired注解将CustomerDao对象注入到本类中,然后在本类的查询方法中调用CustomerDao对象的查询客户方法。

    注:@Transactional注解主要针对数据的增加、修改、删除,此处仅为说明使用。

    3.4 创建控制器类

    package com.itheima.controller;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import com.itheima.po.Customer;
    import com.itheima.service.CustomerService;
    @Controller
    public class CustomerController {
        @Autowired
        private CustomerService customerService;
        /**
         * 根据id查询客户详情
         */
        @RequestMapping("/findCustomerById")
        public String findCustomerById(Integer id,Model model) {
            Customer customer = customerService.findCustomerById(id);
            model.addAttribute("customer", customer);
            //返回客户信息展示页面
            return "customer";
        }
    }

    该文件中,使用@Controller注解来标识控制器类,然后通过@Autowired注解将CustomerService接口对象注入到本类中,最后编写一个根据id查询客户的方法findCustomerById,并将结果返回到视图名为customer的JSP页面中。

    3.5 创建JSP页面customer.jsp,位于:WEB-INFjsp

    <%@ 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>客户信息</title>
    </head>
    <body>
        <table border=1>
            <tr>
                <td>编号</td>
                <td>名称</td>
                <td>职业</td>
                <td>电话</td>
            </tr>
            <tr>
                <td>${customer.id}</td>
                <td>${customer.username}</td>
                <td>${customer.jobs}</td>
                <td>${customer.phone}</td>
            </tr>
        </table>
    </body>
    </html>

    四、测试,打开页面:http://localhost:8080/ssm/findCustomerById?id=1

    结果如上图所示。

  • 相关阅读:
    react父子组件之间传值
    MVC、MVP、MVVM模式的概念与区别
    exports、module.exports 和 export、export default
    进程与线程以及它们的区别
    axios详解
    箭头函数详解
    ES6扩展运算符...
    vue子组件数据跟着父组件改变
    JS实现千分位
    在.NET Core使用TimeZone将客户端时间转服务器本地时间但编译提示已过期
  • 原文地址:https://www.cnblogs.com/nayitian/p/15379765.html
Copyright © 2011-2022 走看看