乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      SpringBoot使用Mybatis注解開發(fā)教程--傳遞對象參數(shù)的用法

       wwq圖書世界 2019-08-05

      代碼示例可以參考個人GitHub項目kingboy-springboot-data

      一、環(huán)境配置

      1.引入mybatis依賴

          compile(
                  //SpringMVC
                  'org.springframework.boot:spring-boot-starter-web',
                  "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.3",
                  //Mybatis依賴及分頁插件
                  "org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1",
                  "com.github.pagehelper:pagehelper:4.1.0",
                  'mysql:mysql-connector-java'
          )
      

      2.數(shù)據(jù)源配置

      spring:
        datasource:
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql:///mybatis?characterEncoding=utf8&useSSL=false
          //根據(jù)resources目錄下的schema.sql自動建表,可省略
          schema: classpath:schema.sql
          //根據(jù)resources目錄下的data.sql自動插入假數(shù)據(jù),可省略
          data: classpath:data.sql
      

      3.分頁插件配置

      @Configuration
      public class CommonConfiguration {
      
          /**
           * 注冊MyBatis分頁插件PageHelper
           */
          @Bean
          public PageHelper pageHelper() {
              PageHelper pageHelper = new PageHelper();
              Properties p = new Properties();
              p.setProperty("offsetAsPageNum", "true");
              p.setProperty("rowBoundsWithCount", "true");
              p.setProperty("reasonable", "true");
              pageHelper.setProperties(p);
              return pageHelper;
          }
      
      }
      

      4.配置SpringBoot掃描Mybatis倉儲,有兩種配置方式

      • 在啟動類上加入@MapperScan,填寫Mapper接口所在的包名,SpringBoot就會自動將該包中的Mapper接口進行加載
      @MapperScan(basePackages = "com.kingboy.repository")
      @SpringBootApplication
      public class KingboySpringbootDataApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(KingboySpringbootDataApplication.class, args);
          }
      }
      
      • 在Mapper接口上加上@Mapper注解,SpringBoot就會自動夾在該Mapper接口
      @Mapper
      public interface UserMapper {
      
              @Insert("INSERT INTO `user` VALUES (#{id}, #{nickName}, #{phoneNumber}, #{sex}, #{age}, #{birthday}, #{status})")
              @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
              void saveUser(User user);
              
      }
      

      這兩種方式都可以,根據(jù)項目結(jié)構(gòu)進行選擇即可,也可以結(jié)合私用。

      5.配置駝峰屬性自動映射

      mybatis:
        configuration:
          map-underscore-to-camel-case: true
      

      例如實體中屬性為phoneNumber,數(shù)據(jù)庫屬性為phone_number,Mybatis默認是不能自動轉(zhuǎn)換的,通常我們要自定義以下結(jié)果集映射

      @Result(column = "phone_number", property = "phoneNumber")
      

      然而這樣很不方便,當我們加上以上配置之后,Mybatis在映射結(jié)果時,會自動轉(zhuǎn)換,去掉下劃線,變n為大寫N。

      6.設置mybatis日志打印,在配置文件中加入如下配置

      logging:
        level:
          #Mapper所在的包
          com.kingboy.repository: debug
      

      開啟日志有三種方式,可以參考我的另一篇博客SpringBoot開啟Mybatis的SQL日志

      二、Mybatis注解

      Mybatis提供了四個注解,先簡單了解一下,后面的完整示例中演示了相應的實例

      @Insert(“sql”) 增
      @Delete(“sql”) 刪
      @Update(“sql”) 改
      @Select(“sql”) 查

      三、方法參數(shù)讀取

      1.普通參數(shù)讀取

      在方法參數(shù)前使用@Param注解對參數(shù)進行標記,在sql中使用#{屬性名}來讀取屬性。

      示例

          //刪除用戶,根據(jù)用戶ID和名稱刪除用戶
          @Delete("DELETE FROM `user` WHERE id = #{id} AND nick_name = #{nickName}")
          void delete(@Param(value = "id") Long id, @Param(value = "nickName") String nickName);
      

      2.對象參數(shù)讀取

      直接在sql中使用#{屬性名}來讀取屬性

      示例

          @Insert("INSERT INTO `user` VALUES (#{id}, #{nickName}, #{phoneNumber}, #{sex}, #{age}, #{birthday}, #{status})")
          @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
          void saveUser(User user);
      

      這里補充一點,@Options注解和@Insert注解結(jié)合使用,可以將保存后的主鍵設置到user實體中。也就是說保存前user的id是沒值的,
      保存后mybatis會自動將數(shù)據(jù)庫中的主鍵設置到user的id屬性上,keyColumn = "id"為數(shù)據(jù)庫主鍵名,keyProperty = "id"為實體的主鍵屬性名。

      四、分頁插件的使用

      分頁插件單獨拿出來說,是因為項目實戰(zhàn)中發(fā)現(xiàn)很多同學都使用錯了,所以著重強調(diào)一下。

      分頁插件的核心類是PageHelper,這個類提供了很多的靜態(tài)方法,其中我們最常用的是PageHelper.startPage(int page, int size)這個方法,返回com.github.pagehelper.Page對象,
      該對象包含了包含了查詢結(jié)果result, 當前頁pageNum,每頁大小pageSize, 總條數(shù)total等信息,可以獲取這些信息返回給前端。需要注意的是,PageHelper的頁數(shù)是從1開始的。

      我們來看一段實際的代碼操作,這里就不寫service層了。

      //controller
      RestController
      @RequestMapping(value = "/user")
      public class UserController {
      
          @Resource
          UserRepository userRepository;
      
          @GetMapping
          @Transactional(readOnly = true)
          public Page get(@RequestParam Integer page, @RequestParam Integer size) {
              //分頁并查詢
              Page<User> pageInfo = PageHelper.startPage(page, size);
              List<User> users = userRepository.listUser();
      
              //獲取分頁信息演示, 實際項目中一般會封裝為自己的返回體。
              int pageNum = pageInfo.getPageNum();
              int pageSize = pageInfo.getPageSize();
              long total = pageInfo.getTotal();
              List<User> result = pageInfo.getResult();//和上面的users結(jié)果相同
      
              return pageInfo;
          }
      
      }
      
      
      
      //repository
      @Mapper
      public interface UserRepository {
          //分頁查詢用戶
          @Select("SELECT * FROM `user`")
          List<User> listUser();
      }
      
      

      五、動態(tài)標簽

      熟悉Mybatis的同學一定對Mybatis的動態(tài)SQL很了解,解決了我們編寫動態(tài)SQL的很多痛點。接下來介紹以下Mybatis常用的動態(tài)sql的注解寫法,其實和xml是幾乎完全一致的。

      首先在注解中使用動態(tài)sql時,我們需要為sql加上<script></script>標簽,這時候mybatis才會解析里面的標簽。

      1.<if test="條件判斷">sql</if>

      用來對參數(shù)進行判斷,若為真,則包裹的sql語句生效。條件中可以使用and作連接

          //分頁查詢用戶,如果sex有值,則查詢相應sex的所有用戶,sex沒值則查詢所有
          @Select("<script>SELECT * FROM `user` <if test='sex != null'>where sex = #{sex}</if><script>")
          List<User> listUser(Sex sex);//sex是一個枚舉類型,值為BOY,GIRL
      

      2.<foreach item = 'item' index = 'index' collection='list' separator=',', open='(', close=')'>sql</foreach>

      循環(huán)參數(shù)中的集合參數(shù)進行操作,和java中的for循環(huán)比較類似,不過多了open/close/separator三個參數(shù)。

      • open是在操作之前加上一個"("
      • close是在操作之后加上一個")"
      • separator是每個元素間的分割符

      需要注意的是,collection的值只能是list或者collection

      示例

          @Select("<script>"
                  + "SELECT * FROM `user` WHERE id in "
                  + "<foreach item='item' collection='list' open='(' close=')' separator=','>"
                  + "#{item}"
                  + "</foreach>"
                  + "</script>")
          List<User> listUserByIds(List<Long> ids);
      

      例如傳入的ids為[2,4,6]生成的sql如下:

      SELECT * FROM `user` WHERE id in ( 2 , 4, 6 ) 
      

      3.<set></set>

      更新實體屬性要用到的標簽,一般我們使用動態(tài)sql更新用戶信息update user set username = ?, age = ?,時要處理最后一個逗號的問題,那么使用set標簽就可以自動幫我們處理這個逗號。

      示例

          //使用set標簽進行動態(tài)set,要注意條件判斷:沒被刪除的用戶才可以更新數(shù)據(jù)
          @Update("<script>"
                  + "UPDATE `user` "
                  + "<set>"
                  + "<if test='nickName != null'>nick_name = #{nickName}, </if>"
                  + "<if test='age != null'>age = #{age}, </if>"
                  + "<if test='phoneNumber != null'>phone_number = #{phoneNumber}, </if>"
                  + "<if test='birthday != null'>birthday = #{birthday}, </if>"
                  + "<if test='status != null'>status = #{status}, </if>"
                  + "<if test='sex != null'>sex = #{sex}, </if>"
                  + "</set>"
                  + "WHERE id = #{id} AND status != 'DELETE';"
                  + "</script>")
          void updateUser(User user);
      

      4.<where></where>

      和更新數(shù)據(jù)時遇到的問題一樣,我們在動態(tài)查詢時也要動態(tài)拼接查詢條件,最前邊一個查詢條件是沒有AND或者OR的,以前通常使用1 = 1避開這個問題,那么現(xiàn)在可以使用標簽自動幫我們處理。

      示例

          /**
           * 根據(jù)條件查詢用戶
           * 注意其中nickName模糊查詢的處理方法
           * 注意其中關(guān)于生日的區(qū)間判斷, < >
           * @param userQueryDTO
           * @return
           */
          @Select("<script>"
                  + "SELECT * FROM `user`"
                  + "<where>"
                  + "<bind name='nickName' value=\"'%' + nickName + '%'\" />"
                  + "<if test='nickName != null'>AND nick_name like #{nickName}</if>"
                  + "<if test='phoneNumber !=null'>AND phone_number = #{phoneNumber}</if>"
                  + "<if test='sex !=null'>AND sex = #{sex}</if>"
                  + "<if test='age !=null'>AND age = #{age}</if>"
                  + "<if test='fromBirthday !=null'>AND birthday > #{fromBirthday}</if>"
                  + "<if test='toBirthday !=null'>AND birthday < #{toBirthday}</if>"
                  + "<if test='status !=null'>AND status = #{status}</if>"
                  + "</where>"
                  + "</script>")
          List<User> queryByCondition(UserQueryDTO userQueryDTO);
      

      5.<bind name='新屬性' value="'%' + 原屬性 + '%'" />

      在模糊查詢時,我們通常使用where name like %金%這樣的方式來進行查詢(當然這樣效率很低,不推薦),但是在mybatis里面我們直接寫where name like %#{name}%是不行的,
      會生成where name like %'金'%這樣的sql, 很明顯是不行的。有兩種方式可以處理。

      1)、傳入的屬性上加上%號,例如傳入的name就為%金%,這樣可以解決,但是不方便。

      2)、使用bind標簽,我們可以在sql中加入一行賦值操作<bind name='newName' value="'%' + name + '%'" />

      示例:參照上一個示例。

      6.<choose><when test='條件1'></when><when test='條件2'></when><otherwise></otherwise></choose>

      這個java中的switch比較像,如果條件1成立,就執(zhí)行條件1中的語句,剩下的不執(zhí)行。條件1不成立就判斷條件2,如果條件2還不成立就執(zhí)行otherwise中的sql。

      示例

          /**
           * 如果age有值,通過age查詢
           * 如果age沒有值,則通過sex查詢
           * 如果age和sex都沒值,則查詢所有status為UNLOCK的用戶
           * @param age
           * @param sex
           * @return
           */
          @Select("<script>"
                  + "SELECT * FROM `user`"
                  + "<where>"
                  + "<choose>"
                  + "<when test='age != null'>AND age = #{age}</when>"
                  + "<when test='sex != null'>AND sex = #{sex}</when>"
                  + "<otherwise>AND status = 'UNLOCK'</otherwise>"
                  + "</choose>"
                  + "</where>"
                  + "</script>")
          List<User> getByOrderCondition(@Param("age") Integer age, @Param("sex") Sex sex);
      

      六、完整示例

      其中的用戶實體等沒有貼出來,太亂了,完整示例代碼可以參考文章開頭的github項目。

      UserController

      package com.kingboy.controller.user;
      
      import com.github.pagehelper.Page;
      import com.github.pagehelper.PageHelper;
      import com.kingboy.common.utils.page.PageParam;
      import com.kingboy.common.utils.page.PageResult;
      import com.kingboy.common.utils.page.PageResultFactory;
      import com.kingboy.common.utils.result.ApiResult;
      import com.kingboy.domain.user.Sex;
      import com.kingboy.domain.user.Status;
      import com.kingboy.domain.user.User;
      import com.kingboy.dto.user.UserQueryDTO;
      import com.kingboy.repository.user.UserRepository;
      import org.springframework.transaction.annotation.Transactional;
      import org.springframework.web.bind.annotation.*;
      
      import javax.annotation.Resource;
      import java.util.List;
      
      /**
       * @author kingboy--KingBoyWorld@163.com
       * @date 2017/12/30 下午11:59
       * @desc 用戶接口.
       */
      @RestController
      @RequestMapping(value = "/user")
      public class UserController {
      
          @Resource
          UserRepository userRepository;
      
          @Resource
          PageResultFactory pageResultFactory;
      
          /**
           * 保存單個用戶
           * http://localhost:8080/user
           * {"nickName":"kingboy","age":"26","sex":"BOY","phoneNumber":"13132296607","birthday":"2011-12-12 12:12","status":"UNLOCK"}
           * @param user
           * @return
           */
          @PostMapping
          public ApiResult save(@RequestBody User user) {
              userRepository.saveUser(user);
              return ApiResult.success(user);
          }
      
          /**
           * 批量保存
           * http://localhost:8080/user/list
           * [
           * {"nickName":"kingboy","age":"26","sex":"BOY","phoneNumber":"13132296607","birthday":"2011-12-12 12:12","status":"UNLOCK"},
           * {"nickName":"kingboy","age":"26","sex":"BOY","phoneNumber":"13132296607","birthday":"2011-12-12 12:12","status":"UNLOCK"},
           * {"nickName":"kingboy","age":"26","sex":"BOY","phoneNumber":"13132296607","birthday":"2011-12-12 12:12","status":"UNLOCK"}
           * ]
           * @param users
           * @return
           */
          @PostMapping(value = "/list")
          public ApiResult save(@RequestBody List<User> users) {
              userRepository.saveUserList(users);
              return ApiResult.success(users);
          }
      
          /**
           * 更新單個用戶
           * http://localhost:8080/user
           * {"id":"1","nickName":"kingboy","age":"26","sex":"BOY","phoneNumber":"13132296607","birthday":"2011-12-12 12:12","status":"UNLOCK"}
           * @return
           */
          @PutMapping
          public ApiResult update(@RequestBody User user) {
              userRepository.updateUser(user);
              return ApiResult.success("success");
          }
      
          /**
           * 刪除用戶
           * http://localhost:8080/user/1
           * @return
           */
          @DeleteMapping("/{id}")
          public ApiResult remove(@PathVariable Long id) {
              //軟刪除
              userRepository.remove(id, Status.DELETE);
              //硬刪除
              //userRepository.delete(id);
              return ApiResult.success("success");
          }
      
          /**
           * 通過ID獲取用戶
           * http://localhost:8080/user/1
           * @return
           */
          @GetMapping("/{id}")
          public ApiResult get(@PathVariable Long id) {
              User user = userRepository.get(id);
              return ApiResult.success(user);
          }
      
          /**
           * 分頁查詢用戶集合
           * http://localhost:8080/user
           * 需要注意的是PageHelper是從1開始分頁,而Hibernate/Jpa是從0開始分頁的
           * @return
           */
          @GetMapping
          @Transactional(readOnly = true)
          public ApiResult get(@ModelAttribute PageParam pageParam) {
              //分頁并查詢
              Page<User> pageInfo = PageHelper.startPage(pageParam.getPage(), pageParam.getSize());
              List<User> users = userRepository.listUser();
      
              //實際使用時,最后一個參數(shù)傳入要轉(zhuǎn)換的類型DTO
              PageResult<User> result = pageResultFactory.createAndConvert(pageParam.getMybatisPage(), pageInfo.getTotal(), users, User.class);
              return ApiResult.success(result);
          }
      
          /**
           * 通過id集合查詢用戶,這里就不做分頁了。
           * http://localhost:8080/user/ids
           * [1,3]
           * @return
           */
          @PostMapping("/ids")
          public ApiResult getUserByIds(@RequestBody List<Long> ids) {
              List<User> users = userRepository.listUserByIds(ids);
              return ApiResult.success(users);
          }
      
          /**
           * 通過查詢條件賴查詢用戶,這里也不做分頁了
           * http://localhost:8080/user/query
           * {
           *   "nickName":"i",
           *   "fromBirthday":"1999-12-31 12:12",
           * }
           * @param userQueryDTO
           * @return
           */
          @PostMapping("/query")
          public ApiResult queryUser(@RequestBody UserQueryDTO userQueryDTO) {
              List<User> users = userRepository.queryByCondition(userQueryDTO);
              return ApiResult.success(users);
          }
      
          /**
           * 根據(jù)條件的順序來查詢用戶
           * http://localhost:8080/user/query?age=24
           * 演示choose標簽的用法:如果傳入age就按年齡查詢用戶,age沒有傳入就按照sex賴查詢用戶。如果兩者都沒有傳入,那就查詢所有status沒有凍結(jié)的用戶
           * 類似如下:
           * switch(value) {
           *     case age:
           *        //查詢age
           *        break;
            *     case sex:
           *        //查詢sex
           *        break;
           *     default:
           *        //查詢status
           *        break;
           * }
           */
          @GetMapping("/query")
          public ApiResult findUserByOrderCondition(@RequestParam(required = false) Integer age, @RequestParam(required = false) Sex sex) {
              List<User> users = userRepository.getByOrderCondition(age, sex);
              return ApiResult.success(users);
          }
      
      }
      
      

      UserRepository

      package com.kingboy.repository.user;
      
      import com.kingboy.domain.user.Sex;
      import com.kingboy.domain.user.Status;
      import com.kingboy.domain.user.User;
      import com.kingboy.dto.user.UserQueryDTO;
      import org.apache.ibatis.annotations.*;
      
      import java.util.List;
      
      /**
       * @author kingboy--KingBoyWorld@163.com
       * @date 2017/12/31 上午12:01
       * @desc 用戶倉儲.
       */
      public interface UserRepository {
      
          /**
           * 添加用戶
           * @Options返回在數(shù)據(jù)庫中主鍵,自動賦值到user的id字段中
           * keyProperty = "id"的默認值為id,可以省略
           */
          @Insert("INSERT INTO `user` VALUES (#{id}, #{nickName}, #{phoneNumber}, #{sex}, #{age}, #{birthday}, #{status})")
          @Options(useGeneratedKeys = true, keyColumn = "id", keyProperty = "id")
          void saveUser(User user);
      
          /**
           * 批量保存用戶
           * @param users
           */
          @Insert("<script>" +
                  "INSERT INTO `user` VALUES " +
                  "<foreach item = 'item' index = 'index' collection='list' separator=','>" +
                  "(#{item.id}, #{item.nickName}, #{item.phoneNumber}, #{item.sex}, #{item.age}, #{item.birthday}, #{item.status})" +
                  "</foreach>" +
                  "</script>")
          @Options(useGeneratedKeys = true)
          void saveUserList(List<User> users);
      
          //使用set標簽進行動態(tài)set,要注意條件判斷:沒被刪除的用戶才可以更新數(shù)據(jù)
          @Update("<script>"
                  + "UPDATE `user` "
                  + "<set>"
                  + "<if test='nickName != null'>nick_name = #{nickName}, </if>"
                  + "<if test='age != null'>age = #{age}, </if>"
                  + "<if test='phoneNumber != null'>phone_number = #{phoneNumber}, </if>"
                  + "<if test='birthday != null'>birthday = #{birthday}, </if>"
                  + "<if test='status != null'>status = #{status}, </if>"
                  + "<if test='sex != null'>sex = #{sex}, </if>"
                  + "</set>"
                  + "WHERE id = #{id} AND status != 'DELETE';"
                  + "</script>")
          void updateUser(User user);
      
      
          //刪除用戶,軟刪除
          @Update("UPDATE `user` SET status = #{status} WHERE id = #{id}")
          void remove(@Param(value = "id") Long id, @Param(value = "status") Status status);
      
          //刪除用戶,硬刪除
          @Delete("DELETE FROM `user` WHERE id = #{id}")
          void delete(@Param(value = "id") Long id);
      
          /**
           * 查詢用戶
           * 單個參數(shù)時,@Param注解可以省略
           * 在配置中指定了駝峰映射,所以@Results的結(jié)果映射可以省略,不是駝峰類型的仍然需要寫結(jié)果映射。
           */
          @Select("SELECT * FROM `user` WHERE id = #{id}")
          @Results({
                  @Result(column = "nick_name", property = "nickName"),
                  @Result(column = "phone_number", property = "phoneNumber")
          })
          User get(Long id);
      
          //分頁查詢用戶
          @Select("SELECT * FROM `user`")
          List<User> listUser();
      
          /**
           * 通過id集合查詢用戶
           * @param ids
           * @return
           */
          @Select("<script>"
                  + "SELECT * FROM `user` WHERE id in "
                  + "<foreach item='item' collection='list' open='(' close=')' separator=','>"
                  + "#{item}"
                  + "</foreach>"
                  + "</script>")
          List<User> listUserByIds(List<Long> ids);
      
          /**
           * 根據(jù)條件查詢用戶
           * 注意其中nickName模糊查詢的處理方法
           * 注意其中關(guān)于生日的區(qū)間判斷
           * @param userQueryDTO
           * @return
           */
          @Select("<script>"
                  + "SELECT * FROM `user`"
                  + "<where>"
                  + "<bind name='nickName' value=\"'%' + nickName + '%'\" />"
                  + "<if test='nickName != null'>AND nick_name like #{nickName}</if>"
                  + "<if test='phoneNumber !=null'>AND phone_number = #{phoneNumber}</if>"
                  + "<if test='sex !=null'>AND sex = #{sex}</if>"
                  + "<if test='age !=null'>AND age = #{age}</if>"
                  + "<if test='fromBirthday !=null'>AND birthday > #{fromBirthday}</if>"
                  + "<if test='toBirthday !=null'>AND birthday < #{toBirthday}</if>"
                  + "<if test='status !=null'>AND status = #{status}</if>"
                  + "</where>"
                  + "</script>")
          List<User> queryByCondition(UserQueryDTO userQueryDTO);
      
      
          /**
           * 如果age有值,通過age查詢
           * 如果age沒有值,則通過sex查詢
           * 如果age和sex都沒值,則查詢所有status為UNLOCK的用戶
           * @param age
           * @param sex
           * @return
           */
          @Select("<script>"
                  + "SELECT * FROM `user`"
                  + "<where>"
                  + "<choose>"
                  + "<when test='age != null'>AND age = #{age}</when>"
                  + "<when test='sex != null'>AND sex = #{sex}</when>"
                  + "<otherwise>AND status = 'UNLOCK'</otherwise>"
                  + "</choose>"
                  + "</where>"
                  + "</script>")
          List<User> getByOrderCondition(@Param("age") Integer age, @Param("sex") Sex sex);
      }
      
      

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多