终于,本:herb::baby_chick:结束了长达一个多月的DDL战争,重拾旧爱。

接下来几天要开始按照 Mybatis -> Spring -> Spring MVC 的流程爬一遍!

img


一、 XML 配置 与基础 CURD 的 XML 实现

Maven XML dependencies 配置
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <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.4</version>
    </dependency>
</dependencies>
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>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatisdb"/>
                <property name="username" value="***"/>
                <property name="password" value="***"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mybatis\dao\IUserMapper.xml"/>
    </mappers>
</configuration>
IUserMapper.xml (这是我自己写的项目中的 IUserMapper 的配置)
<?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="mybatis.dao.IUserDao">
    <select id="findAll" resultType="mybatis.entity.User">
        select * from User
    </select>

    <select id="findById" resultType="mybatis.entity.User" parameterType="Integer">
        select * from User where id=#{uid}
    </select>

    <delete id="removeById" parameterType="Integer">
        delete from User where id=#{uid}
    </delete>

    <insert id="insertUser" parameterType="mybatis.entity.User">
        <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="Integer">
            select last_insert_id()
        </selectKey>
        insert into User(username, address, sex, birthday) values (#{username}, #{address}, #{sex}, #{birthday})
    </insert>

    <update id="updateById" parameterType="mybatis.entity.User">
        update user set username=#{username}, birthday=#{birthday}, address=#{address}, sex=#{sex} where id=#{id}
    </update>

    <select id="findByIdQueryVo" resultType="mybatis.entity.User" parameterType="Integer">
        select * from User where id=#{user.uid}
    </select>
</mapper>
Dao 类实现(同样也是例子)
public interface IUserDao {
    List<User> findAll();

    User findById(Integer id);

    void removeById(Integer id);

    void insertUser(User user);

    void updateById(User user);

    User findByIdQueryVo(Integer id);
}

二、 延时加载 (懒加载)

<resultMap id="userMap" type="user">
  <id property="id" column="id"/>
  <id property="username" column="username"/>
  <id property="sex" column="sex"/>
  <id property="birthday" column="birthday"/>
    
    <!-- 懒加载部分 -->
  <assoociation property="bill" colume="bid" javaType="bill" select="*.findById"/>
</resultMap>
    
<select id="findAll" resultMap="userMap">
  select * from user
</select>

<select id="findById" resultType="bill">
  select * from bills where id = #{bid}
</select>

同时还需要开启延迟加载的开关

<settings>
  <!-- 懒加载开启 -->
  <setting name="lazyLoadingEnabled" value="true"/>
  
  <!-- 按需加载 -->
  <setting name="aggressiveLazyLoading" value="false"/>
</settings>

三、 缓存

减小和数据库的交互次数,提升效率。

缓存目标数据:

  • 经常查询的数据
  • 不经常改变的数据
  • 数据的正确与否对最终结果影响不大
    • 例如银行数据之类的,股市数据之类的都不能用缓存,查询之间不允许有延迟,必须时刻保证数据真实性。
多级缓存
  • 一级缓存

    • 每次执行查询之后,SqlSession 会为我们提供一块区域来进行缓存。

    • 例如,短时间内查询两个相同的对象,那么这两个将会共享同一个内存空间。两者的 reference 相等。

    • 当 SqlSession 对象使用 clearCache 方法清空缓存之后,将不会有一级缓存。

    • 调用 update 方法之后它也会清空一级缓存。

  • 二级缓存

    • 指的 Mybatis 中 SqlSessionFactory 的缓存。

    • 各种由该 SqlSessionFactory 生产的 SqlSession 都共享该缓存。

    • 配置方式:

      • Mybatis 框架支持二级缓存

        <settings>
          <setting name="cacheEnabled" value="true"/>
        </settings>
        
      • 映射文件支持二级缓存

      • 操作支持二级缓存

        <mapper>
            <cache/>
            <select useCache="true">
              select * from user
            </select>
        </mapper>
        
    • 创建新对象,但是不查询。


四、 注解开发

对于CRUD来说一共有四个注解,@Select, @Insert, @Update, @Delete

CRUD: Create, Retrieve, Update, Delete

注解与 xml 不能同时存在!

注解在 Dao 文件中的表现形式:

public interface IUserDao{
    
    @Select("select * from User where id=#{id}")
    @Results(id="userMap", 
            value={
                @Result(id=true, colume="id", property="userId"),
                @Result(colume="username", property="userName")
            })
    List<User> findUser(Integer id);
    
    @Select("select * from User")
    @ResultMap(value={"userMap", })
    List<User> findAllUser();
}
一对一查询

通常使用 EAGER。

public interface IAccountDao{
    
    @Select("select * from account")
    @Results(id="accountMap", 
            value={
                @Result(id=true, colume="id", property="Id"),
                @Result(colume="uid", property="uid"),
                @Result(property="user", column="uid", one=@One(select="*.IUserDao.findUser", 
                                                                fetchType=FetchType.EAGER))
            })
    List<Account> findAccount(Integer id);
}
一对多查询

通常使用 LAZY。

public interface IAccountDao{
    
    @Select("select * from account")
    @Results(id="accountMap", 
            value={
                @Result(id=true, colume="id", property="Id"),
                @Result(colume="uid", property="uid"),
                @Result(property="user", column="uid", many=@Many(select="*.IUserDao.findUser", 
                                                                fetchType=FetchType.LAZY))
            })
    List<Account> findAccount(Integer id);
}
二级缓存
public interface IAccountDao{
    
    @Select("select * from account")
    @Results(id="accountMap", 
            value={
                @Result(id=true, colume="id", property="Id"),
                @Result(colume="uid", property="uid"),
                @Result(property="user", column="uid", many=@Many(select="*.IUserDao.findUser", 
                                                                fetchType=FetchType.LAZY))
            })
    List<Account> findAccount(Integer id);
}