Mybatis框架复习&&整合Spring(一)

  1. 数据持久化
    保存再内存中的数据是处于瞬时状态的,而保存在存储设备中的数据是处于持久状态的,数据持久化就是将内存中的数据保存到储存设备中,保证即使在手机或电脑关机的情况下,防止数据丢失
  2. ORM原理
    ORM 的全称 Object Relational Mapping 即对象关系映射,它的实现思想就是将关系数据库中表的数据映射称为对象,以对象的形式展现,这样开发人员就可以把数据库的操作转化为对这些对象的操作,因此它的目的是为了方便开发人员以面向对象的思想来实现对数据路的操作
    ORM的技术特点:
    1.提高了开发效率,由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的,庞大的数据访问层
    2.ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据
  3. 什么是Mybatis
    Mybtais是apache的一个开源项目iBatis,2010年这个项目由apachesoftware foundation迁移到了google code,并正式改名为Mybatis,2013年11月迁移到了GitHub。Mybatis是一个非常优秀的持久层框架,他对jdbc的操作数据库的过程进行封装,使开发者只需要关注sql本身,而不需要花费经历去处理如注册驱动,创建连接,手动设置参数,结果集检索等jdbc繁杂的
    代码
    Mybatis通过xml或者注解的方式,将要执行的各种statement配置起来,并通过java对象和statement中sql进行映射生成最终指定的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回
    总之Mybatis对JDBC访问数据库的过程做了封装,简化了jdbc代码,解决JDBC将结果集封装为java对象的麻烦
    sqlMapConfig.xml :是 Mybatis 核心的配置文件,通过其中的配置,可以生成SqlSessionFactory, 也就是 SqlSession 工厂
    SqlSessionFactory :用于生成 SqlSession 对象
    SqlSession :是一个既可以发送 sql 去执行,并返回结果,类似于JDBC中的 Connection 对象,也是 Mybatis 中至关重要的一个对象
    Executor :是 SqlSession 底层对象,用于执行 SQL 语句
    MapperStatement :是 SqlSession 底层对象,用于接收输入映射(sql语句中的参数 ) ,以及做输出映射 ( SQL 查询的结果映射成相应的对象)
  4. 为什么使用Mybatis
    1. 使用传统方式 JDBC访问数据库
      使用 JDBC 访问数据库有大量重复的代码
      JDBC 自身没有连接池,会频繁的创建连接和关闭连接,效率低
      SQL 是写死在程序中,一但修改 sql ,需要对类进行重新编译
      对查询 SQL 执行后返回的 ResultSet 对象,需要手动处理,有时会特别麻烦
    2. 使用 mybatis框架访问数据库
      mybatis JDBC 做了封装,可以简化代码
      mybtais 自身自带连接池 ( 也可以配置其他的连接池 ) ,因此可以提高程序员的效率
      mybtais 是将 sql 配置在 mapper.xml 文件中,修改 sql 只是修改配置文件,类不需要重新编译
      ORM- 自动映射
  5. Sql 语句练习,数据库准备
    #1. 创建 ums 数据库
    create database ums;
    use ums;
    #2. 在以上库中,创建 user 的数据表,至少包含 id, 用户名 , 密码,年龄,手机号码,邮箱
    create table user(
    id int auto_increment comment ' 用户的 id' ,
    username varchar ( 30 ) unicode not null comment ' 用户名 ' ,
    password varchar ( 30 ) not null comment ' 密码 ' ,
    age int comment ' 年龄 ' ,
    phone varchar ( 20 ) comment ' 手机号码 ' ,
    email varchar ( 50 ) comment ' 电子邮箱 ' ,
    primary key (id)
    );
    #3. 向表中插入不少于 10 条用户数据
    insert into user values
    ( null , 'A' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'B' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'C' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'D' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'E' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'F' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'G' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'H' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'I' , '123' , 20 , '13333333333' , '133@133.com' );
    insert into user values
    ( null , 'J' , '123' , 20 , '13333333333' , '133@133.com' );
    #4. 删除 id= 3 的数据;
    DELETE FROM t_user WHERE id= 3 ;
    #5. 删除 id= 2 id= 7 id= 9 的数据;
    DELETE FROM t_user WHERE id IN ( 2 , 7 , 9 );
    DELETE FROM t_user WHERE id= 2 OR id= 7 OR id= 9 ;
    #6. 将所有用户的密码全部改为 888888
    UPDATE t_user SET password= '888888' ;
    #7. id= 6 的用户的邮箱改为 user06@tedu .cn
    UPDATE t_user SET email= 'user06@zb.cn' WHERE id= 6 ;
    #8. 查询当前表中用户的数量;
    SELECT COUNT (*) FROM t_user;
    #9. 查询 id= 8 的用户数据详情;
    SELECT * FROM t_user WHERE id= 8 ;
    #10. 查询所有用户的数据;
    SELECT * FROM t_user ORDER BY id;
    #11. 查询年龄最大的那 1 个用户的数据(假设所有用户的年龄值都不相同)。
    SELECT * FROM t_user ORDER BY age DESC LIMIT 0 , 1 ;
    SELECT * FROM tuser WHERE age=( SELECT MAX(age) FROM tuser);
  6. Mybatis 框架搭建
    1. 创建 maven 项目
    2. 导入 jar
      <dependencies>
              <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.4.6</version>
              </dependency>
              <!-- https://mvnrepository.com/artifact/mysql/mysql- connector-java -->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>5.1.47</version>
              </dependency>
              <!-- https://mvnrepository.com/artifact/org.projectlombok/lombo k -->
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>1.18.12</version>
                  <scope>provided</scope>
              </dependency>
          </dependencies>
    3. 创建 Mybatis 配置文件
      <?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>
          <!--单独使用Mybatis配置以下内容,和Spring整合后以下无需配置-->
          <environments default="development">
              <environment id="development">
                  <!--mybatis提供了3种数据源类型,
                  分别是 POOLED,UNPOLLED,JNDI
                  POOLED表示支持JDBC数据源连接池
                  UNPOOLED表示不支持数据源连接池
                  JNDI表示支持外部数据源连接池 -->
                  <transactionManager type="JDBC"></transactionManager>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3306/ums?characterEncoding=utf-8"/>
                      <property name="username" value="root"/>
                      <property name="password" value="root"/>
                  </dataSource>
              </environment>
          </environments>
          <!--告诉框架,你的sql语句写到了哪里,配置mapper-->
          <mappers>
             <mapper resource="UserMapper.xml"></mapper>
          </mappers>
      </configuration>
    4. 创建实体类
      @Data
      @ToString
      public class User {
          private Integer id;
          private String username;
          private String password;
          private Integer age;
          private String phone;
          private String email;
          private Integer idDelete;
          private Integer departmentId;
      }
    5. 创建 UserMapper.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: 类似于包的存在,就是306的张三和405的张三
          命名空间, 可以随意定义, 一般情况下要写全限定路径
          MyBatis管理SQL语句是通过namespace+id来定位的
      -->
      <mapper namespace="com/zb/mapper/UserMapper">
          <insert id="insert">
              insert into user values (#{id},#{username},#{password},#{age},#{phone},# {email})
          </insert>
      
          <select id="findAll" resultType="com.zb.pojo.User">
              select * from user
          </select>
      
          <select id="findById" resultType="com.zb.pojo.User">
              select * from user where id=#{id}
          </select>
      
          <update id="updateEmailById">
              update user set email=#{email} where id=#{id}
          </update>
      </mapper>
    6. 测试类测试
      public class Testmybatis {
          @Test
          public void testInsert() throws IOException {
              InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
              SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(is);
              SqlSession session = factory.openSession();
              User user=new User();
              user.setUsername("xiaowei");
              user.setPassword("root");
              user.setPhone("15534033890");
              Integer i= session.insert("test.insert",user);
              session.commit();
          }
          @Test
          public void testselect() throws IOException {
              InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
              SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(is);
              SqlSession session = factory.openSession();
              List<User> list=session.selectList("test.findAll");
              System.out.println(list);
              session.close();
          }
      
          @Test
          public void findById() throws IOException {
              InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
              SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(is);
              SqlSession session = factory.openSession();
              List<User> list=session.selectList("test.findById",1);
              System.out.println(list);
              session.close();
          }
          @Test
          public void updateEmailById() throws IOException{
              InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
              SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(is);
              SqlSession session = factory.openSession();
              User user=new User();
              user.setEmail("1323791468@qq.com");
              user.setId(14);
              session.update("test.updateEmailById",user);
              session.commit();
          }
      }
  7. Spring整合Mybatis
    1. 创建maven-web项目

    2. 导入依赖
      <dependencies>
          <!--导入junit与Spring依赖-->
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
          </dependency>
      
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.6.RELEASE</version>
          </dependency>
            <!--导入Mybatis依赖-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.4</version>
            </dependency>
          <!--mybatis和spring整合,需要添加mybatis-spring依赖-->
          <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.4</version>
          </dependency>
          <!--器核心依赖是通过jdbc技术实现的,需要添加 spring-jdbc的依赖 此依赖必须与spring-webmvc版本一致-->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.6.RELEASE</version>
          </dependency>
          <!--连接Mysql数据库,添加mysql数据库依赖-->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
          </dependency>
        <!--还会用到数据库连接池,导入连接池依赖 -->
          <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
          </dependency>
      
          <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
          </dependency>
        </dependencies>
    3. 在src/main/resources 下创建db.properties数据库连接配置文件
      url=jdbc:mysql://localhost:3306/ums?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
      driverClassName=com.mysql.jdbc.Driver
      username=root
      password=root
      initialSize=2
      maxActive=10

       

    4. 在resources文件夹下创建spring配置文件spring-config.xml,配置数据库连接池
      <?xml version="1.0" encoding="UTF-8"?>
      <beans default-lazy-init="true"
             xmlns="http://www.springframework.org/schema/beans"
             xmlns:p="http://www.springframework.org/schema/p"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xmlns:util="http://www.springframework.org/schema/util"
             xmlns:jpa="http://www.springframework.org/schema/data/jpa"
             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/tx
             http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
             http://www.springframework.org/schema/aop
             http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
             http://www.springframework.org/schema/util
             http://www.springframework.org/schema/util/spring-util-4.3.xsd
             http://www.springframework.org/schema/data/jpa
             http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-4.3.xsd">
      
          <util:properties id="dbConfig" location="classpath:db.properties">
          </util:properties>
      
          <!--配置数据源 创建连接池对象-->
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
              <property name="url" value="#{dbConfig.url}"></property>
              <property name="driverClassName" value="#{dbConfig.driverClassName}"></property>
              <property name="username" value="#{dbConfig.username}"></property>
              <property name="password" value="#{dbConfig.password}"></property>
              <property name="initialSize" value="#{dbConfig.initialSize}"></property>
              <property name="maxActive" value="#{dbConfig.maxActive}"></property>
          </bean>
      
          <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <property name="basePackage" value="com.zb.mapper"></property>
           </bean>
      
          <bean class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"></property>
              <property name="mapperLocations" value="classpath:mappers/*.xml"></property>
              <!--加载mybatis配置文件,以开启驼峰映射-->
              <property name="configLocation" value="classpath:mybatis-config.xml"></property>
          </bean>
      
      
      
      
      </beans>

       

    5. 测试以上配置是否正确
      public class TestDateSource {
          private ClassPathXmlApplicationContext ac;
          @Before
          public void doBefore(){
              ac=new ClassPathXmlApplicationContext("spring-config.xml");
          }
          @Test
          public void TestTestDateSource() throws SQLException{
              BasicDataSource dataSource=ac.getBean("dataSource",BasicDataSource.class);
              Connection conn=dataSource.getConnection();
              System.out.println(conn);
          }
          @After
          public void doAfter(){
              ac.close();
          }
      }
  8. Spring整合Mybatis实现增删改查
    1. 数据准备,实现插入数据
      1. 创建实体类
        @Data
        @ToString
        @Accessors(chain = true)
        public class User {
            private Integer id;
            private String username;
            private String password;
            private Integer age;
            private String phone;
            private String email;
        }
        
      2. 创建接口
        Mybatis 中,配置的抽象方法都必须存在于接口中,所以,首先需要创建封装抽象方法的接口文件 com.zb.mapper.UserMapper ,并在接口中添加 " 插入用户数据" 的抽象方法
        public interface UserMapper {
            Integer insert(User user);
        }
        关于抽象方法的设计原则:
        如果是增删改操作,需要使用 Integer 作为返回值类型,表示受影响的行数
        如果不关心受影响的行数,也可以使用 void 作为返回值类型
        方法的名称可以自定义,但是不允许出现重载,也就是方法名要唯一
        参数列表可以根据实际需求来决定
      3. 配置MapperScannerConfigure
        此配置的作用就是,使得 Mybatis 框架知道接口文件在哪里,配置到 spring的配置文件中
         <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                <property name="basePackage" value="com.zb.mapper"></property>
             </bean>

         

      4. 配置SqlSessionFactory
        我们之前 Mybatis 核心对象我们都是自己 New 的,现在我们要将对象的创建交给spring 去做
        还需要让 mybatis 知道我们使用的数据源是哪一个,写 sql 语句的 mapper 在哪里
        配置在 spring 的配置文件中
        <bean class="org.mybatis.spring.SqlSessionFactoryBean">
                <property name="dataSource" ref="dataSource"></property>
                <property name="mapperLocations" value="classpath:mappers/*.xml"></property>
            </bean>

         

      5. 编写mapper.xml,编写sql语句
        上面我们已经创建了 UserMapper.xml, 并且告诉了框架 mapper.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: 类似于包的存在,就是306的张三和405的张三
            命名空间, 可以随意定义, 一般情况下要写全限定路径
            MyBatis管理SQL语句是通过namespace+id来定位的
        -->
        <mapper namespace="com.zb.mapper.UserMapper">
            <insert id="insert">
                insert into user values (#{id},#{username},#{password},#{age},#{phone},#{email})
            </insert>
        </mapper>

         

      6. 测试类测试
        public class TestDataSource {
            private ClassPathXmlApplicationContext ac;
            private UserMapper userMapper;
            @Before
            public void doBefore(){
                ac=new ClassPathXmlApplicationContext("spring-config.xml");
                userMapper=ac.getBean("userMapper",UserMapper.class);
            }
            @Test
            public void TestTestDataSource() throws SQLException {
                User user=new User();
                user.setId(null).
                        setUsername("mama").
                        setPassword("81").
                        setAge(56).
                        setPhone("15534033890").setEmail("1323791468@qq.com");
        
                Integer i=userMapper.insert(user);
                System.out.println(i);
        
            }
            @After
            public void doAfter(){
                ac.close();
            }
        }
        
    2. 查询语句
      1. 多个参数的增删改查
        假设需要根据 id 修改邮箱,则抽象方法应该为
        Integer updateEmailById ( Integer id , String email );
        配置的 sql 映射应该为
        <update id = "updateEmailById" >
        update user set email = #{email} where id = #{id}
        </update>
        以上这样做是不能实现的,会报错
        其实Mybatis框架只能识别抽象方法中的一个参数,如果有多个参数,可以使用实体类进行封装,但是如果实体类中有很多属性,实际使用的只需要2个,就很浪费,也可以使用Map将多个参数封装起来,但是,不便于使用,因为方法的调用者在封装参数时,可能不明确需要封装的参数的数量是多少,也不明确每个参数的key是多少
        Mybatis给出的解决方法就是使用@Param注解
        Integer updateEmailById ( @Param ( "id" ) Integer
        id , @Param ( "email" ) String email );
        在配置映射时,sql语句中#{}占位符中的名称就必须时@Param注解中指定的名称
        在底层实现方面,Mybatis会基于注解中的名称和调用方法时的参数值,将多个参数封装成一个Map集合
        小结:在Mybatis应用中,如果抽象方法的参数超过一个,则每个参数之前都必须添加@Param注解,以指定参数的名称,在配置映射时,必须与注解中的名称保持一致
      2. 动态SQL-foreach
        动态值指的是根据参数的不同,生成不一样的sql语句
        在Mybatis中,提供了一些具备逻辑判断能力的循环操作的特殊标签,可以在配置SQL语句时,添加这些标签,使得最终生成的sql语句是不同的
        例如:批量删除用户,则抽象方法可以是:
        // 根基 ID 批量删除用户
        Integer deleteByIds ( List < Integer > ids );
        由于 ID 的值的数量是位置的,可以使用数组或集合类型的参数来表示若干个id 值,在配置 sql 语句时,由于需要根据数组或集合类型的参数,反复生成多个sql 语句,所以需要使用节点来循环生成其中的代码
        <delete id = "deleteByIds" >
        delete from user where id in <!--(1,2,3,4)-->
        <foreach collection = "list" item = "id" separator = ","
        open = "(" close = ")" >
        #{id}
        </foreach>
        </delete>
        测试:
        @Test
        public void deleteByIds (){
            List list = new ArrayList ();
            list . add ( 1 );
            list . add ( 2 );
            list . add ( 3 );
            Integer i = userMapper . deleteByIds ( list );
           System . out . println ( i );
        }
        connection :被遍历的集合,当抽象方法的参数只有一个时,当被遍历的参数类型是List 时,取值为 list ,当被遍历的参数是数组类型时,取值为array ,当抽象方法的参数超过一个时,必须添加@Param注解,且配置该属性时,值是注解中使用的名称
        item :遍历过程中,被遍历到的元素的名称,是自定义的名称,在节点内部,使用的#{} 的占位符中就需要填写这个自定义的名称
        separator :生成 sql 语句中,各参数之间使用的分隔符
        open close :用于配置生成的 sql 语句部分的最左侧字符和最右侧字符
        批量删除用户,传多个参数 
        Integer deleteByIds2(@Param("ids") Integer...id); 
        
        
        <delete id="deleteByIds2"> 
            delete from user where id in <!--(1,2,3,4)--> 
            <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach>
        </delete>
        
        @Test public void deleteByIds(){ 
            Integer i = userMapper.deleteByIds2(4,5,6); 
            System.out.println(i); 
        }
      3. 动态SQL-if
        List<User> find( 
                @Param("where") String where,//查询有没有条件 
                @Param("orderBy") String orderBy,//有没有排序 
                @Param("offset") Integer offset,//分页从第几条开始查 
                @Param("count") Integer count//分页每页显示几条 
        );
        
        <select id="find" resultType="com.zb.pojo.User"> 
            select * from user 
            <if test="where != null"> where ${where} <!--传一个表达式--> </if> 
            <if test="orderBy!=null"> order by ${orderBy} desc </if> 
            <if test="offset!=null"> limit #{offset},#{count} </if> 
        </select>
        
        @Test public void find(){ 
            List<User> list = userMapper.find(null,"age",0,7); 
            System.out.println(list); 
        }
        
  9. Mybatis#{}${}的区别
    使用 ${} 做测试
    User findById ( Integer id ); // mybatis 高版本中此处是不需要加
    @Param 注解的 低版本需要加
    <select id = "findById" resultType = "com.zb.pojo.User" >
        select * from user where id = ${id}
    </select>
    @Test
    public void findById (){
        User user = userMapper . findById ( 10 );
        System . out . println ( user );
    }
    在Mybatis中,#{}格式的占位符只能为值进行占位,可以理解为 ,此前学习JDBC时,使用PreparedStatement时,写的?的占位符,就可以使用这样的占位符 例如select * from user where id = ? 但是不可以是:select * from user where ?
    #{}只能传一个固定的值,不能传表达式或其他语句
    如果一定要实现这样的目的,例如上面讲的If条件,可以使用 ${}格式的占位符,这样的占位符可以为sql语句中的任何位置进行占位,只要最终形成的sql语句的语法是正确的即可(也就是我们之前使用Statement时字符串拼接)
    使用${}进行展位的处理方式,并不是预编译的作法,其处理流程是将xml中配置的sql语句与占位符的值进行拼接,然后在进行预编译的处理,编译之后直接执行 而使用#{}进行占位时,其处理流程是先无视#{}占位符的值,直接进行编译,当编译完成后,再结合#{}对应的值来执行
    小结:以前使用JDBC时能使用?的位置都应该使用#{}格式的占位符,使用这种占位符不需要考虑值数据类型的问题,即字符串的值也不需要添加单引号,另外也没有sql注入问题
    其他场景都应使用${}格式的占位符,这种占位符不是预编译的值,在使用时,涉及到值时,需要考虑是否应添加单引号或其他符号的问题,同时还要考虑sql注入的风险
    <select id="find" resultType="com.zb.pojo.User"> 
        select * from user 
        <if test="where != null"> where ${where} <!--传一个表达式--> 
        </if> 
        <if test="orderBy!=null"> order by ${orderBy} desc </if> 
        <if test="offset!=null"> limit #{offset},#{count} </if> 
    </select>
  10. 解决数据库字段和实体类属性不对应的问题 
    user 表中添加一个新的字段 is_delete 表示用户诗句是否被标记为删除状态
    该字段的值将使用 0 表示未删除, 1 表示已删除
    alter table user add column is_delete int ;
    update user set is_delete= 0 ;
    set sql_safe_updates= 0 ;
    数据库添加了新的字段后,对应的 User 实体类中也应添加新的属性
    @Data
    @ToString
    @Accessors(chain = true)
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Integer age;
        private String phone;
        private String email;
        private Integer isDelete;
    }
    
    此刻由于数据库表字段和实体类属性名不一致,导致我们在查询的时候,实体类中isDelete属性读取不到值,值为null
    
    1. 利用别名
      修改查询功能,根据 id 查询用数据功能为例,如果没有经过任何调整,查询结果中isDelete 属性是没有值的,因为 Mybatis 会自动的将查询结果列名与属性名相对应来封装数据
      <select id="findById" resultType="com.zb.pojo.User"> 
          select id,username,password,age,phone,email,is_delete as isDelete from user where id = 
      ${id}
      </select>
    2. 开启驼峰映射
      开启驼峰映射功能 需要在 mybatis 配置文件中开启 
      <?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>
          <!--全局配置--> 
          <settings> 
              <!--是否开启自动驼峰名命规则映射 
              即从数据库列表名 A_COLUMN 到Java属性名 aCoulumn --> 
              <setting name="mapUnderscoreToCamelCase" value="true"/>
          </settings>
      </configuration>
                                                                                                                                                                                              在spring 配置文件中 配置 SqlSessionFactoryBeande bean 标签中,添加一个属性,目的是加载我们的mybatis 配置文件
      <bean class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"></property>
              <property name="mapperLocations" value="classpath:mappers/*.xml"></property>
              <!--加载mybatis配置文件,以开启驼峰映射--> 
              <property name="configLocation" value="classpath:mybatis-config.xml"></property>
          </bean>

       

    3. resultMap
      在配置映射的 xml 文件中,可以配置 <resultMap> 节点,用于指导 Mybatis ,如何将查询结果封装到对象中
      <!--resultMap: 指导 ( 自定义 )MyBatis 如何将查询结果进行封装 -->
      <!--
      id: 自定义名称,将作为 <select> 标签中 resultMap 属性的值
      type: 将查询结果封装到哪种类型的对象中
      -->
      <resultMap id = "UserMap" type = "com.zb.pojo.User" >
      <!--
      column: 查询结果中的列
      property :封装查询结果的类的属性
      -->
          <result column = "id" property = "id" ></result>
          <result column = "username" property = "username" > </result>
          <result column = "password" property = "password" > </result>
          <result column = "age" property = "age" ></result>
          <result column = "phone" property = "phone" ></result>
          <result column = "email" property = "email" ></result>
          <result column = "is_delete" property = "isDelete" > </result>
      </resultMap>
      <select id = "findByUsername" resultMap = "UserMap" >
      select * from user where username = #{username}
      </select>

       

  11. 关联查询                                                                                                                                                                                 创建部门表,表名department,该表中至少包含idname这两个字段
    create table department(
    id int auto_increment comment ' 部门 id' ,
    name varchar ( 20 ) not null comment ' 部门名称 ' ,
    primary key (id)
    );
    insert into department (name) value ( ' 软件研发部 ' ),( ' 人力资源部' ),( ' 财务部 ' );
    在用户信息表中添加department_id字段:
    alter table user add column department_id int ;
    update user set department_id= 1 where id in ( 7 );
    update user set department_id= 2 where id in ( 8 );
    update user set department_id= 3 where id in ( 9 );
    User 实体类中添加 departmentId
    @Data
    @ToString
    @Accessors(chain = true)
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Integer age;
        private String phone;
        private String email;
        private Integer isDelete;
        private Integer departmentId;
    }
    假设存在需求:根据用户 id 查询用户数据时,还要求显示该用户所归属的部门的名称,则需要执行的sql 语句大致是:
    select * from user u left join department d on u .department_id = d .id where u .id = 8
    在编程时,首先应该设计其抽象方法,但是目前没有哪个数据类型足以封装此次查询结果,所以,在设计抽象方法之前,需要首先设计VO类来封装查询结果
    pojo--代表普通的实体类
    entity--代表与数据库表对应的实体类,由于实体类的属性是完全参考数据库表结构来进行设计的,所以该实体类一定不满足多表联合查询的需求
    vo--代表根据查询结果设计的实体类,是根据查询结果的字段来设计的,用于多表查询
    起到见名知意的效果
    @Data
    @ToString
    public class UserAndDepartment {
        private Integer userId;
        private String username;
        private String password;
        private Integer age;
        private String phone;
        private String email;
        private Integer isDelete;
        private Integer departmentId;
        private String departmentName;
    }
    
    编写抽象方法
    UserAndDepartmentVO findVOById ( Integer id );
    配置 xml:
    <!-- 此处采用别名方式解决 -->
    <select id = "findVOById" resultType = "com.zb.vo.UserAndDepartmentVO" >
        select u.id as userId,username,password,age,phone,email,is_delete as isDelete,
    department_id as departmentId,name as departmentName
    from user u left join department d on
    u.department_id = d.id where u.id=#{id};
    </select>
    测试:
    @Test
    public void findVOById (){
        System . out . println ( userMapper . findVOById ( 8 ));
    }
    利用 resultMap 来查询 VO
    <resultMap id = "userVO" type = "com.zb.vo.UserAndDepartmentVO" >
        <result column = "id" property = "userId" ></result>
        <result column = "username" property = "username" > </result>
        <result column = "password" property = "password" > </result>
        <result column = "age" property = "age" ></result>
        <result column = "phone" property = "phone" ></result>
        <result column = "email" property = "email" ></result>
        <result column = "is_delete" property = "isDelete" > </result>
        <result column = "department_id" property = "departmentId" ></result>
        <result column = "name" property = "departmentName" > </result>
    </resultMap>
    <select id = "findVOById" resultMap = "userVO" >
        select * from user u left join department d on u.department_id = d.id where u.id=#{id}
    </select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值