mybatis笔记


核心:输入映射和输出映射


1 配置文件

新建java project 导入jar  写配置文件

SqlMapConfig.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>
        <!-- <properties resource=""></properties> -->
        <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/mybatis?useSSL=false" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>

        <!-- 配置要加载的mapper.xml -->
        <mappers>
         <mapper resource="sqlmap/UserMapper.xml"/>

        </mappers>
    </configuration>
log4j.properties
    # Global logging configuration
    log4j.rootLogger=DEBUG, stdout
    # Console output...
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n



        String resource="SqlMapConfig.xml";
        InputStream inputStream=Resources.getResourceAsStream(resource);
        SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession=sessionFactory.openSession();

        //查找
        User user=sqlSession.selectOne("test.FindUserById",10);
        System.out.println("user= "+user);


        //更新 要指明id
        User user_update=new User();
        user_update.setId(20);
        user_update.setUsername("宋江2");
        user_update.setAddress("梁山2");
        user_update.setBirthday(new Date());
        user_update.setDetail("首领2");
        user_update.setScore(66.7f);
        user_update.setSex("1");
        sqlSession.insert("test.insertUser", user_update);
        sqlSession.commit();
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="test">

        <!-- 根据用户id查询用户信息  编写statement
        parameterType:指定传入数据参数的类型
        resultType:映射生成的java对象类型,select查询结果集的列名要和resultType指定java对象的属性名保持一致才可以映射
        #{}:表示占位符,如果要传递简单类型数据,#{}可以写任意名称
         -->
         <select id="FindUserById" parameterType="java.lang.Integer"
          resultType="com.mybatis.po.User">
          SELECT * FROM USER WHERE ID=#{VALUE}
         </select>

          <!-- 用户插入  传用户类型的对象(user), 传入的是user对象,#{}中写user对象的属性名  -->
         <insert id="insertUser" parameterType="com.mybatis.po.User">
            <!-- 将自增主键返回到user对象
          keyProperty:返回到user对象中的属性名
         order:返回主键的时机
         LAST_INSERT_ID:通过此函数获取自增主键值
          -->
            <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
                SELECT LAST_INSERT_ID();
            </selectKey>

            insert into user(username,birthday,sex,address,detail,score) values(
            #{username},#{birthday},#{sex},#{address},#{detail},#{score})
         </insert>

         <!-- 删除 传入数据 java.lang.Integer -->
         <delete id="deleteUserById" parameterType="java.lang.Integer">
            DELETE FROM USER WHERE ID=#{ID}
         </delete>

         <!-- 更新  传入参数 com.mybatis.po.User -->
         <update id="updateUser" parameterType="com.mybatis.po.User">
         update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address},detail=#{detail},score=#{score}
         where id=#{id}
         </update>
     </mapper>
<?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>
    <!-- properties -->
    <properties resource="db.properties"></properties> 
    <!-- 自定义别名 -->
    <typeAliases>
     <!--  <typeAlias type="com.mybatis.po.User" alias="user"/> -->
     <!--批量别名定义,扫描整个包下的类 -->
      <package name="com.mybatis.po"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>

    <!-- 配置要加载的mapper.xml -->
    <mappers>
         <mapper resource="sqlmap/UserMapper.xml"/>
         <!-- <mapper resource="sqlmap/mapper/UserMapper.xml"/> -->

        <!-- 接口与xml文件名称一致,且在同一个目录。接口即mapper命名空间 -->
        <!-- <mapper class="com.mybatis.dao.mapper.UserMapper"/> -->

        <!-- 注册指定包下的所有mapper接口。mapper接口和mapper映射文件名称相同且在同一个目录 -->
        <package name="com.mybatis.dao.mapper" />
    </mappers>
</configuration>

2 SqlSession

SqlSession
    SqlSession中封装了对数据库的sql操作,如:查询、插入、更新、删除等。
    通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。

    SqlSessionFactoryBuilder
    SqlSessionFacoty是通过SqlSessionFactoryBuilder进行创建,SqlSessionFactoryBuilder只用于创建SqlSessionFactory,可以当成一个工具类,在使用时随时拿来使用不需要特殊处理为共享对象。

    SqlSessionFactory
    SqlSessionFactory是一个接口,接口中定义了openSession的不同方式,SqlSessionFactory一但创建后可以重复使用,实际应用时通常设计为单例模式。

    SqlSession
    SqlSession是一个接口,默认使用DefaultSqlSession实现类,sqlSession中定义了数据库操作。


namespace的作用(mapper接口地址即namespace,接口的方法即mapper的id,参数、返回值都相同)
    使用mapper接口不用写接口实现类即可完成数据库操作,简单方便,此方法为官方推荐方法。
    使用mapper接口调用必须具备如下条件:
    1、    Mapper接口方法名和mapper.xml中定义的每个sql的id相同
    2、    Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
    3、    Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
    4、    Mapper.xml文件中的namespace即是mapper接口的类路径。

    至此,mybatis的mapper包括mapper.xml和mapper接口两种文件。
<?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命名空间,接口方法即mapper的id。利用动态代理产生对象 -->
<mapper namespace="com.mybatis.dao.mapper.UserMapper">
<!-- sql片段,以表为单位进行抽取 -->
<sql id="query_user_where">
    <if test="ids !=null">
            <!-- <foreach collection="ids" index="index" item="item" open="and id in(" 
            separator="," close=")">
              #{item}
            </foreach> -->
            <foreach collection="ids" index="index" item="item" open="and (" 
            separator="or" close=")">
              id=#{item}
            </foreach>

        </if>
      <if test="username !=null and username!=''">
          and username like '${username}%'
      </if>
      <if test="sex !=null and sex !=''">
           and sex=#{sex}
      </if>
      <if test="id >0">
           and id>#{id}
      </if>
</sql>

    <!-- 根据用户id查询用户信息  编写statement
    parameterType:指定传入数据参数的类型
    resultType:映射生成的java对象类型,select查询结果集的列名要和resultType指定java对象的属性名保持一致才可以映射
    #{}:表示占位符,如果要传递简单类型数据,#{}可以写任意名称
     -->
     <select id="findUserById" parameterType="java.lang.Integer"
      resultType="user">
      SELECT * FROM USER WHERE ID=#{VALUE}
     </select>

      <!-- 查询用户列表,根据用户名称模糊查询
     ${}:将传参数不加任何修饰将传的值拼接在sql中
      -->
     <select id="findUserList" parameterType="String" resultType="user">
    select * from user where username like '${value}%' 

     </select>

     <select id="findUserByUser" parameterType="user" resultType="user">
     <!--     select * from user where username like '${username}%' and sex=#{sex}  -->
         select * from user
         <where>
             <include refid="query_user_where"></include>
         </where>
     </select>

       <!--   返回resultMap -->
     <select id="findUserResultMap" parameterType="user" resultMap="userListMap">
         select username username_,sex sex_,birthday from user
         <where>
             <include refid="query_user_where"></include>
         </where>
     </select>

     <!-- 定义resultMap -->
     <resultMap type="user" id="userListMap">
         <id column="username_" property="username"/>
         <result column="sex_" property="sex"/>
         <result column="birthday_" property="birthday"/>
     </resultMap>

     <select id="findUserByMap" parameterType="hashMap" resultType="user">
         select * from user where username like '${username}%' and sex=#{sex} 
     </select>

     <select id="selectUserCount" parameterType="user" resultType="int">
     <!--     select count(*) from user where username like '${username}%' and sex=#{sex}  -->
     select count(*) from user 
     <where>
         <include refid="query_user_where"></include>
     </where>
     </select>

     <!-- 传入user,返回map -->
     <select id="findUserByUserReturnMap" parameterType="user" resultType="hashMap">
         select * from user where username like '${username}%' and sex=#{sex}
     </select>
      <!-- 用户插入  传用户类型的对象(user), 传入的是user对象,#{}中写user对象的属性名  -->
     <insert id="insertUser" parameterType="com.mybatis.po.User">
        <!-- 将自增主键返回到user对象
      keyProperty:返回到user对象中的属性名
     order:返回主键的时机
     LAST_INSERT_ID:通过此函数获取自增主键值
      -->
         <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
             SELECT LAST_INSERT_ID();
         </selectKey>

         insert into user(username,birthday,sex,address,detail,score) values(
         #{username},#{birthday},#{sex},#{address},#{detail},#{score})
     </insert>

     <!-- 删除 传入数据 java.lang.Integer -->
     <delete id="deleteUserById" parameterType="java.lang.Integer">
         DELETE FROM USER WHERE ID=#{ID}
     </delete>

     <!-- 更新  传入参数 com.mybatis.po.User -->
     <update id="updateUser" parameterType="com.mybatis.po.User">
     update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address},detail=#{detail},score=#{score}
     where id=#{id}
     </update>
 </mapper>

3 一对多查询

 <!-- user-orders 一对一查询,association -->
<resultMap type="com.mybatis.po.Orders" id="ordersUserMap">
     <!-- id 是主键,不会重复。
     即sql语句一对多会查询出id重复的语句
     但是mybatis优化后,一对多的一当中的orderdetails的不会重复-->
    <id column="id" property="id"/>
    <result column="user_id" property="user_id"/>
    <result column="order_number" property="order_number"/>
    <!-- 一对一 association 使用javaType -->
    <association property="user" javaType="com.mybatis.po.User">
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
    </association>
</resultMap>

<!-- orders-orderdetail 一对多查询 -->
<resultMap type="com.mybatis.po.Orders" id="ordersUserOrderdetailResultMap" extends="ordersUserMap"> 
<!-- <resultMap type="java.util.LinkedHashMap" id="ordersUserOrderdetailResultMap">  -->
    <!--     
        一对多查询 。使用collection ofType
       property="orderdetails":关联查询的结果集存储在Orders上哪个属性。
    ofType="com.mybatis.po.Orderdetail":指定关联查询的结果集中的对象类型即List中的对象类型。 
    -->
    <collection property="orderdetails" ofType="com.mybatis.po.Orderdetail">
        <id column="orderdetail_id" property="id"/>
        <result column="item_id" property="item_id"/>
        <result column="item_num" property="item_num"/>
        <result column="item_price" property="item_price"/>
    </collection>

</resultMap>

<!-- Orders-Items 多对多 -->
<resultMap type="com.mybatis.po.Orders" id="ordersItemsResultMap"  extends="ordersUserMap"> 
    <!--     
        一对多查询 。使用collection ofType
       property="orderdetails":关联查询的结果集存储在Orders上哪个属性。
    ofType="com.mybatis.po.Orderdetail":指定关联查询的结果集中的对象类型即List中的对象类型。 
    -->
    <collection property="orderdetails" ofType="com.mybatis.po.Orderdetail">
        <id column="orderdetail_id" property="id"/>
        <result column="item_id" property="item_id"/>
        <result column="item_num" property="item_num"/>
        <result column="item_price" property="item_price"/>

        <!-- Orderdetail-Items 一对一 -->
        <association property="items" javaType="com.mybatis.po.Items">
        <id column="item_id" property="id"/>
        <result column="item_price_" property="item_price"/>
        <result column="item_name" property="item_name"/>
        <result column="item_detail" property="item_detail"/>
        </association>
    </collection>
</resultMap>

4 缓存

<!-- 延迟加载 -->
<resultMap type="orders" id="oredersMap">
    <id column="id" property="id"/>
    <result column="user_id" property="user_id"/>
    <result column="order_number" property="order_number"/>
    <association property="user" javaType="user"
    select="com.mybatis.dao.mapper.UserMapper.findUserById" column="user_id"></association>
</resultMap>


    <!-- properties -->
    <properties resource="db.properties"></properties> 
    <!-- 延迟加载 -->
    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>


二级缓存:
    二级缓存范围可以跨越session,在mapper.xml中同一个namespace范围使用二级缓存。

    配置:
    通过配置开启二级缓存。

    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>

    还需要在mapper.xml配置,表示要对该mapper.xml进行二级缓存。
    在mapper.xml配置:
     <cache />

    对映射的pojo,实现序列化接口。
    应用场景(重点):    1、针对复杂的查询或统计的功能,用户不要求每次都查询到最新信息,使用二级缓存,通过刷新间隔flushInterval设置刷新间隔时间,由mybatis自动刷新。
    比如:实现用户分类统计sql,该查询非常耗费时间。
    将用户分类统计sql查询结果使用二级缓存,同时设置刷新间隔时间:flushInterval(一般设置时间较长,比如30分钟,60分钟,24小时,根据需求而定)

    2、针对信息变化频率高,需要显示最新的信息,使用二级缓存。
    将信息查询的statement与信息的增、删、改定义在一个mapper.xml中,此mapper实现二级缓存,当执行增、删、修改时,由mybatis及时刷新缓存,满足用户从缓存查询到最新的数据。
    比如:新闻列表显示前10条,该查询非常快,但并发大对数据也有压力。 
    将新闻列表查询前10条的sql进行二级缓存,这里不用刷新间隔时间,当执行新闻添加、删除、修改时及时刷新缓存。

results matching ""

    No results matching ""