• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • mybatis01-簡介

    標簽: mybatis  動態標簽

    0.拓展

    1.jdbc操作數據庫

    1.1 maven依賴

    <?xml version="1.0" encoding="UTF-8"?>
    <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>mybatis-study</artifactId>
            <groupId>com.myx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
        <packaging>jar</packaging>
        <artifactId>jdbc-demo</artifactId>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.2</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>4.1.19</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.6.1</version>
            </dependency><dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
        </dependencies>
    </project>
    

    1.2 java代碼

    import java.sql.*;
    
    /**
     * 描述:jdbc test
     * @author: myx
     * @date: 2019/1/7
     * 注意:本內容僅限于學習使用
     * Copyright  2019-myx. All rights reserved.
     */
    public class JdbcTest {
        public static void main(String[] args) {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            try {
                //加載數據庫驅動
                Class.forName("com.mysql.jdbc.Driver");
                //通過驅動管理類獲取數據庫鏈接
                connection = DriverManager.getConnection("jdbc:mysql://140.143.193.83:3306/mybatis-test?characterEncoding=utf-8","iot", "123456");
                //定義sql語句 ?表示占位符
                String sql = "select * from user where username = ?";
                //獲取預處理statement
                preparedStatement = connection.prepareStatement(sql);
                //設置參數,第一個參數為sql語句中參數的序號(從1開始),第二個參數為設置的參數值
                preparedStatement.setString(1, "myx");
                //向數據庫發出sql執行查詢,查詢出結果集
                resultSet = preparedStatement.executeQuery();
                //遍歷查詢結果集
                while(resultSet.next()){
                    System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                //釋放資源
                if(resultSet!=null){
                    try {
                        resultSet.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(preparedStatement!=null){
                    try {
                        preparedStatement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(connection!=null){
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    

    1.3 傳統 JDBC 的弊端

    • jdbc 底層沒有用連接池、操作數據庫需要頻繁的創建和關聯鏈接。消耗很大的資源
    • 寫原生的 jdbc 代碼在java中,一旦我們要修改sql的話,java需要整體編譯,不利于系 統維護
    • 使用 PreparedStatement預編譯的話對變量進行設置123數字,這樣的序號不利于維護
    • 返回 result 結果集也需要硬編碼。

    2.現階段數據訪問層框架

    在這里插入圖片描述

    2.什么是mybatis

    MyBatis 是一款優秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。

    2.1 參考手冊

    官網手冊

    2.2 mybatis架構

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-IZMA557Y-1575011562629)(WEBRESOURCE178f5c19efd4b84cb23d7bed9d918a38)]

    try {
        // 1.mybatis配置文件
        String resources = "mybatis.xml";
        // 2.獲取Reader對象
        Reader resourceAsReader = Resources.getResourceAsReader(resources);
        // 3.獲取SqlSessionFactoryBuilder
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsReader);
        // 4.創建對應的session
        SqlSession sqlSession = build.openSession();
        // 5.獲取對應的mapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        // 6.執行方法
        UserEntity user = userMapper.getUser(1);
        System.out.println("name:" + user.getName());
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    3.helloword(xml)

    官網教程

    4.mybatis全局注解詳解

    官網參考

    5.mybatis注解實現

    5.1 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>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://140.143.193.83:3306/mybatis-test"/>
                    <property name="username" value="iot"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!--xml方式-->
            <!--<mapper resource="mapper/UserMapper.xml"/>-->
            <!--注解方式-->
            <package name="com.myx.mybatis"></package>
        </mappers>
    </configuration>
    

    5.2 UserMapper

    import org.apache.ibatis.annotations.Select;
    
    /**
     * 描述:userMapper接口
     * @author: myx
     * @date: 2019/1/7
     * 注意:本內容僅限于學習使用
     * Copyright  2019-myx. All rights reserved.
     */
    public interface UserMapper {
        @Select("select * from user where id =#{id}")
        public User selectUser(int id);
    }
    

    6.Mybatis 之注解和 xml 優缺點

    • Xml:增加 xml 文件、麻煩、條件不確定、容易出錯,特殊字符轉義
    • 注釋:不適合復雜 sql,收集 sql 不方便,重新編譯

    7.Mybatis 之#與$區別

    7.1 #{}表示一個占位符號

    通過#{}可以實現preparedStatement向占位符中設置值,自動進行java類型和jdbc類型轉換,#{}可以有效防止sql注入。#{}可以接收簡單類型值或pojo屬性值。 如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。

    7.2 ${}表示拼接sql串

    通過${}可以將parameterType傳入的內容拼接在sql中且不進行jdbc類型轉換, pojoparameterType{}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,{}括號中只能是value。

    7.3 OGNL

    Object Graphic Navigation Language
    對象 圖 導航 語言

    它是通過對象的取值方法來獲取數據。在寫法上把get給省略了。
    比如:我們獲取用戶的名稱:

    • 類中的寫法:user.getUsername();
    • OGNL表達式寫法:user.username

    mybatis中為什么能直接寫username,而不用user.呢:因為在parameterType中已經提供了屬性所屬的類,所以此時不需要寫對象名。
    Mybatis使用ognl表達式解析對象字段的值,#{}或者${}括號中的值為pojo屬性名稱。

    8.Mybatis 之 parameterType 與 parameterMap 區別

    • parameterMap和resultMap類似,parameterMap通常應用于mapper中有多個參數要傳進來時,表示將查詢結果集中列值的類型一一映射到java對象屬性的類型上,在開發過程中不推薦這種方式。
    • parameterType直接將查詢結果列值類型自動對應到java對象屬性類型上,不再配置映射關系一一對應。

    9.Mybatis 之 resultType 與 resultMap 區別

    • 使用 resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功。
    • mybatis 中使用 resultMap 完成高級輸出結果映射(自定義映射)。

    10.mybatis插件

    10.1 官網簡介

    插件

    10.2 實現顯示sql插件

    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.BoundSql;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.ParameterMapping;
    import org.apache.ibatis.mapping.ParameterMode;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.session.Configuration;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
    import org.apache.ibatis.type.TypeHandlerRegistry;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    import java.util.Properties;
    import java.util.regex.Matcher;
    
    @Intercepts
            ({
                    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
                    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
            })
    public class SqlPrintInterceptor implements Interceptor{
    
        private static final Logger log = LoggerFactory.getLogger(SqlPrintInterceptor.class);
    
        private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
            Object parameterObject = null;
            if (invocation.getArgs().length > 1) {
                parameterObject = invocation.getArgs()[1];
            }
    
            long start = System.currentTimeMillis();
    
            Object result = invocation.proceed();
    
            String statementId = mappedStatement.getId();
            BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);
            Configuration configuration = mappedStatement.getConfiguration();
            String sql = getSql(boundSql, parameterObject, configuration);
    
            long end = System.currentTimeMillis();
            long timing = end - start;
            if(log.isInfoEnabled()){
                log.info("執行sql耗時:" + timing + " ms" + " - id:" + statementId + " - Sql:" );
                log.info("   "+sql);
            }
    
            return result;
        }
    
        @Override
        public Object plugin(Object target) {
            if (target instanceof Executor) {
                return Plugin.wrap(target, this);
            }
            return target;
        }
    
        @Override
        public void setProperties(Properties properties) {
        }
    
        private String getSql(BoundSql boundSql, Object parameterObject, Configuration configuration) {
            String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
            List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
            if (parameterMappings != null) {
                for (int i = 0; i < parameterMappings.size(); i++) {
                    ParameterMapping parameterMapping = parameterMappings.get(i);
                    if (parameterMapping.getMode() != ParameterMode.OUT) {
                        Object value;
                        String propertyName = parameterMapping.getProperty();
                        if (boundSql.hasAdditionalParameter(propertyName)) {
                            value = boundSql.getAdditionalParameter(propertyName);
                        } else if (parameterObject == null) {
                            value = null;
                        } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                            value = parameterObject;
                        } else {
                            MetaObject metaObject = configuration.newMetaObject(parameterObject);
                            value = metaObject.getValue(propertyName);
                        }
                        sql = replacePlaceholder(sql, value);
                    }
                }
            }
            return sql;
        }
    
        private String replacePlaceholder(String sql, Object propertyValue) {
            String result;
            if (propertyValue != null) {
                if (propertyValue instanceof String) {
                    result = "'" + propertyValue + "'";
                } else if (propertyValue instanceof Date) {
                    result = "'" + DATE_FORMAT.format(propertyValue) + "'";
                } else {
                    result = propertyValue.toString();
                }
            } else {
                result = "null";
            }
            return sql.replaceFirst("\\?", Matcher.quoteReplacement(result));
        }
    }
    

    11.MyBatis的動態SQL

    MyBatis的強大特性之一便是它的動態SQL,以前拼接的時候需要注意的空格、列表最后的逗號等,現在都可以不用手動處理了,MyBatis采用功能強大的基于OGNL的表達式來實現,下面主要介紹下。

    11.1 if標簽

    if是最常用的判斷語句,主要用于實現某些簡單的條件選擇。基本使用示例如下:

    <select id="queryAllUsersByName" resultType="com.example.springboot.mybatisxml.entity.User">
        select * from user where 1=1
        <if test="name != null and name != ''">
            and name = #{name}
        </if>
        <if test="age != null ">
            and age = #{age}
        </if>
    </select>
    

    11.2 where標簽

    上面的例子中使用了“1=1”,是為了避免后續條件不滿足時候報錯,那有沒有辦法避免這種寫法呢?
    當然有,就是接下來要說的,標簽會自動判斷如果包含的標簽中有返回值的話,就在sql中插入一個‘where’,如果where標簽最后返回的內容是以and 或者or開頭的,也會被自動移除掉,上面例子中換成“where”標簽后寫法如下:

    <select id="queryAllUsersByName" resultType="com.example.springboot.mybatisxml.entity.User">
        select * from user 
        <where>
            <if test="name != null and name != ''">
                and name = #{name}
            </if>
            <if test="age != null ">
                and age = #{age}
            </if>
        </where>
    </select>
    

    11.3 trim標簽

    trim的作用是去除特殊的字符串,它的prefix屬性代表語句的前綴,prefixOverrides屬性代表需要去除的哪些特殊字符串,prefixOverrides屬性會忽略通過管道分隔的文本序列(注意此例中的空格也是必要的),后綴的處理和前綴一樣。

    trim標簽的主要屬性如下

    • prefix:前綴覆蓋并增加其內容。
    • suffix:后綴覆蓋并增加其內容。
    • prefixOverrides:前綴判斷的條件。
    • suffixOverrides:后綴判斷的條件。

    舉兩個例子。

    • 使用前綴屬性
    <select id="queryAllUsersByName" resultType="com.example.springboot.mybatisxml.entity.User">
        select * from user
        <trim prefix="WHERE" prefixOverrides="AND |OR " >
            <if test="name != null and name != ''">
                and name = #{name}
            </if>
            <if test="sex != null ">
                or sex = #{sex}
            </if>
            <if test="age != null ">
                and age = #{age}
            </if>
        </trim>
    </select>
    
    • 使用后綴屬性
    <update id="update" parameterType="Object">
        UPDATE user
        <trim suffix=" SET " suffixOverrides=",">
            <if test="id != null ">id=#{id},</if>
            <if test="name != null ">name=#{name},</if>
            <if test="age != null ">age=#{age},</if>
        </trim>
        WHERE ID=#{id}
    </update>
    

    11.4 foreach標簽

    作用是遍歷集合,它能夠很好地支持數組和List、Set接口的集合的遍歷,往往和sql中的in組合比較多。

    foreach標簽的主要屬性如下

    • item:表示循環中當前的元素。
    • index:表示當前元素在集合的位置下標。
    • collection:配置list的屬性名等。
    • open和close:配置的是以什么符號將這些集合元素包裝起來。
    • separator:配置的是各個元素的間隔符。
    <select id="queryAllUsersByName" resultType="com.example.springboot.mybatisxml.entity.User">
        select * from user where id in
        <foreach item="id" index="index" collection="userList"
                 open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
    
    版權聲明:本文為qq_31463999原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/qq_31463999/article/details/103311186

    智能推薦

    【Mybatis01】實現縮小版銀行轉賬+分頁查詢功能

    一、實現轉賬 1.1 項目實現圖和結構圖 1.1.1 pojo實體類 !分頁查詢表 1.2 全局文件mybatis.xml的編寫 1.3 mapper.xml的編寫(用來進行查詢!!!) 1.3.1分析: (確保轉賬用戶的正確性)因為需要確認轉賬用戶的賬號密碼輸入正確,所以需要根據賬號和密碼進行表查詢并且拿出查出來的對象,以作后續的余額更改操作! (確保入帳用戶的正確性)同上述,查表,取出對象! ...

    mybatis01-簡介

    文章目錄 0.拓展 1.jdbc操作數據庫 1.1 maven依賴 1.2 java代碼 1.3 傳統 JDBC 的弊端 2.現階段數據訪問層框架 2.什么是mybatis 2.1 參考手冊 2.2 mybatis架構 3.helloword(xml) 4.mybatis全局注解詳解 5.mybatis注解實現 5.1 mybatis-config.xml 5.2 UserMapper 6.Myb...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    猜你喜歡

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    styled-components —— React 中的 CSS 最佳實踐

    https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...

    精品国产乱码久久久久久蜜桃不卡