MyBatis

一、MyBatis

1、MyBatis简介

  • MyBatis本是apache的一个开源项目Batis,2010年这个项目由apache software foundation迁移到了Google Code,并且改名为MyBatis。2013年11月迁徙到Github。
  • MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建conneion、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
  • MyBatis通过xml或注解方式将要执行的各种statement(statement、preparedStatemnt)配置起来,并通过Java对象和statement中的SQL进行映射,生成最终执行的sql语句,最后由MyBatis框架执行SQL,并将结果映射成Java对象并返回。
  • 总之,MyBatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决了JDBC将结果集封装为Java对象的麻烦。
  • MyBatis架构图:  
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OlzNgvBz-1626745304940)(MyBatis_files/1.jpg)]

2、MyBatis快读入门

2.1.准备数据(yonghedb)

2.2 创建项目、导入jar包,创建测试类

  • 创建一个Maven的java项目

  • 在项目的pom文件中导入Junit、MyBatis、MySQL、Log4j的jar包

      	<dependency>
      		<groupId>junit</groupId>
      		<artifactId>junit</artifactId>
      		<version>4.9</version>
      	</dependency>
      	<dependency>
      		<groupId>mysql</groupId>
      		<artifactId>mysql-connector-java</artifactId>
      		<version>8.0.11</version>
      	</dependency>
      	<dependency>
      		<groupId>org.mybatis</groupId>
      		<artifactId>mybatis</artifactId>
      		<version>3.2.8</version>
      	</dependency>
      	<dependency>
      		<groupId>org.slf4j</groupId>
      		<artifactId>slf4j-log4j12</artifactId>
      		<version>1.6.4</version>
      	</dependency>
    
  • 创建MyBatisTest测试类
    + 读取MyBatis的核心配置文件(mybati-config.xml)
    + 获取SqlSessionFactory工厂对象
    + 通过工厂对象获取SqlSession对象(类似于JDBC中的Connection连接对象)
    + 通过namespace+id定位SQL并执行SQL语句,返回处理后的结果

  • 创建一个类,查询表中所有数据,并将所有数据封装到对象中,最后将对象封装到集合中
    + 为了封装员工信息而提供的Emp类,城市为实体类(简单Java对象,POJO:Plain Ordinary Java Object)
    + 如果需要查询所有的员工信息,员工信息查询出来后需要封装到Java对象中
    + pojo(plain old/ordinary java object):简单Java对象
    - 如果一个类只是用来封装数据的(比如为了封装员工信息而提供的Emp类)
    - 这样的类我们称之为POJO类,通过该类生成的对象称之为POJO对象
    + 在Emp中提供四个变量,分别用来封装emp表中的撕裂数据
    + 再提供4个变量的get/set()
    + 关于Emp实体类中的id和salary用Integer和Double类型
    - 因为int和double都属于基本类型,基本类型的默认值(0,0.0,空字符,false)
    - 但如果使用包装类型,包装类型的默认值是null,可以避免一些误会产生
    + 重写toString():为了在打印Emp对象时,输出的时对象中所储存的值,而不是地址值
    + 在编写实体类(POJO类)时,建议添加无参构造和含参构造

    • 提供mabatis-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>
        	<!-- 配置开发环境 -->
        	<environments default="dev">
        		<environment id="dev">
        			<!-- 配置事务管理方式
        			 JDBC:将事务交给JDBC管理(mybatis会自动开启事务,但需要手动提交)
        			 MANAGED:自己手动管理事务
        			 -->
        			<transactionManager type="JDBC"></transactionManager>
        			<!-- 是否配置连接池信息,type取值:
        				JNDI:已过时
        				UNPOOLED:不使用连接池
        				POOLED:使用连接池(可以减少连接池创建次数,提高执行效率)
        			 -->
        			<dataSource type="POOLED">
        				<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        				<property name="url" value="jdbc:mysql:///yonghedb?characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai&amp;useSSL=false"/>
        				<property name="username" value="root"/>
        				<property name="password" value="root"/>
        			</dataSource>
        		</environment>
        	</environments>
        	<!-- 导入XxxMapper.xml文件
        		resource属性会直接到类目录下去找指定的文件
        	 -->
        	<mappers>
        		<mapper resource="EmpMapper.xml"/>
        	</mappers>
        </configuration>
      
    • 提供EmpMapper.xml文件,在文件中可以配置我们想执行的任何SQL语句(增、删、改、查等)

        <?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:用于标识当前这个mapper文件
        在mybatis程序中需要通过这个名字来定位当前这个mapper文件
        通过namespace值+id值可以定位要执行的是哪一条SQL语句-->
        <mapper namespace="EmpMapper">
        	<!-- 可以通过select,insert,update,delete存放要执行的SQL语句 -->
        	<!-- id属性要求当前文件中的id值必须是独一无二的(不能重复)
        		resultType属性:指定查询的结果要存放在哪个类型的对象中-->
        	<select id="findAll" resultType="cn.edu.pojo.Emp">
        		select * from emp
        	</select>
        </mapper>
      
  1. MyBatis的增、删、改操作
    • 新增员工信息:赵云 保安 6000

      • .xml文件:

          <insert id="insert">
          	insert into emp value(null,"赵云","保安",6000)
          </insert>
        
      • .java文件:

          @Test
          public void testInsert(){
          	int insert = session.insert("EmpMapper.insert");
          	System.out.println("影响行数为:" + insert);
          }
        
    • 修改员工信息:赵云 保镖 20000

      • .xml文件:

          <update id="update">
          	update emp set job="保镖",salary=20000 where name="赵云"
          </update>
        
      • .java文件:

          @Test
          public void testUpdate(){
          	int update = session.update("EmpMapper.update");
          	System.out.println("影响行数为:" + update);
          }
        
    • 删除员工信息:删除名称为‘赵云’的员工信息

      • .xml文件:

          <delete id="delete">
          	delete from emp where name="赵云"
          </delete>
        
      • .java文件:

          @Test
          public void testDelete(){
          	int delete = session.delete("EmpMapper.delete");
          	System.out.println("影响行数为:" + delete);
          }
        

MyBatis程序中常见的问题

  1. Emp类中添加了有参构造函数,但没有添加无参构造函数。
    • MyBatis底层会基于反射创建Emp类的对象实例,创建时使用的就是Emp的无参构造函数,如果没有无参构造函数,就会报错。
  2. 执行SQL语句时,namespace或id写错了,就找不到要执行的SQL,语句就会报错。
    • 每条SQL语句都会有namespace+id,而这些信息是存放在一个map中

        EmpMapper.findAll(key) : select * from emo(value);
      
  3. 连接数据库的基本信息书写错误,会导致连接不上数据库。
    • 未知的数据源(连接池)属性
  4. 如果mapper文件中标签的id值重复了,将会报错。

MyBatis占位符操作

  1. Mybatis中有两种占位符,分别是:#{}, ${}

  2. 启用log4j日志框架:专门为Java语言提供的一套日志框架,可以通过log4j打印程序中执行的日志信息

    • 由于MyBatis默认已经整合了log4j,使用log4j只需要完成以下两步操作:

      • 添加log4j的jar包

      • 添加log4j的配置文件如下:(文件名必须是log4j.properties,文件必须要放在类目录下)

          # Global logging configuration
          log4j.rootLogger=DEBUG, stdout
          # (DEBUG表示输出级别,stdout表示输出到控制台)
          # Console output...
          log4j.appender.stdout=org.apache.log4j.ConsoleAppender
          log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
          log4j.appender.stdout.layout.ConversionPattern=%5p [%t] %d{yyyy-MM-dd hh:mm:ss} - %m%n
        

      或者:

        	log4j.rootLogger=DEBUG, Console, LOGFILE
        	log4j.appender.console=org.apache.log4j.ConsoleAppender
        	log4j.appender.console.layout=org.apache.log4j.PatternLayout
        	log4j.appender.console.layout.ConversionPattern=%5p [%t] %d{yyyy-MM-dd hh:mm:ss} - %m%n
      
  3. #{}占位符:

    • 其实就是JDBC中的问号(?)占位符,在MyBatis底层会将#{}占位符翻译成问号(?)占位符。

    • 如果在SQL语句中占位符只有一个#{}占位符,{}中名称没有要求,但不能是空的,参数可以直接传递,不用封装。

    • 如果在SQL语句中的#{}占位符不止一个,参数值需要通过Map或者POJO对象进行封装。

    • 如果通过Map集合来封装SQL参数值,#{}占位符中的名称要和Map中的key一致。

      • 因为在MyBatis底层是通过#{}占位符中的名称,作为key,到map中获取对应的value。
    • 如果通过POJO对象来封装SQL参数值,#{}占位符中的名称要在POJO对象中有对应的getXxx(),或者有对应的变量

      • 例如:#{job}占位符中的名称为job,就意味着在Emp表中要有getJob()或者有job变量。
      • 如果两者都有,会优先通过getXxx()来获取POJO对象中存储的属性值,如果没有getXxx(),会通过暴力反射直接获取Emp中job变量的值。
    • 总结:在MyBatis框架中,大部分情况都是用#{}占位符,#{}其实就是JDBC中的(?)占位符,是为SQL语句中的【参数值】进行占位。

    • 例如:

        查询:select * from emp where job=参数值 and salary>参数值
        新增:insert into emo value(null,参数值,参数值,参数值)
        修改:uodate emp set 列=参数值,列=参数值, ... where 列=参数值...
        删除:delete from emp where 列=参数值...
      
    • .xml文件:

        <insert id="insert2">
        insert into emp value(null,#{name},#{job},#{salary})
        </insert>
      
    • .java文件:

        public void insert2(String name, String job, Double salary){
        	//方式一
        	Map map = new HashMap();
        	map.put("name","马云");
        	map.put("job","教师");
        	map.put("salary",800);
        	session.insert("EmpMapper.insert2",map);
        	//方式二
        	Emp emp = new Emp(null,"马云","教授",10000);
        	session.update("EmpMapper.update2",emp);
        	//方式三
            Emp emp = new Emp();
            emp.setName("马云");
            emp.setJob("大学教授");
            emp.setSalary(8000);
        	session.update("EmpMapper.update2",emp);
        }
      
  4. ${}占位符:

    • 是为SQL语句中某个SQL片段进行占位,将参数传递过来时,是直接将参数拼接在${}占位符所在的位置,因为是直接拼接,所以可能会引发SQL注入攻击,因此不推荐大量使用。

    • 如果SQL语句中只有一个#{}占位符,参数不用封装,直接传递即可。

    • 但如果SQL语句中哪怕只有一个${}占位符,参数也必须先封装到Map或者POJO对象中,再把Map或者POJO对象传递过去。

    • MyBatis底层在执行SQL语句时,使用的就是PreparedStatement对象来传输SQL语句。

    • .xml文件

        <!-- 查询emp表中的所有员工信息,动态查询所有的列 -->
        <select id="findAll2" resultType="cn.edu.pojo.Emp">
        	select ${colStr} from emp
        </select>
      
    • .java文件

        @Test
        public void testFindAll(){
        	Map map = new HashMap();
        	map.put("colStr","id,name,job");
        	List<Emp> list = session.selectList("EmpMapper.findAll2",map);
        	for (Emp e:list
        		 ) {
        		System.out.println(e);
        	}
        }
      
  5. MyBatis的动态SQL

    • if标签、where标签、foreach标签。

    • 动态SQL值得是:SQL语句可以根据参数值的不同来生成不同的SQL语句。

    • 如果在员工列表页面中可以根据员工薪资区间查询员工信息。

      • 如果不传最低薪资和最高薪资,默认查询所有员工信息

          select * from emp;
        
      • 如果传了最低薪资,但没有传最高薪资

         select * from emp where salary > 最低薪资
        
      • 如果传了最高薪资,但没有传最低薪资

          select * from emp where salary < 最高薪资
        
      • 如果既传了最低薪资,也传了最高薪资

          select * from emp where salary > 最低薪资 and salary < 最高薪资
        
    • if标签:如果test属性中的布尔表达式为true,那if标签中的SQL片段就会参与整个SQL语句的执行;反之,如果test属性中的布尔表达式为false,那么if标签中的内容将不会执行。

        <if test="布尔表达式">
        	SQL片段
        </if>
      
      • .xml文件:

          <select id="findBySal" resultType="cn.edu.pojo.Emp">
          	select * from emp
          	where 1=1
          		<if test="minSal != null">
          			and salary > #{minSal}
          		</if>
          		<if test="maxSal != null">
          			and salary &lt; #{maxSal}
          		</if>
          </select>
        
      • .java文件:

          @Test
          public void testFindBySal(){
          	Map map = new HashMap();
          	map.put("minSal",3000);
          	map.put("maxSal",4500);
          	List<Emp> list = session.selectList("EmpMapper.findBySal",map);
          	for (Emp e:list
          		 ) {
          		System.out.println(e);
          	}
          }
        
    • where标签:将if标签以及其中的条件都包裹在where标签内部,字要有任何一个条件成立,where标签就会自动生成where关键字,并且如果条件前面有多余的连接词(比如or、and),where标签会将多余的连接词去掉。

      • .xml文件:

          <select id="findBySal2" resultType="cn.edu.pojo.Emp">
          	select * from emp
          	<where>
          		<if test="minSal != null">
          			and salary > #{minSal}
          		</if>
          		<if test="maxSal != null">
          			and salary &lt; #{maxSal}
          		</if>
          	</where>
          </select>
        
      • .java文件:

          @Test
          public void testFindBySal2(){
          	Map map = new HashMap();
          	map.put("minSal",3000);
          	map.put("maxSal",4500);
          	List<Emp> list = session.selectList("EmpMapper.findBySal2",map);
          	for (Emp e:list
          	) {
          		System.out.println(e);
          	}
          }
        
    • foreach标签:foreach标签可以对传过来的数组或集合进行遍历,生成我们所需要的SQL片段

      • collection属性:如果传过来的只有一个数组(或List集合)collection指定的值则为array(或list);如果传过来的是一个Map集合,将数组或集合作为value封装到map中,collection属性的值就是数组或集合在Map中的key;
      • open属性:指定所生成SQL片段的起始符号,通常是左圆括号 (
      • close属性:指定所生成SQL片段的结束符号,通常是右圆括号 )
      • item属性:指定占位符中的名称
      • separator属性:指定占位符中间的分隔符,通常是逗号 ,
      • 案例1:根据员工的id批量删除员工信息 id数组 int[] ids={1,3,5,7}
        • .xml文件:

            <delete id="deleteByIds">
            	delete from emp where id in
            	<foreach collection="array" open="(" item="id" separator="," close=")">
            		#{id}
            	</foreach>
            </delete>
          
        • .java文件:

            @Test
            public void testDeleteById(){
            	int[] ids = {1,3,5,7};
            	session.delete("EmpMapper.deleteByIds",ids);
            }
          
      • 案例2:根据员工的id批量更新员工信息 id数组 int[] ids={2,4,6,8} 薪资+1000
        • .xml文件:

            <update id="updateByIds">
            	update emp set salary=salary+#{money} where id in
            	<foreach collection="array" open="(" item="id" separator="," close=")">
            		#{id}
            	</foreach>
            </update>
          
        • .java文件:

            @Test
            public void testUpdateById(){
            	int[] ids = {2,4,6,8};
            	Double money = 1000.0;
            	Map map = new HashMap();
            	map.put("ids",ids);
            	map.put("money",money);
            	session.update("EmpMapper.updateByIds",map);
            }
          
  6. MyBatis的Mapper接口开发

    • Mapper接口开发要满足以下4个规则:

      • 写一个接口,要求接口的全类名(包名.接口名)要等与XxxMapper文件的namespace值。
        即namespace = 接口的全类名
      • Mapper文件中要执行的SQL语句,在接口中得有对应的接口方法,并且SQL语句的id值要等于接口的这个方法名。
        即SQL标签的id值 = 方法名
      • 如果是查询SQL,resultType指定的类型要和接口方法的返回值类型对应。
        1. 如果接口返回的是某一个实体对象(Emp),此时resultType指定的是该对象的类型(cn.edu.pojo.Emp)
        2. 如果接口返回的是集合(List),此时resultType指定的是集合中的泛型(cn.edu.pojo.Emp)
      • (可以忽略)SQL标签上的参数类型(paramterType属性)要和接口方法的参数类型保持一致。
    • 查询所有员工的信息

        public List<Emp> findAll(){
        	/**
        	 * 获取当前这个类的父接口的全类名(=namespace)
        	 * 通过当前类的对象(this)获取当前类的字节码对象,再通过当前类的字节码对象获取当前类实现的所有
        	 * 再通过接口获取的全类名(包名.接口名)
        	 */
        	String name = this.getClass().getInterfaces()[0].getName();
        	/**
        	 * 获取当前方法的名字(=SQL标签的id值)
        	 * 获取存放的方法调用栈信息(也就是所有方法的调用信息),返回的是一个数组,getStackTrace()会在栈顶(也就是数组的第一个元素),调用这个方法的是findAll方法,这个方法在数组的第二个位置,也就是数组的第二个元素。
        	 */
        	StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        	/**
        	 * 通过数组中的第二个元素(其中方法所属类的全类名,方法名,当前方法所属文件的名字呢,也就是方法调用的行数)获取当前调用的方法的名字。
        	 */
        	String id = stackTrace[1].getMethodName();
        	List<Emp> list = session.selectList(name + "." + id);
        	return list;
        }
      
  7. MyBatis的注解开发

    • 使用xml方式和注解开发的区别

      • 使用xml方式配置SQL语句,写起来相比注解要麻烦一些,而注解方式不用谢配置文件,直接在接口的方法上面添加一个注解(@Select、@Insert、@Update、@Delete…),将SQL语句直接写在注解的括号里面即可。
      • 使用注解方式配置SQL语句又回到将SQL语句写在Java程序中,如果将来SQL语句一旦发生变化,就意味着要修改Java源文件(.java),改完之后要重新编译整个项目,再打包、部署到服务器上,相比来说较为麻烦。
    • 由于使用注解开发,要将SQL语句配置在注解中,因此EmpMapper.xml文件也就不需要了,在mybatis-config.xml文件中也就不需要引入EmpMapper.xml文件了。

      • mybatis-config.xml文件:

          <mappers>
          	<!--<mapper resource="EmpMapper.xml"/>-->
          	<!--可以将每一个XxxMapper接口通过一个mapper标签的class属性引入-->
          	<!--如果有多个XxxMapper接口,添加多个mapper标签引入即可-->							<!--<mapper class="cn.edu.dao.EmpMapper"/>-->
          	<!--或者是直接引入XxxMapper接口所在的包,这样MyBatis会直接扫描这个包下的所有接口中的每个方法,那么这些方法上所配置的SQL语句也会被读取到MyBatis中->
          	<package name="cn.edu.dao"/>
          </mappers>
        
    • 在mybatis-config.xml文件中引入SQL语句所在的Mapper接口(因为SQL语句存放在接口中)。

      • EmpMapper接口:

          //接口的全类名:cn.edu.dao.EmpMapper
          public interface EmpMapper {
        
          	//查询emp表中所有信息
          	@Select("select * from emp")
          	public List<Emp> findAll();
        
          	//新增增员工信息(无占位符)
          	@Insert("insert into emp value(null,'赵云','保安',6000)")
          	public void insert();
        
          	//新增增员工信息(带占位符)
          	@Insert("insert into emp value(null,#{name},#{job},#{salary})")
          	public void insert2(Map map);
        
          	//修改员工信息
          	@Update("update emp set job=#{job},salary=#{salary} where name=#{name}")
          	public void update2(Emp emp);
        
          	//删除员工信息
          	@Delete("delete from emp where id=#{id}")
          	public void delete2(Integer integer);
        
          }
        
    • 测试(由于这里只是将SQL语句从XxxMapper.xml文件中移动到了XxxMapper接口中,所以测试代码直接使用之前即可)。

补充内容:单元测试框架(Junit)

  1. 这个框架可以在不提供main函数,并且不创建对象的情况下,直接运行一个非静态的方法。
  2. @Test注解可以标记一个非静态的方法,在不添加main函数并且不创建对象的情况下直接运行这个方法,但被@Test标记的方法必须符合以下要求:
    • 方法必须是公共的(public),不能是私有的(private)

    • 方法必须是非静态的(no static)

    • 方法必须是无返回值的(no return)

    • 方法必须是无参的(no param)

    • 如果违反以上任何一个规则,就会报如下异常:

        java.lang.Exception: No tests found matching [{ExactMatcher:...}]
      

tomcat服务器

服务器相关概念

  • 服务器:分为软件服务器和硬件服务器。
  • 硬盘服务器:运行在互联网上的、具有静态IP地址的一台计算机(通常配置比较高)。
  • 软件服务器:运行在互联网上的计算机程序(软件),将服务器软件安装在硬件服务器上,才可以对外提供服务。
  • 服务器分为很多种:数据库服务器(MySQL,Oracle,SQL Server等),Web服务器(tomcat,jetty,jboss等),邮件服务器,FTP服务器…

Web服务器

  • Web服务器:运行在互联网上的计算机程序,专门用于接收客户端的请求,根据请求进行处理,最后给出回应。
  • 比如打开浏览器,输入 (https://www.baidu.com) 回车,其实访问的就是百度的服务器,此时会向百度服务器发送一个请求,请求百度的首页,百度服务器会接收并处理这个请求,根据请求给出回应(将百度首页相应给客户端浏览器)。
  • tomcat就是一个Web服务器,特点:小巧灵活、简单易学、学习成本非常低。

Tomcat服务器下载、安装、启动、配置

  1. 下载tomcat服务器
    • 下载地址:(http://tomcat.apache.org)
    • tomcat分为很多版本,由Windows版本(解压版和安装版)、Linux版本
    • 推荐使用解压版(需要的时候解压一份,不需要直接删除解压目录即可)
  2. 安装tomcat
    • 安装:解压之后即可使用(安装的路径中最好不要包含中文和空格)
    • 在启动tomcat之前,需要配置(检查)一个JAVA_HOME环境变量,该变量需要指向JDK的安装目录
    • 变量名:JAVA_HOME
    • 变量值:C:\Program Files\Java\jdk1.8.0_221
    • 由于tomcat服务器是由Java语言开发的,所以运行tomcat需要JDK的支持
    • JAVA_HOME这个变量就是在告诉tomcat服务器,需要使用哪一个位置上的JDK
  3. 启动tomcat
    • 启动tomcat:通过【tomcat安装目录】/bin/startup.bat文件可以启动tomcat服务器

    • 关闭tomcat:通过【tomcat安装目录】/bin/shutdown.bat文件可以关闭tomcat服务器,或者之间点❌关闭

    • 启动tomcat之后,可以打开浏览器,访问

        http://localhost:8080
        http://127.0.0.1.8080
      
    • 如果可以访问到tomcat服务器主页,就说明tomcat安装并且启动成功

  4. 修改tomcat服务器默认端口
    • 如果不修改tomcat端口,每次在访问tomcat服务器时,都需要在主机名/IP地址的后面加上8080

    • 如果向在访问时,在主机名或IP地址后面省略端口,可以将端口修改为80(这个端口特殊,可以省略不写)

    • 修改tomcat端口的方法是:

      • 找到并打开【tomcat安装目录】/conf/server.xml文件
      • 将其中的Connector标签上的port属性值改为80,保存文件,并重启服务器即可生效。
    • 重启服务器后,就可以通过如下地址访问tomcat服务器:

        http://localhost:80
        http://localhost
        http://127.0.0.1.80
        http://127.0.0.1
      

tomcat服务器的目录结构

  • bin:存放批处理文件的目录(startup.bat、shutdown.bat文件)
  • conf:存放tomcat配置文件的目录(server.xml时tomcat核心配置文件)
  • lib:存放tomcat服务器在运行时所依赖的jar包的目录
  • logs:存放tomcat服务器在运行时产生的日志文件的目录
  • temp:存放tomcat服务器在运行时产生的临时文件的目录
  • work:存放tomcat服务器再运行其兼产生的一些工作文件(JSP在第一次被访问后的Servlet文件、session对象序列化后产生的文件等都会放在这个目录下)
  • webapps:是Web应用的存放目录,放在这个目录中的Web应用程序,可以通过localhost虚拟主机进行访问。
    • webapps目录是localhost主机默认存放Web应用的目录
    • 把Web应用放在webapps目录下,就相当于发布到了localhost主机中

Web应用和虚拟主机

  1. Web应用:
    • Web应用其实就是一个目录,其中可以包含很多资源文件(html/css/js/图片/jsp/servlet…等)
    • 虚拟主机中不能直接管理Web资源文件(html/css/js/图片/jsp…等)
    • 需要将Web文字源文件组织成一个Web应用(目录),将Web应用发布到虚拟主机中运行才可以被虚拟主机所管理。
  2. 虚拟主机:
    • 就是在tomcat服务器中配置的一个站点,在访问时就好像在访问一台真实独立的主机一样。
    • 我们将这个站点称之为是:运行在tomcat服务器中的一台虚拟主机,tomcat服务器中可以配置多个站点,每一个站点都是一台虚拟主机。
    • 下面是tomcat默认提供的localhost主机配置:
      • <Host name=“localhost” appBase=“webapps”…>< /Host>
      1. 在服务器上安装一个tomcat服务器软件。
      2. 在tomcat服务器软件内部可以配置多个站点(虚拟主机),其中tomcat默认自带了一个localhost虚拟主机。
      3. localhost虚拟机主机管理Web应用的目录–webapps,发布到webapps目录下的web应用,也就都发布到了localhost主机中。
      4. 往webapps中发布了一个 jt web 应用,其中包含一些Web资源文件。
      5. web资源文件可以是(html/css/js/图片/servlet/jsp等)。

Web应用

  1. Web应用的目录结构
    • news(目录,Web应用)
      • 也可将Web资源文件放在Web应用的根目录下
      • 其他目录(放在其他目录中的资源文件可以被浏览器直接访问到)
      • WEB-INF目录(隐私目录,放在这里面的资源文件,不能被浏览器直接访问)
        • classes目录(Java程序编译后的.class文件会放在此目录下)
        • lib目录(Web应用所依赖的jar包会放在此目录下)
        • web.xml文件(当前Web应用的核心配置文件)
  2. 如何发布一个Web应用到虚拟主机中
    • 直接将Web应用的目录复制到虚拟主机所管理的目录下即可
    • 例如:将news复制到webapps目录下,由于webapps是localhost主机发布web应用的目录
    • 所以相当于将news发布到了localhost主机中,可以通过localhost主机进行访问。

导入已有的Maven项目

  1. 导入数据库(yonghedb)、表、表记录

    • 打开"yonghe-ssm项目"目录中的"SQL脚本.txt", 复制其中的SQL语句, 到Navicat中执行
    • 执行后会创建yonghedb库, 并创建 tb_door 表(门店表) 和 tb_order(订单表)
  2. 导入yonghe项目

    • 方式一: 通过import导入(只要是eclipse创建的项目, 任何项目都可以这样导入)

      • 点击eclipse左上角的"File" --> “Import…”, 在弹出的窗口中找 “General” --> “Existing Project into Workspace”
      • 接着会切换到下一个窗口, 可以看到一个 "Select root directory"选项(选择根目录), 这行的后面有 “Browse…” 选项, 点击 “Browse…” 可以找到你要导入的项目, 点击你要导入的项目, 点击下方的 “选择文件夹”
      • 接着在窗口中间的位置 找到 “Copy Pojects into workspace” 选项并选中该选项, 选中该选项意味着: 导入的项目会复制到工作空间中一份(这样的好处是, 即使导入位置的项目删除了也不影响, 因为已经把整个项目复制到工作空间中了), 最后点击 “Finish” 完成即可!
    • 方式二: 创建新的项目, 将原项目中的代码复制到新项目中

      • 创建一个同类型的新的项目
        • 如果要导入的项目是Maven的Web项目,也就需要你创建一个Maven的Web项目
        • 这里新项目的名字可以 和原项目保持一致, 也可以不一致
      • 将原项目中的src目录复制到新项目中, 将新项目中的src目录覆盖即可
      • 如果是maven项目, 那么其中还有pom.xml文件, 将原项目中的 pom.xml 文件打开, 将其中需要的配置复制, 粘贴到新项目的pom文件中的对应位置即可!
  3. 可能出现的问题

    • 导入项目后如果是 xxx.xml 文件报错, 这里的错误可以忽略, 是eclipse误报的!

    • 如果在导入项目后,有叹号(!),都是因为maven没有将所有的环境/依赖下载下来。

    • 可以通过如下三个步骤去解决:

      • 打开yonghe项目,找到其中的pom.xml文件,在文件中敲一个空白行并保存,让maven重新扫描pom文件,并根据其中的配置下载所需要的依赖;
      • 在报错的maven项目上右键–> Maven–> Update Project…,在弹出的窗口中勾选下方的[]Force Update…,即勾选强制更新,如果还没有解决,再看第3步!
      • 下载老师下发的本地仓库(localRepo(maven的本地库).zip),用老师下发的本地仓库,替换自己的本地仓库!
    • 运行导入的yonghe项目,在项目上右键–> Run As --> Run On Server,在打开的浏览器地址栏后面补全路径: http://localhost:8080/yonghe/index

    • /index对应的是controller中的一个方法,最后会跳转到index.jsp

Servlet

什么是Servlet

  1. Servlet是由SUN公司提供开发的一门Web资源开发技术(规范、接口)。
  2. Servlet本质上是一个Java程序,但和我们之前接触的不同。
  3. Servlet无法独立运行(Servlet中没有main函数)。
  4. 需要将Servlet程序放在服务器中,由服务器调用才可以执行。
  5. 运行在服务器中的Servlet程序作用是:对服务器接收的请求进行处理(处理请求)。

开发Servlet程序

  1. 开发Servlet程序的步骤
    • 写一个类,需要实现一个Servlet接口或者继承Servlet接口的子类
      • Servler
        • GenericServlet实现了Servlet接口,并实现了其中的方法
        • HttpServlet继承了GenericServlet,也实现了其中的方法
      • 在开发时,我们只需要继承HttpServlet,并继承其中的方法即可
    • 在web.xml文件中配置Servlet对外访问的路径,再将Web应用发布到服务器即可。
    • 如果是Servlet3.0及以上版本,可以使用注解方式配置Servlet访问路径。
  2. 如何通过Eclipse创建一个Servlet程序?
    • Ctrl+N, 会弹出创建窗口, 在输入框中输入 “servlet” 进行搜索, 选中servlet, 点击 “Next”
    • 接着进入下一界面(其实这里和我们之前创建类几乎一样了, 区别就是这里默认会继承 HttpServlet )
    • 填写包名和类名点击完成即可。
    • 创建好的类中有很多不需要的注释和构造方法实现, 删除即可!
    • 创建的Servlet类的内部保留 doGet 和 doPost 方法即可!
  3. 运行Servlet程序
    • 第一种运行方式:

      • 直接在要运行的文件(html/jsp/servlet等)上–>右键–>Run as–>Run On Server,
      • eclipse会帮我们做如下几件事儿:
        • 将Servlet所在的Web项目(CGB-Servlet-01)发布到服务器中
        • 再启动tomcat服务器
        • 最后打开浏览器,在地址栏输入路径去访问这个Servlet
      • Eclipse默认用内置浏览器去访问Servlet,但是这个内置浏览器有bug,最好是使用本地的浏览器去测试!
    • 第二种运行方式: 可以自己手动将项目发布到服务器、启动服务器、打开浏览器输入地址进行访问!

  4. Servlet在web.xml文件中的配置
    • 全限定类名(全类名):包名.类名 或者 包名.接口名

        <servlet>	
        	<servlet-name>HelloWorld</servlet-name>
        	<servlet-class>cn.tedu.HelloWorld</servlet-class>
        </servlet>
        <servlet-mapping>
        	<servlet-name>HelloWorld</servlet-name>
        	<url-pattern>/HelloWorld</url-pattern>
        </servlet-mapping>
      
    • 每创建一个Servlet,eclipse会帮我们生成至少8行配置信息

      • 这8行配置信息由一个servlet标签和一个servlet-mapper标签组成。
      • 这两个标签中的< servlet-name >标签中的内容一致,决定了它俩是一组配置。
    • < servlet-class >标签中配置的当前Servlet类的全类名(包名.类名)。

      • 将来服务器根据访问路径找到这个全类名,再利用反射+全类名可以获取当前Servlet类的实例。
    • < url-pattern >标签中配置了外界应该通过什么路径来访问当前Servlet。

      • 也就是说,这里配置什么路径,外界旧的通过什么路径来访问这个Servlet。
    • 注意事项1:如果不知道什么原因,tomcat服务器启动失败了,可以将Eclipse创建的Servlet删除,再重新创建一份(删除Servlet同时,也将左侧的Servlet项目从工作空间中删除。

    • 注意事项2:在将tomcat和Eclipse整合之后,tomcat默认开启了热部署功能:

      • 在修改了代码之后,不需要重启服务器,就可以运行得到新的效果。
      • 如果是创建了新的Servlet类,或者修改了web.xml文件,则需要重启服务器后才会生效。
  5. 创建Servlet3.0或以上版本的项目
    • 在Servlet3.0的项目中,可以通过注解方式配置Servlet相关信息

        @WebServlet(name = "HelloWorld")
        public class HelloWorld extends HttpServlet {}
      
    • 在@WebServlet这个注解内容所配置的内容就是(xml方式)url-pattern中配置的访问路径。

    • 在服务器通过扫描注解定位到当前这个Servlet,获取该类的全路径。

    • 通过全路径从硬盘上加载这个类到内存中,获取该类的字节码对象,再利用反射+字节码对象创建该类的实例,然后通过HelloWorld类的对象实例再调用其中的方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刘刘刘刘刘先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值