Mybatis学习笔记

#Mybatis
###第一个例子
#####第一步:pom.xml文件中添加Mybatis3.4.5的坐标,mysql,junit,logj
#####第二步:编写User实体类。
#####第三步:编写SqlMapConfig.xml配置文件(放在resources中)

<?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>
<!-- 配置mybatis的环境 -->
<environments default="mysql">
<!-- 配置mysql的环境 -->
<environment id="mysql">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/review"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 告知mybatis映射配置的位置 -->
<mappers>
<mapper resource="com/itheima/dao/IUserDao.xml"/>
</mappers>
</configuration>

#####第四步:编写持久层接口IuserDao
#####第五步:编写持久层接口的映射文件IUserDao.xml

  • 创建位置:必须和持久层接口在相同的包中。
  • 名称:必须以持久层接口名称命名文件名,扩展名是.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.zichuan.dao.IUserDao">
<!-- 配置查询所有操作 -->
<select id="findAll" resultType="com.zichuan.domain.User">
select * from user
</select>
</mapper>

#####第六步:编写测试类

//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.使用构建者创建工厂对象SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.使用SqlSessionFactory生产SqlSession对象
SqlSession session = factory.openSession();
//5.使用SqlSession创建dao接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//6.使用代理对象执行查询所有方法
List<User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
//7.释放资源
session.close();
in.close();

注解

  1. 持久层接口中添加注解
@Select("select * from user")
List<User> findAll();
  1. 修改SqlMapConfig.xml(注意:移除xml的映射配置(IUserDao.xml)。)
<!-- 告知mybatis映射配置的位置 -->
<mappers>
<mapper class="com.zichuan.dao.IUserDao"/>
</mappers>

###其他查询方式详解
#####根据id查询

<select id="findById" resultType="com.zichuan.domain.User" parameterType="int">
select * from user where id = #{uid}
</select>

resultType属性:用于指定结果集的类型。
parameterType属性:用于指定传入参数的类型。
sql语句中使用#{}字符:它代表占位符,相当于原来jdbc部分所学的?,都是用于执行语句时替换实际的数据。 具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:由于数据类型是基本类型,所以此处可以随意写。

#####测试类框架

private InputStream in ;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Before//在测试方法执行之前执行
public void init()throws Exception {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.创建SqlSession工厂对象
factory = builder.build(in);
//4.创建SqlSession对象
session = factory.openSession();
//5.创建Dao的代理对象
userDao = session.getMapper(IUserDao.class);
}
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
session.commit();
//7.释放资源
session.close();
in.close();
}
@Test
public void testFindOne() {
//6.执行操作
User user = userDao.findById(41);
System.out.println(user);
}

#####保存用户

<!-- 保存用户-->
<insert id="saveUser" parameterType="com.zichuan.domain.User">
insert into user(username,birthday,sex,address)
values(#{username},#{birthday},#{sex},#{address})
</insert>
#{user.username}它会先去找user对象,然后在user对象中找到username属性,并调用getUsername()方法把值取出来。但是我们在parameterType属性上指定了实体类名称,所以可以省略user.而直接写username。

实现增删改时一定要去控制事务的提交,可以使用:session.commit();来实现事务提交

#####新增用户id的返回值

<insert id="saveUser" parameterType="USER"> 
<!-- 配置保存时获取插入的id --> 
<selectKey keyColumn="id" keyProperty="id" resultType="int"> 
select last_insert_id(); 
</selectKey> 
insert into user(username,birthday,sex,address) 
values(#{username},#{birthday},#{sex},#{address}) 
</insert>

更新方法

<!-- 更新用户 --> 
<update id="updateUser" parameterType="com.itheima.domain.User"> 
update user set username=#{username},birthday=#{birthday},sex=#{sex}, 
address=#{address} where id=#{id} 
</update>

删除方法

<!-- 删除用户 --> 
<delete id="deleteUser" parameterType="java.lang.Integer"> 
delete from user where id = #{uid} 
</delete>

模糊查询

<!-- 根据名称模糊查询 --> 
<select id="findByName" resultType="com.itheima.domain.User" parameterType="String"> 
select * from user where username like #{username} 
</select>
List<User> users = userDao.findByName("%王%");

我们在配置文件中没有加入%来作为模糊查询的条件,所以在传入字符串实参时,就需要给定模糊查询的标识%。配置文件中的#{username}也只是一个占位符,所以SQL语句显示为“?”

select * from user where username like '%${value}%'

我们在上面将原来的#{}占位符,改成了 v a l u e 。 注 意 如 果 用 模 糊 查 询 的 这 种 写 法 , 那 么 {value}。注意如果用模糊查询的这种写法,那么 value{value}的写法就是固定的,不能写成其它名字。

List<User> users = userDao.findByName("王");

#{}与${}的区别

通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
表 示 拼 接 s q l 串 通 过 {}表示拼接sql串 通过 sql{}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值, pojoparameterType{}括号中只能是value

查询使用聚合函数

<!-- 查询总记录条数 --> 
<select id="findTotal" resultType="int"> 
select count(*) from user;
</select>

####resultType配置结果类型

  • 实体类属性和数据库表的列名已经不一致了
  • 使用别名查询
<select id="findAll" resultType="com.itheima.domain.User"> 
select id as userId,username as userName,birthday as userBirthday, 
sex as userSex,address as userAddress from user 
</select>

####resultMap结果类型
resultMap标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。

<resultMap type="com.itheima.domain.User" id="userMap">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>
  • id标签:用于指定主键字段
  • result标签:用于指定非主键字段
  • column属性:用于指定数据库列名
  • property属性:用于指定实体类属性名称
<select id="findAll" resultMap="userMap">
select * from user 
</select>

###SqlMapConfig.xml中配置的内容和顺序

-properties(属性)
–property
-settings(全局配置参数)
–setting
-typeAliases(类型别名)
–typeAliase
–package
-typeHandlers(类型处理器)
-objectFactory(对象工厂)
-plugins(插件)
-environments(环境集合属性对象)
–environment(环境子属性对象)
—transactionManager(事务管理)
—dataSource(数据源)
-mappers(映射器)
–mapper
–package

####properties(属性)

  • 第一种方式:
<properties> 
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/> 
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/review"/>
<property name="jdbc.username" value="root"/> 
<property name="jdbc.password" value="root"/> 
</properties>
  • 第二种方式:
    在classpath下定义db.properties文件
jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/review
jdbc.username=root 
jdbc.password=root

properties标签配置

<properties url= file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.properties"> 
</properties>

此时我们的dataSource标签就变成了引用上面的配置

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

####mappers(映射器)
使用相对于类路径的资源 ,如:

<mapper resource="com/zichuan/dao/IUserDao.xml" />

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中使用mapper接口类路径 ,如:

<mapper class="com.zichuan.dao.UserDao"/> 

注册指定包下的所有mapper接口 ,如:

<package name="cn.zichaun.mybatis.mapper"/> 

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

###Mybatis的连接池技术

在Mybatis的SqlMapConfig.xml配置文件中,通过来实现Mybatis中连接池的配置。

MyBatis在初始化时,根据的type属性来创建相应类型的的数据源DataSource,即:
type=”POOLED”:MyBatis会创建PooledDataSource实例
type=”UNPOOLED” : MyBatis会创建UnpooledDataSource实例
type=”JNDI”:MyBatis会从JNDI服务上查找DataSource实例,然后返回使用

###Mybatis的事务控制

Mybatis框架因为是对JDBC的封装,所以Mybatis框架的事务控制方式,本身也是用JDBC的setAutoCommit()方法来设置事务提交方式的。
在连接池中取出的连接,都会将调用connection.setAutoCommit(false)方法,这样我们就必须使用sqlSession.commit()方法,相当于使用了JDBC中的connection.commit()方法实现事务提交。

###Mybatis的动态SQL语句
####动态SQL之标签

<select id="findByUser" resultType="user" parameterType="user"> 
select * from user where 1=1 
<if test="username!=null and username != '' "> 
and username like #{username} 
</if> 
<if test="address != null"> 
and address like #{address} 
</if> 
</select>

Test

User u = new User(); 
u.setUsername("%王%"); 
u.setAddress("%顺义%"); 
//6.执行操作 
List<User> users = userDao.findByUser(u);

####动态SQL之标签
为了简化上面where 1=1的条件拼装,我们可以采用标签来简化开发。

<select id="findByUser" resultType="user" parameterType="user"> 
<include refid="defaultSql"></include> 
<where> 
<if test="username!=null and username != '' "> 
and username like #{username} 
</if> 
<if test="address != null"> 
and address like #{address} 
</if> 
</where> 
</select>


####动态标签之标签

<!-- 查询所有用户在id的集合之中 --> 
<select id="findInIds" resultType="user" parameterType="queryvo"> 
<!-- select * from user where id in (1,2,3,4,5); --> 
<include refid="defaultSql"></include> 
	<where> 
		<if test="ids != null and ids.size() > 0"> 
		<foreach collection="ids" open="id in ( " close=")" item="uid" separator=","> 
		#{uid} 
		</foreach> 
		</if> 
	</where> 
</select> 

SQL语句:
select 字段from user where id in (?)
标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符

#####Mybatis中简化编写的SQL片段

Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

<!-- 抽取重复的语句代码片段 --> 
<sql id="defaultSql"> 
select * from user 
</sql>

<!-- 根据id查询 --> 
<select id="findById" resultType="UsEr" parameterType="int">
<include refid="defaultSql"></include> 
where id = #{uid} 
</select>

###Mybatis 多表查询之一对多
一个用户(User)可以有多个账户(Account)

  • 方式一
select a.*,u.username,u.address from account a,user u where a.uid =u.id;

返回两个表的信息所以accountuser包含Account所有,同时继承User

return super.toString() + " AccountUser [username=" + username + ", address=" + address + "]";
<select id="findAll" resultType="accountuser"> 
select a.*,u.username,u.address from account a,user u where a.uid =u.id; 
</select>
  • 方式二
    使用resultMap,定义专门的resultMap用于映射一对一查询结果。
    通过面向对象的(has a)关系可以得知,我们可以在Account类中加入一个User类的对象来代表这个账户是哪个用户的。
private User user; 
public User getUser() { 
return user; 
} 
public void setUser(User user) { 
this.user = user; 
}
<!-- 建立对应关系 --> 
<resultMap type="account" id="accountMap"> 
<id column="aid" property="id"/> 
<result column="uid" property="uid"/> 
<result column="money" property="money"/> 
<!-- 它是用于指定从表方的引用实体属性的 --> 
<association property="user" javaType="user"> 
<id column="id" property="id"/> 
<result column="username" property="username"/> 
<result column="sex" property="sex"/> 
<result column="birthday" property="birthday"/> 
<result column="address" property="address"/> 
</association> 
</resultMap>
<select id="findAll" resultMap="accountMap"> 
select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id; 
</select>
  • 需求:
    查询所有用户信息及用户关联的账户信息。
  • 分析:
    用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来,我们想到了左外连接查询比较合适。
    User类加入List
<resultMap type="user" id="userMap"> 
<id column="id" property="id"></id> 
<result column="username" property="username"/> 
<result column="address" property="address"/> 
<result column="sex" property="sex"/> 
<result column="birthday" property="birthday"/> 
<!-- collection是用于建立一对多中集合属性的对应关系 
ofType用于指定集合元素的数据类型 
--> 
<collection property="accounts" ofType="account"> 
<id column="aid" property="id"/> 
<result column="uid" property="uid"/> 
<result column="money" property="money"/>
</collection> 
</resultMap> 
<!-- 配置查询所有操作 --> 
<select id="findAll" resultMap="userMap"> 
select u.*,a.id as aid ,a.uid,a.money from user u left [outer] join account a on u.id =a.uid 
</select>

collection
部分定义了用户关联的账户信息。表示关联查询结果集
property=“accList”:
关联查询的结果集存储在User对象的上哪个属性。
ofType=“account”:
指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

###Mybatis 多表查询之多对多
用户与角色的多对多关系模型

SELECT 
r.*,u.id uid, 
u.username username, 
u.birthday birthday, 
u.sex sex, 
u.address address 
FROM 
ROLE r 
INNER JOIN 
USER_ROLE ur 
ON ( r.id = ur.rid) 
INNER JOIN 
USER u 
ON (ur.uid = u.id);
<!--定义role表的ResultMap--> 
<resultMap id="roleMap" type="role"> 
<id property="roleId" column="rid"></id> 
<result property="roleName" column="role_name"></result> 
<result property="roleDesc" column="role_desc"></result> 
<collection property="users" ofType="user"> 
<id column="id" property="id"></id> 
<result column="username" property="username"></result> 
<result column="address" property="address"></result> 
<result column="sex" property="sex"></result> 
<result column="birthday" property="birthday"></result> 
</collection> 
</resultMap>
<!--查询所有--> 
<select id="findAll" resultMap="roleMap"> 
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id = ur.rid 
left outer join user u on u.id = ur.uid 
</select> 
</mapper>

###Mybatis延迟加载策略

延迟加载:
就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.
好处:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
坏处:
因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

mybatis第三天实现多表操作时,我们使用了resultMap来实现一对一,一对多,多对多关系的操作。主要是通过association、collection实现一对一及一对多映射。association、collection具备延迟加载功能。

 <mapper namespace="com.zichuan.dao.IAccountDao"> 
<!-- 建立对应关系 --> 
<resultMap type="account" id="accountMap"> 
<id column="aid" property="id"/> 
<result column="uid" property="uid"/> 
<result column="money" property="money"/> 
<!-- 它是用于指定从表方的引用实体属性的 --> 
<association property="user" javaType="user" 
select="com.zichuan.dao.IUserDao.findById" 
column="uid"> 
</association> 
</resultMap> 
<select id="findAll" resultMap="accountMap"> 
select * from account 
</select> 

<!-- 根据id查询 --> 
<select id="findById" resultType="user" parameterType="int" > 
select * from user where id = #{uid} 
</select>
</mapper> 
  • select: 填写我们要调用的 select 映射的 id
  • column : 填写我们要传递给 select 映射的参数

我们需要在Mybatis的配置文件SqlMapConfig.xml文件中添加延迟加载的配置。

<!-- 开启延迟加载的支持 -->
<settings> 
<setting name="lazyLoadingEnabled" value="true"/> 
<setting name="aggressiveLazyLoading" value="false"/> 
</settings>

####使用Collection实现延迟加载
结点中也有select属性,column属性。
在User实体类中加入List属性

<resultMap type="user" id="userMap">
<id column="id" property="id"></id>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<!-- collection是用于建立一对多中集合属性的对应关系
ofType用于指定集合元素的数据类型
select是用于指定查询账户的唯一标识(账户的dao全限定类名加上方法名称)
column是用于指定使用哪个字段的值作为条件查询
-->
<collection property="accounts" ofType="account"
select="com.itheima.dao.IAccountDao.findByUid"
column="id">
</collection>
</resultMap>
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
select * from user
</select>
<!-- 根据用户id查询账户信息 -->
<select id="findByUid" resultType="account" parameterType="int">
select * from account where uid = #{uid}
</select>
  • 标签:
    主要用于加载关联的集合对象
  • select属性:
    用于指定查询account列表的sql语句,所以填写的是该sql映射的id
  • column属性:
    用于指定select属性的sql语句的参数来源,上面的参数来自于user的id列,所以就写成id这一个字段名了

###Mybatis缓存
####一级缓存
一级缓存是SqlSession级别的缓存,只要SqlSession没有flush或close,它就存在
一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。

####二级缓存
二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
sqlSession1去查询用户信息,查询到用户信息会将查询数据存储到二级缓存中。

  • 首先开启mybatis的二级缓存。
    第一步:在SqlMapConfig.xml文件开启二级缓存
<settings> 
<!-- 开启二级缓存的支持 --> 
<setting name="cacheEnabled" value="true"/> 
</settings> 

因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。为true代表开启二级缓存;为false代表不开启二级缓存。
第二步:配置相关的Mapper映射文件

<cache>标签表示当前这个mapper映射将使用二级缓存,区分的标准就看mapper的namespace值。
<mapper namespace="com.itheima.dao.IUserDao"> 
<!-- 开启二级缓存的支持 --> 
<cache></cache> 
</mapper>

第三步:配置statement上面的useCache属性

<!-- 根据id查询 --> 
<select id="findById" resultType="user" parameterType="int" useCache="true"> 
select * from user where id = #{uid} 
</select> 

将UserDao.xml映射文件中的标签中设置useCache=”true”代表当前这个statement要使用二级缓存,如果不使用二级缓存可以设置为false。
注意:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。

SqlSession sqlSession1 = factory.openSession();
sqlSession1.close();//一级缓存消失
SqlSession sqlSession2 = factory.openSession();

二级缓存来自工厂
###Mybatis注解开发

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result一起使用,封装多个结果集
@ResultMap:实现引用@Results定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态SQL映射
@CacheNamespace:实现注解二级缓存的使用

若实体类名与数据库的不一致
在持久层接口中

@Select("select * from user") 
@Results(id="userMap", 
value= { 
@Result(id=true,column="id",property="userId"), 
@Result(column="username",property="userName"), 
@Result(column="sex",property="userSex"), 
@Result(column="address",property="userAddress"), 
@Result(column="birthday",property="userBirthday") 
}) 
List<User> findAll();
@Select("select * from user where id = #{uid} ")
@ResultMap("userMap")
User findById(Integer userId);
@Insert("insert into user(username,sex,birthday,address)values(#{username},#{sex},#{birthday},#{address})")
@SelectKey(keyColumn="id",keyProperty="id",resultType=Integer.class,before = false, statement = { "select last_insert_id()" })
int saveUser(User user);
@Update("update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id =#{id} ")
int updateUser(User user);
@Delete("delete from user where id = #{uid} ")
int deleteUser(Integer userId);
@Select("select count(*) from user ")
int findTotal();
@Select("select * from user where username like #{username} ")
List<User> findByName(String name);

通过注解方式,我们就不需要再去编写UserDao.xml 映射文件了。

<!-- 配置映射信息 -->
<mappers>
<!-- 配置dao接口的位置,它有两种方式
第一种:使用mapper标签配置class属性
第二种:使用package标签,直接指定dao接口所在的包
-->
<package name="com.itheima.dao"/>
</mappers>

使用注解实现复杂关系映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置来实现,在使用注解开发时我们需要借助@Results注解,@Result注解,@One注解,@Many注解。

  • @Results注解
    代替的是标签
    该注解中可以使用单个@Result注解,也可以使用@Result集合
    @Results({@Result(),@Result()})或@Results(@Result())
  • @Resutl注解
    代替了 标签和标签
  • @Result 中 属性介绍:
    id 是否是主键字段
    column 数据库的列名
    property需要装配的属性名
    one 需要使用的@One注解(@Result(one=@One)()))
    many 需要使用的@Many注解(@Result(many=@many)()))
    **@One注解(一对一) **
    代替了标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
    @One注解属性介绍:
    select 指定用来多表查询的sqlmapper
    fetchType会覆盖全局的配置参数lazyLoadingEnabled。。
    使用格式:
    @Result(column=" “,property=”",one=@One(select=""))
    @Many注解(多对一)
    代替了标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
    注意:聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList)但是注解中可以不定义;
    使用格式:
    @Result(property="",column="",many=@Many(select=""))

使用注解实现一对一复杂关系映射及延迟加载
添加账户的持久层接口并使用注解配置

查询所有账户,采用***延迟加载***的方式查询账户的所属用户
@return

@Select("select * from account") 
@Results(id="accountMap", 
value= { 
@Result(id=true,column="id",property="id"), 
@Result(column="uid",property="uid"), 
@Result(column="money",property="money"), 
@Result(column="uid", 
property="user", 
one=@One(select="com.itheima.dao.IUserDao.findById", 
fetchType=FetchType.LAZY) 
) 
}) 
List<Account> findAll();

添加用户的持久层接口并使用注解配置

查询所有用户
@return

@Select("select * from user") 
@Results(id="userMap", 
value= { 
@Result(id=true,column="id",property="userId"), 
@Result(column="username",property="userName"), 
@Result(column="sex",property="userSex"), 
@Result(column="address",property="userAddress"), 
@Result(column="birthday",property="userBirthday") 
}) 
List<User> findAll(); 

**根据id查询一个用户 **

@param userId
@return

@Select("select * from user where id = #{uid} ") 
@ResultMap("userMap") 
User findById(Integer userId);

使用注解实现一对多复杂关系映射

  • 一对多关系映射:主表方法应该包含一个从表方的集合引用
    private List accounts;
    编写用户的持久层接口并使用注解配置

**查询所有用户 **

@return

@Select("select * from user") 
@Results(id="userMap", 
value= { 
@Result(id=true,column="id",property="userId"), 
@Result(column="username",property="userName"), 
@Result(column="sex",property="userSex"), 
@Result(column="address",property="userAddress"), 
@Result(column="birthday",property="userBirthday"), 
@Result(column="id",property="accounts", 
many=@Many( 
select="com.itheima.dao.IAccountDao.findByUid", 
fetchType=FetchType.LAZY 
) 
) 
}) 
List<User> findAll(); 
} 

**@Many: **
相当于的配置

  • select属性:代表将要执行的sql语句
  • fetchType属性:代表加载方式,一般如果要延迟加载都设置为LAZY的值
    编写账户的持久层接口并使用注解配置
@Select("select * from account where uid = #{uid} ") 
List<Account> findByUid(Integer userId);

####mybatis基于注解的二级缓存
在SqlMapConfig中开启二级缓存支持

<!-- 配置二级缓存 --> 
<settings> 
<!-- 开启二级缓存的支持 --> 
<setting name="cacheEnabled" value="true"/> 
</settings>

在持久层接口中使用注解配置二级缓存

@CacheNamespace(blocking=true)//mybatis基于注解方式实现配置二级缓存 
public interface IUserDao {}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值