03-MyBatis进阶
一.Mybatis的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>
<!--
具体更加详情的配置请查看mybatis官网
https://mybatis.org/mybatis-3/zh/getting-started.html
-->
<!--引入外部属性文件-->
<properties resource="jdbc.properties"/>
<!--核心配置文件的全局的设置-->
<settings>
<!--开启全局的延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 如果是true,则立即加载-->
<!-- 如果是false,则按需加载-->
<!--如果小于3.4.1 则必须配置,大于:3.4.1. 可以省略-->
<setting name="aggressiveLazyLoading" value="false"/>
<!--开启二级缓存: 默认是开启状态,可以不配置-->
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<!--配置包的别名,配置好之后,该包中的类可以直接使用类名配置
比如com.mybatis.dao.User 配置的时候就可以直接写User
-->
<package name="com.mybatis.dao"/>
</typeAliases>
<!--default 可以指定用哪个环境的配置-->
<environments default="development">
<!--数据库的环境:
default; 指定默认的环境
-->
<environment id="development">
<!--事务管理: jdbc-->
<transactionManager type="JDBC"/>
<!--
dataSource: 数据源(数据库连接池)配置
type="POOLED" : 数据源的类型配置
POOLED :使用mybatis的自带数据源配置
UNPOOLED: 不使用数据源配置, 使用Connection操作数据库
JNDI:JNDI服务 数据源配置
-->
<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="AccountDao.xml"/>-->
<!-- mapper配置了package之后,对应的mapper文件要和接口在统计目录下
比如java代码中的com.mybatis.dao.UserDao中定义接口,那么对应的UserDao.xml的
mapper文件必须要和接口类名同名,且在resources中的路径也必须一致:com.mybatis.dao.UserDao.xml
这样UserDao.java和UserDao.xml在编译之后会在同级目录下,而mybatis动态代理方式正式通过这种方式
根据接口的全限定类名寻找Mapper.xml文件的
-->
<package name="com.mybatis.dao"/>
</mappers>
</configuration>
二.一对一方式查询
xml 方式 AccountDao.xml 一条sql,没有引用UserDao.xml中的查询sql
<resultMap id="accountUserResultMap" type="account">
<id column="id" property="id"/>
<association property="user" javaType="user">
<result column="user_id" property="id"/>
<result column="user_name" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findById" parameterType="int" resultMap="accountUserResultMap">
select * from account as a inner join user as u on a.uid=u.user_id where a.id = #{accountId}
</select>
三.一对多
1.xml方式
UserDao.xml
<resultMap id="userResultSplit" type="user">
<id property="id" column="user_id"/>
<result column="user_name" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<collection property="accountList" column="user_id" select="com.mybatis.dao.AccountDao.findByUid"/>
</resultMap>
<select id="findByIdSplit" parameterType="int" resultMap="userResultSplit">
select * from user where user_id = #{id}
</select>
AccountDao.xml
<select id="findByUid" parameterType="int" resultType="account">
select * from account where uid = #{id}
</select>
2.注解方式
UserDao
@Results(id="userResult", value={
@Result(id = true,column = "user_id",property = "id"),
@Result(property = "username",column = "user_name"),
@Result(property = "accountList",column = "user_id",
many = @Many(select = "com.mybatis.dao.AccountDao.findByUid",fetchType = FetchType.LAZY)),
})
@Select("select * from user where user_id = #{userId}")
User findById(Integer userId);
AccountDao
@Select("select * from account where uid = #{uid}")
List<Account> findByUid(Integer uid);
四.@SelectKey 和 @Option 实现主键回显
主键回显用于在插入数据时获取新插入数据的主键
SelectKey 方式,该方式比较通用,可以用在Mysql中或oracle中
// 保存获取主键(主键回显):
// @SelectKey 在oracle中会使用
// keyProperty: 主键的属性名
// keyColumn :主键列名
// resultType: 主键的类型
// before=false : 不是在添加之前, 添加之后查询
// before=true : 在添加之前查询
// statement: 需要执行的sql语句
// select last_insert_id() :最后一次执行添加生成的主键
xml方式:
<selectKey keyColumn="uid" keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
注解方式:
@SelectKey(statement = "select last_insert_id()",keyColumn = "user_id",keyProperty = "id",resultType = Integer.class, before=false)
@Insert("insert into user values(null ,#{username},#{password},#{sex},#{address},#{birthday})")
public void insert(User user);
Option 方式
该方式可适用于自增主键的数据库,比如mysql. oracle就不行
注解方式
@Options(useGeneratedKeys = true, keyProperty = "ID")
void insertOperateLog(OperateLog operateLog);
五.动态在注解中的使用
动态sql在xml和主机方式中都可以使用
1.注解中使用动态sql方式一:
使用 @SelectProvider 注解
定义提供类
public class UserDaoProvider {
public String findByNameAndAddressLike(String name, String address){
StringBuffer sb = new StringBuffer();
return sb.append("select * from user where 1 = 1 ")
.append(name.isEmpty()? "":" and user_name=#{param1}")
.append(address.isEmpty()?"":" and address=#{param2}").toString();
}
}
UserDao 中使用
@SelectProvider(type=UserDaoProvider.class,method = "findByNameAndAddressLike")
List<User> findByNameAndAddressLike(String name, String address);
2.注解中使用动态sql方式二
动态拼接sql,和在xml中使用一样
@Select("<script>" +
"select * from CoursewareAssociation where `ROOMID` = #{roomId} " +
"<if test='cid != 0'>" +
"and `CID` = #{cid}" +
"</if>" +
"<if test='vid >= 0'>" +
"and `VID` = #{vid}" +
"</if>" +
"</script>")
List<CoursewareAssociation> selectCoursewareAssociation(CoursewareAssociation coursewareAssociation);
六. Mybatis 的一级缓存
/**
* 一级缓存
* 1,在同一sqlSession对象范围下,两次执行同一个sql语句,第二层没有执行sql语句,说明缓存的存在
* 2.如果执行了增删改,提交操作,会清空缓存
* 3. sqlSession.clearCache();清空缓存
* 4. 一级缓存是SqlSession级别的, 必须是在一个sqlsession对象范围下才可以的得到一级缓存
*
* 一级缓存运行流程
* 第一次执行sql语句,查询到数据,在会在一级缓存中存储sql语句和数据,以 sql语句为key值, 以数据为value值
* 在第二层执行sql语句时,会先从缓存中查询 ,以sql为key查询,得到数据,直接返回,如果没有相应的sql语句,则查询数据库
*
*/
七.Mybatis 的二级缓存
/**
* 二级缓存
* 1. 是sessionFactory级别的, 可以在多个SqlSession对象共享缓存数据
* 2. 默认的是开启的
* <setting name="cacheEnabled" value="true"/>
* 3. 在需要使用二级缓存的配置映射文件中开启
* <cache/>
* 4. 需要在二级缓存中保存的pojo对象必须实现序列化接口
* User implements Serializable
* 5. 在同一namespace范围下,执行提交操作,会清空该namespace的缓存
*
* 二级缓存的工作流程
* 1,在任意一个sqlSession对象中执行了sql查询语句,当关闭sqlSession对象时,在二级缓存中保存数据:以 namespace.sql语句为key值
* 以对象为value存储
* 2. 当其他sqlSession对象执行时, 需要根据namespace.sql 查询是否存在缓存
*
*
*/
八.Mybatis 的分页助手 PageHelper
九.联合主键和外键的创建方式
create table sys_user_role(
userId int unsigned,
roleId int unsigned,
primary key(userId,roleId),
foreign key(userId) references sys_user(id),
foreign key(roleId) references sys_role(id)
);
Last updated
Was this helpful?