Mybatis基础巩固(从放弃到找回自信)

一.快速查找学习地址

1.mybatis 源码地址: https://gitee.com/weixinmayun/mycode

2.mybatis 官方学习文档地址:http://www.mybatis.org/mybatis-3/

3.maven 导入相关坐标的地址:https://mvnrepository.com/

二.Mybatis环境搭建注意事项

1.自己写的xml文件没有在mybatis主配置文件注册

会报如下错误:

org.apache.ibatis.binding.BindingException: Type interface com.my.dao.UserDao is not known to the MapperRegistry.

解决办法在:核心配置文件注册mappers

例如: mybatis-config.xml主配置文件添加如下代码:(注意:以自己的工程名为主)

<!--每一个mapper.xml都需要注册-->

    <mappers>

        <mapper resource="com/my/dao/UserMapper.xml"/>

    </mappers>

2.当resultMap和resultType弄混了是会报如下错误:
java.lang.IllegalArgumentException: Result Maps collection does not contain value for com.yang.domain.TArticle

3.当返回值类型错误或返回值类型起的别名没对应上,会报如下错误:

org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/yang/mapper/TCommentMap.xml
### The error occurred while processing mapper_resultMap[articleMap]
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper 

4.Maven导出资源问题

Maven工程当无法导出静态资源

解决办法:maven工程的pom.xml 添加如下代码:

    <!--在build中配置resources,来防止我们资源导出失败的问题-->

    <build>

        <resources>

            <resource>

                <directory>src/main/resources</directory>

                <includes>

                    <include>**/*.properties</include>

                    <include>**/*.xml</include>

                </includes>

                <filtering>true</filtering>

            </resource>

            <resource>

                <directory>src/main/java</directory>

                <includes>

                    <include>**/*.properties</include>

                    <include>**/*.xml</include>

                </includes>

                <filtering>true</filtering>

            </resource>

        </resources>

    </build>

 

三.配置文件深入解析

1.Mybatis的核心配置 (官网示例图)

  

2. 属性properties

    实际开发中,习惯将数据源的配置信息单独抽取成一个jdbc.properties文件,该标签可以加载额外配置的 properties:

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql:///mybatis_db

jdbc.username=root

jdbc.password=root

然后在mybatis主配置xml文件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>

 

    <!--加载properties文件-->

    <properties resource="jdbc.properties"></properties>

    <settings>

        <!--开启全局延迟加载功能-->

        <setting name="lazyLoadingEnabled" value="false"/>

        <!--所有方法都会延迟加载-->

        <setting name="lazyLoadTriggerMethods" value="toString()"/>

        <!-- 因为cacheEnabled的取值默认就为true所以这一步可以省略不配置

       true代表开启二级缓存false代表不开启二级缓存 -->

        <setting name="cacheEnabled" value="true"/>

    </settings>

    <!--设置别名-->

    <typeAliases>

        <!--方式一:给单个实体起别名-->

       <!-- <typeAlias type="com.yang.domain.User" alias="user"></typeAlias>-->

        <!--方式二:批量起别名 别名就是类名,且不区分大小写-->

        <package name="com.yang.domain"/>

    </typeAliases>

    <!--environments: 运行环境-->

    <environments default="development">

        <environment id="development">

                <!--当前的事务事务管理器是JDBC-->

            <transactionManager type="JDBC"></transactionManager>

                <!--数据源信息 POOLED:使用mybatis的连接池-->

            <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>

    <!--引入映射配置文件-->

    <mappers>

       <!--<mapper resource="com/yang/mapper/UserMapper.xml"></mapper>-->

        <!--使用该方式:接口和映射文件需要同包同名-->

       <!-- <mapper class="com.yang.mapper.UserMapper"></mapper>-->

        <!--批量加载映射-->

        <package name="com.yang.mapper"/>

    </mappers>

</configuration>

3.置Settings

官网参数连接: https://mybatis.org/mybatis-3/zh/configuration.html#settings

具体用法mybatis主配置xml文件mybatis-config.xml 中引入如下代码:

 

    <settings>

        <!--开启全局延迟加载功能-->

        <setting name="lazyLoadingEnabled" value="false"/>

        <!--所有方法都会延迟加载-->

        <setting name="lazyLoadTriggerMethods" value="toString()"/>

        <!--因为cacheEnabled的取值默认就为true所以这一步可以省略不配置

       true代表开启二级缓存false代表不开启二级缓存-->

        <setting name="cacheEnabled" value="true"/>    

</settings>

 

4. typeAliases标签

官网参数详解: https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases

具体用法在mybatis主配置xml文件mybatis-config.xml中引入如下代码:

 

    <!--设置别名-->

    <typeAliases>

        <!--方式一:给单个实体起别名-->

       <!-- <typeAlias type="com.yang.domain.User"       alias="user"></typeAlias>-->

        <!--方式二:批量起别名 别名就是类名,且不区分大小写-->

        <package name="com.yang.domain"/>

    </typeAliases>

例如:原来的类型名称配置如下

<select id="findAll" resultType="com.yang.domain.User">

select * from User

</select>

设置了typeAliases,com.yang.domain.User定义别名为User, 使代码更简洁。

5.environments标签

数据库环境的配置,支持多环境配置

 

6.映射器mappers

该标签的作用是加载映射的,加载方式有如下几种:

 <!--引入映射配置文件-->

  <mappers>

1. <!--使用该方式:接口和映射文件需要同包同名-->

<mapper resource="com/yang/mapper/UserMapper.xml"></mapper>

2. 使用完全限定资源定位符URL),例如

<mapper url="file:///var/mappers/userMapper.xml"/>

3.   <!--批量加载映射-->

   <package name="com.yang.mapper"/>

</mappers>

(:通俗的说就是把每接口对应的xml文件需要在mybatis主配置文件注册下,才能加载到)

7.Mybaits生命周期

         

 

声明周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoryBuilder:一旦创建了SqlSessionFactory,就不再需要它了

局部变量SqlSessionFactory:说白了就可以想象为,数据库连接池.

SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建一个实例。

因此SqlSessionFactory的最佳作用域是应用作用域(ApplocationContext)。

最简单的就是使用单例模式或静态单例模式。

SqlSession:连接到连接池的一个请求

SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。用完之后需要赶紧关闭,否则资源被占用!

四.解决属性名和字段名不一致

使用resultMap,使数据库字段和实体类,对应起来。

 

<resultMap id="UserMap" type="User">

    <!--column数据库中的字段,property实体类中的属性-->

    <result column="id" property="id"></result>

    <result column="name" property="name"></result>

    <result column="pwd" property="password"></result>

</resultMap>

 

<select id="getUserList" resultMap="UserMap">

    select * from USER

</select>

 

五.Mybaits分页用法

MyBatis可以使用第三方的插件来对功能进行扩展分页助手PageHelper是将分页的复杂操作进行封

使用简单的方式即可获得分页的相关数据

开发步骤

导入通用PageHelper的坐标

mybatis核心配置文件中配置PageHelper插件

测试分页数据获取

1. 导入通用PageHelper坐标

<!-- 分页助手-->

<dependency>

<groupId>com.github.pagehelper</groupId>

<artifactId>pagehelper</artifactId>

<version>3.7.5</version>

</dependency>

<dependency>

<groupId>com.github.jsqlparser</groupId>

<artifactId>jsqlparser</artifactId>

<version>0.9.1</version>

</dependency>

 2. 在mybatis核心配置文件中配置PageHelper插件

<!-- 分页助手的插件-->

<plugin interceptor="com.github.pagehelper.PageHelper">

<!-- 指定方言-->

<property name="dialect" value="mysql"/>

</plugin>

 

3. 测试分页代码实现

@Test

public void testPageHelper(){

//设置分页参数

PageHelper.startPage(1,2);// Mybaits很强大这行代码加在查询的列表上面就可以分页

List<User> select = userMapper2.select(null);

for(User user : select){

System.out.println(user);

}

}

 

获得分页相关的其他参数

//其他分页的数据

PageInfo<User> pageInfo = new PageInfo<User>(select);

System.out.println("总条数:"+pageInfo.getTotal());

System.out.println("总页数:"+pageInfo.getPages());

System.out.println("当前页:"+pageInfo.getPageNum());

System.out.println("每页显示长度:"+pageInfo.getPageSize());

System.out.println("是否第一页:"+pageInfo.isIsFirstPage());

System.out.println("是否最后一页:"+pageInfo.isIsLastPage());

 

 

六.联合查询

1.联合查询MyBatis多表配置方式

 

* 多对一一对一配置使用<resultMap>+<association>做配置

* 一对多配置使用<resultMap>+<collection>做配置

* 多对多配置使用<resultMap>+<collection>做配置

* 多对多的配置跟一对多很相似难度在于SQL语句的编写

2.一对一联合查询代码详解

例如一个订单从属一个用户,(一对一)

SELECT * FROM orders o LEFT JOIN USER u ON o.`uid`=u.`id`;

实体:

public class Order {

private Integer id;

private Date ordertime;

private double money;

// 表示当前订单属于哪个用户

private User user;

}

OrderMapper接口

public interface OrderMapper {

public List<Order> findAllWithUser();

}

OrderMapper.xml映射

<resultMap id="orderMap" type="com.yang.domain.Order">

<id column="id" property="id"></id>

<result column="ordertime" property="ordertime"></result>

<result column="money" property="money"></result>

<!--

一对一多对一使用association标签关联

property="user" 封装实体的属性名

javaType="user" 封装实体的属性类型

-->

<association property="user" javaType="com.yang.domain.User">

<id column="uid" property="id"></id>

<result column="username" property="username"></result>

<result column="birthday" property="birthday"></result>

<result column="sex" property="sex"></result>

<result column="address" property="address"></result>

</association>

</resultMap>

3.一对多联合查询

一个用户有多个订单

一对多查询语句:

SELECT *,o.id oid FROM USER u LEFT JOIN orders o ON u.`id` = o.`uid`;

 

User实体

public class User {

private Integer id;

private String username;

private Date birthday;

private String sex;

private String address;

// 代表当前用户具备的订单列表

private List<Order> orderList;

}

UserMapper接口

public interface UserMapper {

public List<User> findAllWithOrder();

}

UserMapper.xml映射

<resultMap id="userMap" type="com.yang.domain.User">

<id column="id" property="id"></id>

<result column="username" property="username"></result>

<result column="birthday" property="birthday"></result>

<result column="sex" property="sex"></result>

<result column="address" property="address"></result>

<!--

一对多使用collection标签关联

property="orderList" 封装到集合的属性名

ofType="order" 封装集合的泛型类型

-->

<collection property="orderList" ofType="com.yang.domain.Order">

<id column="oid" property="id"></id>

<result column="ordertime" property="ordertime"></result>

<result column="money" property="money"></result>

</collection>

</resultMap>

<select id="findAllWithOrder" resultMap="userMap">

SELECT *,o.id oid FROM USER u LEFT JOIN orders o ON u.`id`=o.`uid`;

</select>

4.多对对联合查询

多对多联合查询跟一对多很想似,只是sql语句变得稍微复杂。

七.嵌套查询

1.嵌套查询多表配置方式

一对一配置使用<resultMap>+<association>做配置通过column条件执行select查询

一对多配置使用<resultMap>+<collection>做配置通过column条件执行select查询

多对多配置使用<resultMap>+<collection>做配置通过column条件执行select查询

优点简化多表查询操作

缺点执行多次sql语句浪费数据库性能

2.一对一代码嵌套查询

一个订单从属一个用户

一对一查询语句:

-- 先查询订单

SELECT * FROM orders;

-- 再根据订单uid外键,查询用户

SELECT * FROM `user` WHERE id = #{订单的uid};

 

OrderMapper接口

public interface OrderMapper {

public List<Order> findAllWithUser();

}

OrderMapper.xml映射

<!--一对一嵌套查询-->

<resultMap id="orderMap" type="order">

<id column="id" property="id"></id>

<result column="ordertime" property="ordertime"></result>

<result column="money" property="money"></result>

<!--根据订单中uid外键,查询用户表-->

<association property="user" javaType="user" column="uid"

select="com.yang.mapper.UserMapper.findById"></association>

</resultMap>

<select id="findAllWithUser" resultMap="orderMap" >

SELECT * FROM orders

</select>

UserMapper接口

public interface UserMapper {

public User findById(Integer id);

}

 

UserMapper.xml映射

<select id="findById" parameterType="int" resultType="user">

SELECT * FROM `user` where id = #{uid}

</select>

 

3.一对多代码嵌套查询

查询所有用户,与此同时查询出该用户具有的订单

一对多查询语句:

-- 先查询用户

SELECT * FROM `user`;

-- 再根据用户id主键,查询订单列表

SELECT * FROM orders where uid = #{用户id}

UserMapper接口

public interface UserMapper {

public List<User> findAllWithOrder();

}

 

UserMapper.xml映射

<!--一对多嵌套查询-->

<resultMap id="userMap" type="user">

<id column="id" property="id"></id>

<result column="username" property="username"></result>

<result column="birthday" property="birthday"></result>

<result column="sex" property="sex"></result>

<result column="address" property="address"></result>

<!--根据用户id,查询订单表-->

<collection property="orderList" column="id" ofType="order"

select="com.yang.mapper.OrderMapper.findByUid"></collection>

</resultMap>

<select id="findAllWithOrder" resultMap="userMap">

SELECT * FROM `user`

</select>

OrderMapper接口

public interface OrderMapper {

public List<Order> findByUid(Integer uid);

}

 

OrderMapper.xml映射

<select id="findByUid" parameterType="int" resultType="order">

SELECT * FROM orders where uid = #{uid}

</select>

4。多对多嵌套查询

多对多嵌套查询和一对多很想,只是sql语句有很大差别

-- 先查询用户

SELECT * FROM `user`;

-- 再根据用户id主键,查询角色列表

SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid`

WHERE ur.`uid` = #{用户id};

八. MyBatis延迟加载

1.概念

延迟加载就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载。

* 优点

先从单表查询需要时再从关联表去关联查询大大提高数据库性能因为查询单表要比关联查询多张表速度要快

* 缺点

因为只有当需要用到数据时才会进行数据库查询这样在大批量数据查询时因为查询工作也要消耗时间所以可能造成用户等待时间变长造成用户体验下降

* 在多表中

一对多多对多通常情况下采用延迟加载

一对一多对一):通常情况下采用立即加载

 

2.实现

局部延迟加载

在association和collection标签中都有一个fetchType属性,通过修改它的值,可以修改局部的加载策略。

<!-- 开启一对多延迟加载-->

<resultMap id="userMap" type="user">

<id column="id" property="id"></id>

<result column="username" property="username"></result>

<result column="password" property="password"></result>

<result column="birthday" property="birthday"></result>

<!--

fetchType="lazy" 懒加载策略

fetchType="eager" 立即加载策略

-->

<collection property="orderList" ofType="order" column="id"

select="com.yang.dao.OrderMapper.findByUid" fetchType="lazy">

</collection>

</resultMap>

<select id="findAll" resultMap="userMap">

SELECT * FROM `user`

</select>

设置触发延迟加载的方法

   大家在配置了延迟加载策略后发现即使没有调用关联对象的任何方法但是在你调用当前对象的equalsclonehashCodetoString方法时也会触发关联对象的查询

  我们可以在配置文件中使用lazyLoadTriggerMethods配置项覆盖掉上面四个方法

<settings>

<!--所有方法都会延迟加载-->

<setting name="lazyLoadTriggerMethods" value="toString()"/>

</settings>

 

全局延迟加载

在Mybatis的核心配置文件中可以使用setting标签修改全局的加载策略。

 

<settings>

<!--开启全局延迟加载功能-->

<setting name="lazyLoadingEnabled" value="true"/>

</settings>

注意 局部的加载策略优先级高于全局的加载策略。

 <!-- 关闭一对一延迟加载-->

<resultMap id="orderMap" type="order">

<id column="id" property="id"></id>

<result column="ordertime" property="ordertime"></result>

<result column="total" property="total"></result>

<!--

fetchType="lazy" 懒加载策略

fetchType="eager" 立即加载策略

-->

<association property="user" column="uid" javaType="user"

select="com.yang.dao.UserMapper.findById" fetchType="eager">

</association>

</resultMap>

<select id="findAll" resultMap="orderMap">

SELECT * from orders

</select>

 

 

九.MyBatis缓存    

1.为什么使用缓存?

   当用户频繁查询某些固定的数据时,第一次将这些数据从数据库中查询出来,保存在缓存中。当用户再 次查询这些数据时,不用再通过数据库查询,而是去缓存里面查询。减少网络连接和数据库查询带来的损 耗,从而提高我们的查询效率,减少高并发访问带来的系统性能问题。

   一句话概括:经常查询一些不经常发生变化的数据,使用缓存来提高查询效率。

   像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数, 从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。

2.一级缓存

    一级缓存是SqlSession级别的缓存,是默认开启的。

    所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往 只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时 候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不 会再次发送SQL到数据库。

 注意事项

   一级缓存是SqlSession范围的缓存,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调 用clearCache()、commit()、close()方法,都会清空缓存。

3.二级缓存

   二级缓存是namspace级别(跨sqlSession)的缓存,是默认不开启的。

   二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置 就可以开启 二级缓存了。

  配置核心配置文件:

<settings>

<!--

因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。

true代表开启二级缓存false代表不开启二级缓存

-->

<setting name="cacheEnabled" value="true"/>

</settings>

配置UserMapper.xml映射

<mapper namespace="com.yang.dao.UserMapper">

<!--当前映射文件开启二级缓存-->

<cache></cache>

<!--

<select>标签中设置useCache=true代表当前这个statement要使用二级缓存

如果不使用二级缓存可以设置为false

注意

针对每次查询都需要最新的数据sql要设置成useCache="false"禁用二级缓存

-->

<select id="findById" parameterType="int" resultType="user" useCache="true"

>

SELECT * FROM `user` where id = #{id}

</select>

</mapper>

4.注意问题(脏读)

mybatis的二级缓存因为是namespace级别,所以在进行多表查询时会产生脏读问题

5.总结

1. mybatis的缓存,都不需要我们手动存储和获取数据。mybatis自动维护的。

2. mybatis开启了二级缓存后,那么查询顺序:二级缓存--》一级缓存--》数据库

3. 注意:mybatis的二级缓存会存在脏读问题,需要使用第三方的缓存技术解决问题。

十.Mybatis使用注解开发

一.介绍  

    这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写 Mapper映射文件了。

* @Insert实现新增代替了<insert></insert>

* @Delete实现删除代替了<delete></delete>

* @Update实现更新代替了<update></update>

* @Select实现查询代替了<select></select>

* @Result实现结果集封装代替了<result></result>

* @Results可以与@Result 一起使用封装多个结果集代替了<resultMap></resultMap>

* @One实现一对一结果集封装代替了<association></association>

* @Many实现一对多结果集封装代替了<collection></collection>

二. MyBatis注解的增删改查

创建UserMapper接口

public interface UserMapper {

@Select("SELECT * FROM `user`")

public List<User> findAll();

@Insert("INSERT INTO `user`(username,birthday,sex,address) VALUES(#

{username},#{birthday},#{sex},#{address})")

public void save(User user);

@Update("UPDATE `user` SET username = #{username},birthday = #{birthday},sex

= #{sex},address = #{address} WHERE id = #{id}")

public void update(User user);

@Delete("DELETE FROM `user` where id = #{id}")

public void delete(Integer id);

}

 

三.编写核心配置文件

两种用法选择一个

第一种用法:

<!--我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可-->

<mappers>

<!--扫描使用注解的Mapper-->

<mapper class="com.yang.mapper.UserMapper"></mapper>

</mappers>

第二种用法:

<!--或者指定扫描包含映射关系的接口所在的包也可以-->

<mappers>

<!--扫描使用注解的Mapper类所在的包-->

<package name="com.yang.mapper"></package>

</mappers>

四. 使用注解实现复杂映射开发

  4.1.我们在映射文件中通过配置来实现复杂关系映射。

  使用注解开发后,我们可以使用 @Results、@Result,@One、@Many 注解组合完成复杂关系的配置。

注解

说明

@Results

代替的是标签<resultMap>该注解种可以使用单个@Result注解,也可以使用@Result集合。

使用格式:@Results({@Result(),@Result()})或Results (@Result())

@Result

代替了<id>标签和<result>标签

@Result中属性介绍:

column:数据库列名

property:需要装配的属性名

one:需要使用的@One注解(@Result(one=@One)()))

many:需要使用的@Many注解(@Result(many=@many)()))

@One(一对一)

代替了<assocation>标签,使多表查询的关键,在注解种用来指定自查询返回单一对象。

@One注解属性介绍

Select:指定用来多表查询的sqlmapper

使用格式:@Result(column="",property="",one=@One(select=""))

@Many(一对多)

代替了<collection>标签,使多表查询的关键,在注解种用来指定自查询返回对象集合。

  4.2. 一对一查询

一对一查询语句

SELECT * FROM orders;

SELECT * FROM `user` WHERE id = #{订单的uid};

OrderMapper接口

public interface OrderMapper {

@Select("SELECT * FROM orders")

@Results({

@Result(id = true, column = "id", property = "id"),

@Result(column = "ordertime", property = "ordertime"),

@Result(column = "money", property = "money"),

@Result(property = "user", javaType = User.class,

column = "uid", one = @One(select =

"com.yang.mapper.UserMapper.findById", fetchType = FetchType.EAGER))

})

public List<Order> findAllWithUser();

}

 

UserMapper接口

public interface UserMapper {

@Select("SELECT * FROM `user` WHERE id = #{id}")

public User findById(Integer id);

}

 

  4.3. 一对多查询

一对多查询语句

SELECT * FROM `user`;

SELECT * FROM orders where uid = #{用户id};

UserMapper接口

public interface UserMapper {

@Select("SELECT * FROM `user`")

@Results({

@Result(id = true, column = "id", property = "id"),

@Result(column = "brithday", property = "brithday"),

@Result(column = "sex", property = "sex"),

@Result(column = "address", property = "address"),

@Result(property = "orderList", javaType = List.class,

column = "id" ,

many = @Many(select = "com.yang.mapper.OrderMapper.findByUid"))

})

public List<User> findAllWithOrder();

}

OrderMapper接口

 

public interface OrderMapper {

@Select("SELECT * FROM orders WHERE uid = #{uid}")

public List<Order> findByUid(Integer uid);

}

  4.4.多对多查询

 

多对多跟一对多很相似就是sql语句有些差别

多对多查询语句::

 SELECT * FROM `user`;

SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid`

WHERE ur.`uid` = #{用户id};

UserMapper接口

public interface UserMapper {

@Select("SELECT * FROM `user`")

@Results({

@Result(id = true, column = "id", property = "id"),

@Result(column = "brithday", property = "brithday"),

@Result(column = "sex", property = "sex"),

@Result(column = "address", property = "address"),

@Result(property = "roleList", javaType = List.class,

column = "id" ,

many = @Many(select = "com.yang.mapper.RoleMapper.findByUid"))

})

public List<User> findAllWithRole();

}

RoleMapper接口

public interface RoleMapper {

@Select("SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid`

WHERE ur.`uid` = #{uid}")

public List<Role> findByUid(Integer uid);

}

 

  4.5. 基于注解的二级缓存

配置SqlMapConfig.xml文件开启二级缓存的支持

<settings>

<!--

因为cacheEnabled的取值默认就为true所以这一步可以省略不配置

true代表开启二级缓存false代表不开启二级缓存

-->

<setting name="cacheEnabled" value="true"/>

</settings>

 

在Mapper接口中使用注解配置二级缓存

@CacheNamespace

public interface UserMapper {...}

 

注解延迟加载不管是一对一还是一对多 ,在注解配置中都有fetchType的属性

* fetchType = FetchType.LAZY 表示懒加载

* fetchType = FetchType.EAGER 表示立即加载

* fetchType = FetchType.DEFAULT 表示使用全局配置

 4.6.xml方式和注解优劣

注解开发和xml配置优劣分析

1.注解开发和xml配置相比,从开发效率来说,注解编写更简单,效率更高。

 2.从可维护性来说,注解如果要修改,必须修改源码,会导致维护成本增加。xml维护性更强。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值