mybatis详解
mybatis:
依赖坐标
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql依赖-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--日志-->
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--测试-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
1.关系映射
1.1 一对一关系映射
<resultMap id="accountMap" type="com.domain.Account"> <id column="id" property="id"/> <result property="uid" column="uid"/> <result property="money" column="money"/> <result property="name" column="name"/> <!--配置一对一关系映射--> <association property="user" javaType="com.domain.User" select="com.dao.UserDao.findById" column="uid"/> </resultMap>
1.2一对多(多对多)关系映射
<resultMap id="user" type="com.domain.User">
<id property="id" column="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!--配置一对多关系映射-->
<!--AccountDao中必须要有根据uid查询数据的方法
property:属性名称
ofType:所属类型
select:对应的查询方法
column:查询方法的参数
fetchType:指定加载方式,默认为lazy
eager:立即加载
lazy:延迟加载
-->
<collection property="accounts" ofType="com.domain.Account" select="com.dao.AccountDao.findByUid" column="id"/>
<collection property="roles" ofType="com.domain.Role" select="com.dao.RoleDao.findByUid" column="id" fetchType="eager"/>
</resultMap>
2.二级缓存
第一步:SqlMapConfig.xml文件
<!--开启二级缓存:SqlSessionFactory级别的缓存--> <setting name="cacheEnabled" value="true"/><!--默认为true,所以可以不用配置-->
第二步:mapper.xml文件 <!--添加cache标签,开启二级缓存--> <cache/><!--对,就是这个标签--> <resultMap id="roleMap" type="com.domain.Role"> <id column="id" property="id"/> <result property="roleName" column="ROLE_NAME"/> <result property="roleDesc" column="ROLE_DESC"/> <!--多对多关系映射--> <collection property="users" ofType="com.domain.User" select="com.dao.UserDao.findByRid" column="id"/> </resultMap> <!-- useCache:是否开启二级缓存,默认为true true:开启二级缓存 false:不开启二级缓存 --> <select id="findAll" resultMap="roleMap" useCache="true"> select * from role </select>
综上所述:要开启二级缓存,只需要在mapper.xml文件中添加一个<cache/>即可。
注:实体类一定要实现Serializable接口


3.延迟加载
第一步:<!--SqlMapConfig.xml文件-->
<settings>
<!--开启延迟加载-->
<!--lazyLoadingEnabled:延迟加载的全局开关,开启时,所有关联对象都会延迟加载。如需立即加载,可通过设置fetchType属性覆盖该项的开关状态-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--aggressiveLazyLoading:开启时,立即加载所有延迟加载属性;关闭时,每个延迟加载都会按需加载-->
<setting name="aggressiveLazyLoading" value="false"/><!--此项可以不配,因为mybatis3.4.1之后默认为false-->
</settings>
第二步:mapper.xml文件
<!--
fetchType:指定加载方式,默认为lazy。所以懒加载时无需配置此属性
eager:立即加载
lazy:延迟加载
-->
<collection property="roles" ofType="com.domain.Role" select="com.dao.RoleDao.findByUid" column="id" fetchType="lazy"/>
综上所述,要开启延迟加载,只需要配置<setting name="lazyLoadingEnabled" value="true"/>即可。
4.插入时获取新插入数据的id:
<insert id="save" parameterType="com.domain.User"> /*插入时获取新插入数据的id*/ <selectKey keyColumn="id" resultType="int" keyProperty="id" order="AFTER"> select last_insert_id(); </selectKey> insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address}) </insert>
5.模糊查询
<select id="findLike3" resultType="com.domain.User" parameterType="String"> select * from user where username like concat('%', #{username},'%') </select>
6.起别名
<!--typeAliases:用于设置别名,只能配置domain包中得类-->
<typeAliases>
<!--设置别名后,mapper文件中就不需要再写全限定类名了-->
<typeAlias type="com.domain.User" alias="user"/>
<!--如果类太多,可以用package指定包,此种方式类名即别名,不再区分大小写-->
<package name="com.domain"/>
</typeAliases>
下面再来说说通过注解的方式实现上述配置
1.关系映射
1.1一对一关系映射
@Select("select * from account where uid = #{uid}") @Results(id = "accountMap", value = { @Result(id = true,property = "id", column = "id"), @Result(property = "uid",column = "uid"), @Result(property = "money",column = "money"), @Result(property = "name",column = "name"), //配置一对一关系映射 @Result(property = "user",one = @One(select = "com.dao.UserDao.findById"),column = "uid") }) List<Account> findByUid(int uid);
//当然不需要每一个方法都写一遍@Results,其他方法可以通过@ResultMap注解直接引用,如下:
@ResultMap(value = {"userMap"})
1.2一对多关系映射
@Select("select * from user") //配置实体类-表映射关系 @Results(id = "userMap",value = { @Result(id = true,property = "id",column = "id"), @Result(property = "userName",column = "username"), @Result(property = "userBirthday",column = "birthday"), @Result(property = "userSex",column = "sex"), @Result(property = "userAddress",column = "address"), //配置一对多关系映射 @Result(property = "accounts", many = @Many(select = "com.dao.AccountDao.findByUid",fetchType = FetchType.LAZY), column = "id"), @Result(property = "roles", many = @Many(select = "com.dao.RoleDao.findByUid"), column = "id") }) List<User> findAll();
2.延迟加载(同上)
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
3.二级缓存
接口上面加注解@CacheNamespace(bolcking = true)
@CacheNamespace(blocking = true) public interface RoleDao {}
4.插入时获取新插入数据的id
插入方法上加注解 @Potions(useGeneratedKeys = true , keyColumn = "id")
//添加 @Insert("insert into user (username,birthday,sex,address) values (#{userName},#{userBirthday},#{userSex},#{userAddress})") //@Options:用于在插入时获取新插入数据的id @Options(useGeneratedKeys = true,keyColumn = "id") void save(User user);
遗留问题:
1.连接数据库的信息单独放入一个配置文件会导致条件查询获取不到(哪位大佬知道的可以解答一下,不胜感激!)
题外话:本来想两天搞定,结果用了8天,哦天啊,我发誓我一定要干掉惰性这个混蛋!!!

浙公网安备 33010602011771号