【mybatis-04】
01 mybatis 延迟加载/懒加载 (需要时才进行加载)
00 开启mybatis的延迟加载
<settings>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--关闭积极加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
01 association 实现懒加载
List<Account> findAllLazyInit();
<select id="findAllLazyInit" resultMap="account_user_lazy_init_map">
select
*
from account
</select>
<resultMap id="account_user_lazy_init_map" type="account">
<id column="id" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
<association property="user" column="uid" javaType="user" select="com.mybatis.dao.UserDao.findById"></association>
</resultMap>
User findById(Integer id);
<select id="findById" parameterType="java.lang.Integer" resultType="com.mybatis.domain.User" useCache="true">
select * from user
where id = #{id}
</select>
02 collection 实现懒加载
List<User> findAllLazyInit();
<select id="findAllLazyInit" resultMap="user_account_lazy_init_map">
select * from user
</select>
<resultMap id="user_account_lazy_init_map" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<collection property="accountList" ofType="account" column="id" select="com.mybatis.dao.AccountDao.findByUserId"></collection>
</resultMap>
List<Account> findByUserId(Long uid);
<select id="findByUserId" parameterType="long" resultType="account">
select * from account where uid = #{uid}
</select>
02 mybatis 一级缓存 sqlSession
只要 SqlSession 没有 clearCache 或 close,它就存在。
当调用 SqlSession 的修改,添加,删除,commit(),close(),clearCache()方法时,将清空一级缓存
测试:在同一个 sqlSession 中获取同一个id,返回的地址相同
03 mybatis 二级缓存 sqlSessionFactory
01 配置二级缓存的开启
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
02 配置相应的 Mapper 映射文件
<mapper namespace="com.itheima.dao.IUserDao">
<!-- 开启二级缓存的支持 -->
<cache></cache>
</mapper>
03 配置 statement 的 useCache 属性
<select id="findById" resultType="user" parameterType="int" useCache="true">
select * from user where id = #{uid}
</select>
【注意】针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存
04 测试:
在不同的 sqlSession 中获取同一个id
只发出一条 sql ,但返回的地址不同
因为 二级缓存,保存的是数据
05 注意
缓存的类需要实现 java.io.Serializable 接口
04 mybatis 注解开发
00 常用注解说明
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@ResultMap:实现引用@Results 定义的封装
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
@SelectProvider: 实现动态 SQL 映射
@CacheNamespace:实现注解二级缓存的使用
01 CRUD
@Select("select * from user")
List<User> findAll();
@Select("select * from user where id=#{id} ")
User findById(Integer id);
@SelectKey(keyProperty = "id",keyColumn = "id",resultType = int.class,before = false,statement = "select last_insert_id()")
@Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
void save(User user);
@Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
void update(User user);
@Delete("delete from user where id=#{id} ")
void deleteById(Integer id);
@Select("select * from user where id=#{id} ")
User findById(Integer id);
@Select("select * from user where username like concat('%',#{username},'%') ")
// @Select("select * from user where username like '%${value}%' ")
List<User> findByName(String username);
02 复杂关系映射
01 @Many collection
/**
* 包含 account 信息
* @return
*/
@Select("select * from user")
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday"),
@Result(property = "accountList",column = "id",javaType = List.class,
many = @Many(select = "com.mybatis.dao.AccountDao.findByUserId",fetchType = FetchType.LAZY))
})
List<User> findAllVersion2();
@Select("select * from account where uid = #{uid}")
List<Account> findByUserId(Long uid);
02 @One association
/**
*
* @return
*/
@Select("select * from account")
@Results(id = "account_user_map",value = {
@Result(property = "uid",column = "uid"),
@Result(property = "user",column = "uid",javaType = User.class,
one = @One(select = "com.mybatis.dao.UserDao.findById",fetchType = FetchType.EAGER)
)
})
List<Account> findAllVersion2();
@Select("select * from user where id=#{id} ")
User findById(Integer id);
05 dao查询使用多个参数
@Select("select * from user where username like concat('%',#{username},'%') and sex = #{sex} ")
List<User> findByUsernameAndSex(@Param("username") String username,@Param("sex") String sex);
06 注解 二级缓存
<settings>
<!-- 开启二级缓存的支持 -->
<setting name="cacheEnabled" value="true"/>
</settings>
@CacheNamespace(blocking=true)
public interface IUserDao {}
【mybatis-03】
01 mybatis 连接池分类
01 UNPOOLED 不使用连接池的数据源
02 POOLED 使用连接池的数据源
03 JNDI 使用jndi实现的数据源
02 事务控制
01 jdbc 事务控制 默认自动提交 setAutoCommmit(false),开启手动提交
02 mybatis 事务控制
01 openSession() 默认手动提交
02 openSession(autoCommit)
03 动态SQL
01 if
<select id="findByCondition" resultMap="userMap">
select * from user
where 1=1
<if test="username != null"></if>
and username like #{username}
</select>
02 choose(when otherwise)
03 trim(where set)
<select id="findByUser" resultType="user" parameterType="user">
select * from user
<where>
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</where>
</select>
04 foreach
<select id="findUserByIds" resultMap="userMap" parameterType="QueryVO">
select * from user
<where>
<if test="ids!=null and ids.size()>0">
<foreach collection="ids" open="id in (" separator="," close=")" item="tmpId" >
#{tmpId}
</foreach>
</if>
</where>
</select>
04 简化编写 sql 语句
<sql id="defaultSql">
select * from user
</sql>
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
05 mybatis 一对多/多对一
user (1:m) account
01 一对一/多对一
01 AccountUser 包含sql查询出来的全部字段
02 Account (属性 user)
<resultMap id="accountResultMap" type="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
<!-- 指定从表方的引用实体属性 -->
<association property="user" javaType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findAllVersion2" resultMap="accountResultMap">
select
a.id as aid ,a.uid,a.money,
u.id,u.username,u.sex,u.birthday,u.address
from account a
inner join user u
on a.uid = u.id
</select>
01 一对多
User (属性 List<Account> accountList)
<resultMap id="userMap" type="com.mybatis.domain.User">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<collection property="accountList" ofType="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<select id="findAllVersion2" resultMap="userMap">
select
a.id as aid ,a.uid,a.money,
u.id,u.username,u.sex,u.birthday,u.address
from user u
left join account a
on a.uid = u.id
</select>
06 mybatis 多对多
user (m:n) role
<resultMap id="roleResultMap" type="role">
<id property="roleId" column="rid"/>
<result property="roleName" column="role_name"/>
<result property="roleDesc" column="role_desc"/>
<collection property="userList" ofType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="roleResultMap">
select
u.*,r.id as rid,r.role_name,r.role_desc
from role r
left join user_role ur on r.id = ur.rid
left join user u on u.id = ur.uid
</select>
【mybatis-02】
01 基于代理dao 实现 CRUD
01 select
User findById(Integer id);
<select id="findById" parameterType="java.lang.Integer" resultType="com.mybatis.domain.User">
select * from user
where id = #{id}
</select>
02 insert
【需要 sqlSession.commit(),openSession()事务默认不提交】
void save(User user);
<insert id="save" parameterType="com.mybatis.domain.User">
<!-- 配置插入操作后,获取插入数据的id -->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user
(username,birthday,sex,address)
values
(#{username},#{birthday},#{sex},#{address})
</insert>
03 update
【需要 sqlSession.commit(),openSession()事务默认不提交】
void update(User user);
<update id="update" parameterType="com.mybatis.domain.User">
UPDATE USER
set username = #{username},
birthday = #{birthday},
sex = #{sex},
address = #{userAddress}
where id = #{id}
</update>
04 delete
【需要 sqlSession.commit(),openSession()事务默认不提交】
void deleteById(Integer id);
<delete id="deleteById" parameterType="java.lang.Integer">
DELETE FROM user where id = #{uid}
</delete>
02 小插曲 ognl apache 提供的一种表达式语言
Object Graphic Navigation Language 对象图导航语言
按照一定的语法格式来获取数据的 对象.属性名
03 模糊查询
/**
* 根据姓名进行模糊查询
* @param username
* @return
*/
List<User> findByName(String username);
01 方式一 #{username} 【preparedStatement,推荐】
<select id="findByName" parameterType="java.lang.String" resultType="com.mybatis.domain.User">
select * from user
where username like #{username}【】
</select>
List<User> userList = userDao.findByName("%王%");【】
02 方式二 ${username} 【statement,不大推荐,使用字符串拼接】
<select id="findByName" parameterType="java.lang.String" resultType="com.mybatis.domain.User">
select * from user
where username like '%${value}%'【写法固定】
</select>
List<User> userList = userDao.findByName("王");【】
04 聚合函数查询
Integer findTotal();
<select id="findTotal" resultType="java.lang.Integer">
select count(*) from user
</select>
05 parameterType
别名,参考 TypeAliasRegistery.class 或 官方文档
06 resultType
mysql 在 window 下,不区分大小写
07 数据库列名 与实体的属性名 对应不上【】
01 查询的时候,取别名,使得别名与属性名对应
select name(列名) as username(属性名)
02 使用 resultMap
<resultMap id="userMap" type="com.mybatis.domain.User">
<!--
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
-->
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<!--
collection : 用于建立一对多中集合属性的对应关系
ofType : 用于指定集合元素的数据类型
-->
<collection property="accountList" 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="userMap">
select * from user
</select>
08 mybatis 传统dao开发(了解)
01 dao
02 daoImpl
03 sqlSession api
【mybatis-01】
01 mybatis 介绍
01 持久层框架
02 内部封装了jdbc
03 开发者只需要关注 sql
04 ORM 思想解决 实体与数据库映射的问题
02 mybatis 入门(基于xml)
01 引入依赖
01 mybatis
02 junit
03 mysql-connector-java
04 log4j
02 实体类
03 dao接口
04 映射文件 xxxDao.xml
【】xml约束从文件中拷贝
05 sqlMapConfig.xml 配置文件
【】xml约束从文件中拷贝
06 测试类
01 读取配置文件
02 sqlSessionFactoryBuilder
03 sqlSessionFactory
04 sqlSession
05 userDao = sqlSession.getMapper(UserDao.class)
06 调用方法
【】如果是增加、更新、删除,需要使用 sqlSession.commit()
07 释放资源
03 基于注解
01 删除 xxxDao.xml
02 在接口的方法上使用注解
@Select("select * from user")
List<User> findAll();
03 sqlMapConfig.xml 修改
<mappers>
<mapper class="com.mybatis.dao.UserDao"/>
</mappers>
04 自定义mybatis框架
01 涉及的知识点
工厂模式
构建者模式
代理模式
反射
自定义注解
注解的反射
xml解析
数据库元数据
元数据的反射
02 引入的依赖
01 log4j
02 dom4j
03 jaxen
04 mysql-connector-java
05 junit
03 工具类
01 XMLConfigBuilder
dom4j+xpath
解析主配置文件,将配置信息设置到 defaultSqlSession
02 Executor
负责执行 sql 语句,封装结果集
03 DatasourceUtil
数据源的工具类
04 Resources
读取配置文件
05 Mapper
用于封装查询时的必要信息(sql + 实体类的类名全路径)
06 Configuration
01 数据库信息 driver、url、username、password
02 sql 的 map 集合 <String,Mapper>
实体类、dao接口、xxxDao.xml
07 SqlSessionFactoryBuilder
根据 inputSream ,创建 SqlSessionFactory
08 SqlSessionFactory DefaultSqlSessionFactory
创建 SqlSession
09 SqlSession DefaultSqlSession
10 MapperProxyFactory
使用动态代理,增强方法
11 @Select
自定义注解
|
|