mybatis
一、mybatis延迟加载
一对一:用的标签<association></association>
一对多:用的标签<collection></collection>
配置SqlMapConfig.xml:
<!--配置延迟加载参数-->
<settings>
<setting name="lazyLoadingEnabled" value="true"></setting>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
配置一对一关系(一个账户对应着一个用户)的IAccountDao.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.fjut.dao.IAccountDao">
<!--一对一的表关系的resultMap-->
<resultMap id="accountUserMap" type="account"> <!--type是指返回结果类型(即封装到哪)-->
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--封装user的内容***-->
<association property="user" column="uid" javaType="user" select="com.fjut.dao.IUserDao.findById"></association>
</resultMap>
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
</mapper>
IUserDao添加User findById(Integer id)的方法,配置IUserDao.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.fjut.dao.IUserDao">
<!-- 定义User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- 配置user对象中accounts集合的映射 -->
<collection property="accounts" ofType="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="userAccountMap">
select u.*,a.id as aid,a.uid,a.money from user u left outer join account a on u.id = a.uid
</select>
<select id="findById" parameterType="java.lang.Integer" resultType="user">
select * from user where id = #{id}
</select>
</mapper>
测试:
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Account> accounts = accountDao.findAll();
for(Account account : accounts){
System.out.println("--------每个account的信息------------");
System.out.println(account);
System.out.println(account.getUser());
}
}
结果:
一对多的延迟加载:需要改变的就是collection的参数(注意column属性是指用于查询的列名(不能少))。
延迟加载思想:就是在需要使用延迟加载的时候去调用对方映射配置中的方法来实现延迟加载。(即:在用的时候在调用)。
什么表关系情况下需要采用什么加载?:
一对多,多对多:通常情况下采用延迟加载。
一对一:通常情况下采用立即加载。
二、mybatis中的缓存
1.什么是缓存
存在于内存中的临时数据。用于减少和数据库的交互次数,提高执行效率。
2.一级缓存和二级缓存
一级缓存:
- 指的是mybatis中SqlSession对象的缓存。
- 当我们执行查询之后,查询的结果会同存入到SqlSession为我们提供一块区域中。
- 该区域的结构是一个Map。
- 当SqlSession对象消失时,mybatis的一级缓存也就消失了。
注意:当SqlSeesion的修改、添加、删除、commit()、close()、clearCache()等方法是,一级缓存就会自动被情况。
二级缓存:
- 指的是mybatis的SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建SqlSession共享其缓存。
- 二级缓存的使用步骤。
- 第一步:让mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
<!--配置二级缓存参数-->
<settings>
<setting name="cacheEnabled" value="true"></setting>
</settings>
- 第二步:让当前的映射文件支持二级缓存
<!--开启支持二级缓存-->
<cache/>
- 第三步:让当前的操作支持二级缓存(在select、update、这些标签中配置)
<!--配置userCache="true"-->
<select id=findById parameterType="java.lang.Integer" resultType="user" userCache="true">
select * fron user where id = #{id}
</select>
注意:二级缓存中,查询语句只执行了一次,但是创建对象时是创建了两个对象。(原因:它保存的是{“。。。”“。。。”“。。。”“。。。”}这样的数据。在新new对象的时候存进去,所以对象不一样。)
mybatis注解开发环境:
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="jdbcConfig.properties"></properties>
<!--配置别名-->
<typeAliases>
<package name="com.fjut.domain"></package>
</typeAliases>
<!--配置mysql环境-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!--引入指定带有注解的dao接口所在的位置。-->
<mappers>
<package name="com.fjut.dao"></package>
</mappers>
</configuration>
IUserDao
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
List<User> findAll();
测试:
/**
* 测试mybatis注解使用
*/
@Test
public void findAllTest() throws IOException {
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = factory.openSession();
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
//以上代码可以放到一个@Before注解注解的方法内。用于在测试之前执行。
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
//以下代码可以放到一个@After注解注解的方法内。用于在测试代码完成后执行。
userDao.commit(); //这是提交事务,用在增删改方法时必须要有。否则更新数据库不成功。
sqlSession.close();
in.close();
}
注解环境注意:resources路径下不能存在对应的映射配置文件,不然会报错。