zoukankan      html  css  js  c++  java
  • mybatis

    mybatis 文档:https://mybatis.org/mybatis-3/zh/

    ##maven:pom.xml

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.3</version>
    </dependency>

     #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>
    <!--    可以配置两个环境development test default=xxx-->
        <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://localhost:3306/iqiyi?useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="howhy@123"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
    <!--        <mapper class="com.howhy.study.mapper.UserMapper"/>-->
            <package name="com.howhy.study.mapper"/>
        </mappers>
    </configuration>

    ##UserMapper.java接口 UserMapper.xml 文件名称路径必须一致
    ##UserMapper.java
    public interface UserMapper {
    
        public User findUserById(Integer id);
    }

    ##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">
    <mapper namespace="com.howhy.study.mapper.UserMapper">
    <select id="findUserById" resultType="com.howhy.study.domain.User">
        select * from account where id = #{id}
      </select>
    </mapper>


    ##mybatis日志
    ##pom.xml
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.20</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>


    ##logback.xml
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!-- 配置文件修改时重新加载,默认true -->
    <configuration scan="true">
        
        <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
        <property name="CATALINA_BASE" value="**/logs"></property>
        
        <!-- 控制台输出 -->
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder charset="UTF-8">
                <!-- 输出日志记录格式 -->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
     
        <!-- 第一个文件输出,每天产生一个文件 -->
        <appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- 输出文件路径+文件名 -->
                <fileNamePattern>${CATALINA_BASE}/aa.%d{yyyyMMdd}.log</fileNamePattern>
                <!-- 保存30天的日志 -->
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <encoder charset="UTF-8">
                <!-- 输出日志记录格式 -->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
     
        <!-- 第二个文件输出,每天产生一个文件 -->
        <appender name="FILE2" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${CATALINA_BASE}/bb.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${CATALINA_BASE}/bb.%d{yyyyMMdd}.log</fileNamePattern>
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <encoder charset="UTF-8">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        
        <appender name="CUSTOM" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>${CATALINA_BASE}/custom.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!-- daily rollover -->
                <fileNamePattern>${CATALINA_BASE}/custom.%d{yyyy-MM-dd}.log</fileNamePattern>
                <!-- keep 30 days' worth of history -->
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <encoder charset="UTF-8">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        
        <!-- 设置日志输出级别 -->
        <root level="ERROR">
            <appender-ref ref="CONSOLE" />
        </root>
        <logger name="file1" level="DEBUG">
            <appender-ref ref="FILE1" />
        </logger>
        <logger name="file1" level="INFO">
            <appender-ref ref="FILE2" />
        </logger>
        <!-- 自定义logger -->
        <logger name="custom" level="INFO">
            <appender-ref ref="CUSTOM" />
        </logger>
    </configuration>

    首先,如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就 OK 了。例如,如果上面的 Author 表已经在 id 列上使用了自动生成,那么语句可以修改为:

    <insert id="insertAuthor" useGeneratedKeys="true"
        keyProperty="id">
      insert into Author (username,password,email,bio)
      values (#{username},#{password},#{email},#{bio})
    </insert>

    如果你的数据库还支持多行插入, 你也可以传入一个 Author 数组或集合,并返回自动生成的主键。

    <insert id="insertAuthor" useGeneratedKeys="true"
        keyProperty="id">
      insert into Author (username, password, email, bio) values
      <foreach item="item" collection="list" separator=",">
        (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
      </foreach>
    </insert>

    对于不支持自动生成主键列的数据库和可能不支持自动生成主键的 JDBC 驱动,MyBatis 有另外一种方法来生成主键。

    这里有一个简单(也很傻)的示例,它可以生成一个随机 ID(不建议实际使用,这里只是为了展示 MyBatis 处理问题的灵活性和宽容度):

    <insert id="insertAuthor">
      <selectKey keyProperty="id" resultType="int" order="BEFORE">
        select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
      </selectKey>
      insert into Author
        (id, username, password, email,bio, favourite_section)
      values
        (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
    </insert>

    在上面的示例中,首先会运行 selectKey 元素中的语句,并设置 Author 的 id,然后才会调用插入语句。这样就实现了数据库自动生成主键类似的行为,同时保持了 Java 代码的简洁。

    selectKey 元素描述如下:

    <selectKey
      keyProperty="id"
      resultType="int"
      order="BEFORE"
      statementType="PREPARED">

    ##mybatis 参数传递 

    1、#{} jdbc预编译的方式?传参 可以防止sql注入   ${}  sql语句拼接的方式 有sql注入问题 一个参数 #{这里可以随便写} ${这里可以随便写} 

    2、多个参数:#{arg0} #{arg1}  或 #{param1} #{param2}   若dao层 参数没有注解@Param() 这两个方式都可以 若有注解@Param()只能使用#{param1} #{param2}

    3、参数是javaBean或map  单个参数可以直接使用#{属性名} 或#{param1} 多个参数可以使用:#{param1}  #{bean.属性} #{param1.属性} 

    4、参数是集合或数组  mybatis list会封闭成map {key:"list",value:"[1,2]"}   数组会封装成map {key:"array",value:"[1,2]"}如下 

      <select id="findUserByIds" resultType="com.howhy.study.domain.User">
        select * from account where id = #{list[0]} or id = #{list[1]}
      </select>
     <select id="findUserByIds" resultType="com.howhy.study.domain.User">
        select * from account where id = #{array[0]} or id = #{array[1]}
      </select>

    ##ResultMap

    <resultMap id="userResultMap" type="User">
      <id property="id" column="user_id" />
      <result property="username" column="user_name"/>
      <result property="password" column="hashed_password"/>
    </resultMap>
    然后在引用它的语句中设置 resultMap 属性就行了(注意我们去掉了 resultType 属性)。比如:
    
    <select id="selectUsers" resultMap="userResultMap">
      select user_id, user_name, hashed_password
      from some_table
      where id = #{id}
    </select>

     Mybatis缓存

    一级缓存:默认开启了

      1、若关闭:localCacheScope=STATEMENT

      2、缓存默认作用域是基于sqlSession的,一次数据库操作会话

      3、缓存默认实现类PerpetualCache,使用map进行存储的key的值是hashcode+sqlid+sql语句+hashcode+开发环境

           4、查询时就会缓存

      缓存失效的情况:

      1、不同的sqlSession会使一级缓存失效

      2、同一个sqlSession不同的sql查询语句

      3、同一个sqlSession和同样的sql查询语句但执行了其它的增删改的情况

      4、手动清空缓存

    二级缓存:默认也是开启的,但没有实现

       1、作用域是全局的,应用级的

       2、开启二级缓存 :<setting name="cacheEnabled" value="true"></setting>

       3、在需要用到二级缓存的映射文件mapper.xml中加入<cache></cache>,基于mapper映射文件来实现缓存的,基于mapper映射文件命名空间来存储的

       4、事务提交时才会缓存

            缓存失效:

       1、同一个命名空间进行增删改就会失效

      先从二级缓存中取 若二级缓存没有再从一级缓存中取









  • 相关阅读:
    bugku-web40
    buuctf-BabyUpload
    webpack4系列之 【1. webpack入门】
    webpack Cannot find module 'webpack/schemas/WebpackOptions.json'
    .gitignore无效解决方案以及git rm和rm的区别
    nginx启动或者重启失败,报错nginx: [error] open() "/usr/local/var/run/nginx.pid" failed (2: No such file or directory)
    vue-学习系列之vue双向绑定原理
    mac环境下配置nginx
    杂记
    更换淘宝源
  • 原文地址:https://www.cnblogs.com/howhy/p/14980533.html
Copyright © 2011-2022 走看看