zoukankan      html  css  js  c++  java
  • Mybatis入门(二)

      上文中说道SqlSession执行语句时的用法,不过现在有了一种更简洁的方式 ——使用正确描述每个语句的参数和返回值的接口(比如 UserMapper.class),你现在不仅可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。

    文件层次如图:

        

    代码示例:

    @AllArgsConstructor
    @NoArgsConstructor
    @Getter@Setter
    @ToString
    @Alias("User")
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Date date;
        private BigDecimal salary;
    }
    beanUser(使用了lombok插件)
    public interface IUserService {
        void save(User user);
        void delete(Integer id);
        void update(User user);
        User find(Integer id,String username);
        List<User> findAll();
        List<User> findOrderByColumn(String column);
        void deleteSelectAll(int[] ids);
    }
    IUserService接口
    public class UserServiceImpl implements IUserService {
        
        @Override
        public void save(User user) {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            um.save(user);
            session.commit();
            session.close();
        }
    
        @Override
        public void delete(Integer id) {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            um.delete(id);
            session.commit();
            session.close();
        }
    
        @Override
        public void update(User user) {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            um.update(user);
            session.commit();
            session.close();
        }
    
        @Override
        public User find(Integer id,String username) {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            User user = um.find(id, username);
            session.close();
            return user;
        }
    
        @Override
        public List<User> findAll() {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            List<User> all = um.findAll();
            session.close();
            return all;
        }
    
        @Override
        public List<User> findOrderByColumn(String column) {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            List<User> orderByColumn = um.findOrderByColumn(column);
            session.close();
            return orderByColumn;
        }
    
        @Override
        public void deleteSelectAll(int[] ids) {
            SqlSession session = MybatisUtil.getSession();
            /*MAP接口的代处理对象*/
            UserMapper um = session.getMapper(UserMapper.class);
            um.deleteSelectAll(ids);
            session.commit();
            session.close();
        }
    }
    UserServiceImpl
    public interface UserMapper {
        void save(User user);
        void delete(Integer id);
        void update(User user);
        User find(@Param("id") Integer id,@Param("username") String username);
        List<User> findOrderByColumn(@Param("column") String column);
        List<User> findAll();
        void deleteSelectAll(int[] ids);
    }
    UserMapper
    <?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:写UserMapper接口的全限定名-->
    <mapper namespace="com.test.mapper.UserMapper">
        <!--  #{}表示调用对象中响应的get方法-->
        <!--  注意,这里的标签中的id值是唯一的
        因为在UserMapper的底层是将namespace和id一起作为一个Map集合的key,sql语句作为value,因为map的key唯一,所以id必须唯一 -->  
        <!--  保存  -->
        <!--useGeneratedKeys为true表示返回主键的值 keyProperty表示返回给对象的哪个属性-->
        <insert id="save" useGeneratedKeys="true" keyProperty="id">
            insert into user values(null,#{username},#{password},#{date},#{salary})
        </insert>
    
        
        <!--  删除  -->
        <delete id="delete">
            delete from user where id=#{id}
        </delete>
        <!--批量删除-->
        <delete id="deleteSelectAll">
            delete from user where id in 
            <foreach collection="array" open="(" close=")" item="item" separator=",">
                #{item}
            </foreach>
        </delete>
    
        <!--  更新  -->
        <update id="update">
            update user
            <trim prefix="set" suffixOverrides=",">
                <if test="username!=null">
                    username=#{username},
                </if>
                <if test="password!=null">
                    password=#{password},
                </if>
                <if test="date!=null">
                    date=#{date},
                </if>
                <if test="salary!=null">
                    salary=#{salary},
                </if>
            </trim>
            where id=#{id}
        </update>
    
        <!--type:把结果集封装成对象的类型-->
        <resultMap id="myResultMap" type="User">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
            <result column="date" property="date"/>
            <result column="salary" property="salary"/>
        </resultMap>
    
        <!--  查询一个  -->
        <!--<select id="find" resultMap="myResultMap">
            select * from user where 1=1
            <if test="username !=null">
                and username = #{username}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
        </select>-->
        <select id="find" resultMap="myResultMap">
            select * from user
            <where>
                <if test="username !=null">
                    username = #{username}
                </if>
                <if test="id != null">
                    and id = #{id}
                </if>
            </where>
        </select>
    
        <!--  查询全部 -->
        <select id="findAll" resultType="User">
            select * from user
        </select>
    
        <!--通过列名降序查询-->
        <select id="findOrderByColumn" resultType="User">
            select * from user order by ${column} desc
        </select>
    
    </mapper>
    UserMapper.xml

    几个知识点介绍:重点

    1、Mapper接口的使用方式及原理

      1.mapper映射文件中的namespace的值,必须等于mapper接口的全限定名

      2.mapper映射文件中的Sql的id,必须等于mapper接口中的方法名

      3.mapper映射文件中的Sql的paramterType必须跟对应的方法的类型相同

      4.方法的返回值必须和resultType或者resultMap的值保持一致

      以Update为例,图中解释了update的原理

    2、保存数据自动获取数据库生成的主键

        <!--useGeneratedKeys为true表示返回主键的值
         keyProperty表示返回给对象的哪个属性-->
        <insert id="save" useGeneratedKeys="true" keyProperty="id">
            insert into user values(null,#{username},#{password},#{date},#{salary})
        </insert>

    3、resultMap的使用与where的作用  以及if的作用

    <!--resultMap:结果集映射标签
        type:把结果集封装成对象的类型
        id:当前结果集映射的唯一标识
    
        在列名与属性名不一致时使用这两个标签进行转换
        column:数据库中的列名
        property:类中的属性名
    -->
        <resultMap id="myResultMap" type="User">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
            <result column="date" property="date"/>
            <result column="salary" property="salary"/>
        </resultMap>
    
        <!--  查询  -->
        <!--  where标签
        自动拼接里面的sql语句,当where里面没有成立的条件时,则什么都没有
        如果里面有条件成立,则自动为语句前加上where ,若语句为and开头,则自动删除and

        if标签
        if test="判断条件" 如果条件成立,则执行if中间的语句,与jstl用法相同
    -->
      
    <select id="find" resultMap="myResultMap"> select * from user <where> <if test="username !=null"> username = #{username} </if> <if test="id != null"> and id = #{id} </if> </where> </select>

    4、动态sql

      if  上面已经介绍过了

      choose 类似与java中的switch

    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG WHERE state = ‘ACTIVE’
      <choose>
        <when test="title != null">
          AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
          AND author_name like #{author.name}
        </when>
        <otherwise>
          AND featured = 1
        </otherwise>
      </choose>
    </select>

      where 上面已经介绍过了

      set

    <update id="update">
            update user
            <trim prefix="set" suffixOverrides=",">
                <if test="username!=null">
                    username=#{username},
                </if>
                <if test="password!=null">
                    password=#{password},
                </if>    
            </trim>
            where id=#{id}
    </update>
    <!--set原理与where很相似,set会自动处理语句后的逗号,如果语句以逗号结尾则会删掉逗号,以及会给语句前加上set关键字-->

      trim 

    <!--prefix:前缀,在返回的字符串前添加什么内容
        suffix:后缀,在饭后的字符串后添加什么内容
        prefixOverrides:当字符串以什么内容开头时,该内容会被覆盖
        suffixOverrides:当字符串以什么内容结尾时,该内容会被覆盖
    -->
    <trim prefix="" suffix="" prefixOverrides="" suffixOverrides="">
    
    </trim>
    
    
    <!--trim模仿where-->
    <trim prefix="where" prefixOverrides="and'></trim>
    <!--trim模仿set-->
    <trim prefix="set" suffixOverrides=","></trim>

      foreach

    <!--collection:遍历元素的类型
      item:遍历时每次的变量名
      index:每次的下标(从0开始计数)
      open:字符串开头添加
      close:字符串结尾添加
      separator:元素之间的分隔符-->
    <select id="selectPostIn" resultType="domain.blog.Post">
      SELECT *
      FROM POST P
      WHERE ID in
      <foreach item="item" index="index" collection="list"
          open="(" separator="," close=")">
            #{item}
      </foreach>
    </select>

    5、Sql语句中${}和#{}的区别  

      #{}:会吧参数的位置使用”?”做占位符,执行SQL的时候才会替换”?”的值

      ${}:直接把参数中的值作为SQL的一部分来执行 -----------> 可能会有SQL注入的问题

      如何选用?

        ${}:当插入的参数时作为SQL执行的一部分的时候必须使用${};

        #{}:当传入的参数时同数据库进行交互的时候,使用#{}.

      简单的判断:传入的参数在SQL中是否能够加上单引号 可以加单引号,使用#{},不能加单引号,使用${}

    6、多参数问题处理

      解决方案: 把多个对象封装成一个对象

      1、封装成一个javaBean对象

      2、封装成一个Map对象  将属性名设为Map的key,属性值设为value

      3、使用@param注解

  • 相关阅读:
    windows7环境下使用pip安装MySQLdb
    ZeroMQ
    LazyValue<T>
    方法执行失败,重复执行指定次数某个方法
    关于截取字符串substr和substring两者的区别
    C#的字符串优化-String.Intern、IsInterned
    几张图轻松理解String.intern()
    string 线程安全
    请问C#中string是值传递还是引用传递?
    C# String与StringBuilder
  • 原文地址:https://www.cnblogs.com/xfdhh/p/11443766.html
Copyright © 2011-2022 走看看