Mybatis
配置步骤 :
1、创建数据库表
2、引入MyBatis依赖、MySql依赖
3、创建主配置文件
4、编写接口
5、配置mapper.xml文件
6、加载mapper.xml,通过namespace关联起来,SQL标签ID和接口里的方法名保持一致
7、配置别名,开始测试
主配置文件标签顺序
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>//日志文件配置
<setting name="lazyLoadingEnabled" value="true"/>//懒加载配置,默认为false
</settings>
<typeAliases>
<package name="com.itdfbz.entity"/>//配置别名
</typeAliases>
//数据库配置
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF8"></property>
<property name="username" value="root"></property>
<property name="password" value="admin"></property>
</dataSource>
</environment>
</environments>
//配置Mybatis文件mapper.xml
<mappers>
<package name="com/itdfbz/utils"></package>
</mappers>
</configuration>
Mybatis中内置配置类型的区别
1、POOLED:如果将类型设置成POOLED,Mybatis会创建一个数据库连接池,连接池中的一个链接将会用作数据库操作。一旦数据库操作完成,Mybatis会将这个链接返回给连接池。在开发或者测试环境中,经常使用这种模式操作。
2、UNPOOLED:如果将类型设置成UNPOOLED,Mybatis会为每一个数据库创建一个新链接并关闭它。这种模式适用于只有小规模数量并发用户的简单应用程序。
3、JNDI:如果将类型设置成JDNI,Mybatis从在应用服务器向配置好的JNDI数据源DataSource获取数据库链接。在生产环境中,优先考虑这种方式。
配置过程中小心的坑
注意:
1、当mapper中class引入文件只能用点,而且不需要带文件扩展名
2、当mapper中resource引入文件只能用斜杠,而且需要带文件扩展名
动态SQL标签
1、if标签
<if test="user.username!=null">
WHERE username=#{user.username}
</if>
当test里面的表达式成立,执行if标签里面的语句
2、where标签
<select id="findByCriteria" parameterType="criteria" resultType="user">
SELECT * from user
<where>
<if test="user.username!=null">
and username=#{user.username}
</if>
<if test="start!=null">
and birthday >= #{start}
</if>
<if test="end!=null">
and birthday <= #{end}
</if>
</where>
</select>
会自动添加where关键字,并去除and关键字
3、foreach标签
<select id="findByCriteriaIds" parameterType="criteria" resultType="user">
select * from USER
<where>
<if test="ids!=null and ids.size>0">
id in
<foreach collection="ids" separator="," item="id" open="(" close=")">
#{id}
</foreach>
</if>
</where>
</select>
foreach参数介绍
1、collection 需要遍历的值
2、separator 分隔符
3、item 定义临时变量名
4、open 开始遍历符
5、close 结束遍历符
6、index 遍历下标(索引)
映射
一对一映射
接口类
//映射部分
<resultMap id="accountMap" type="account">//id代表下面查询语句的resultMap的临时变量名,type代表返回的类型(主表实体类)
<id property="accountId" column="accountId"></id>//第一个参数代表实体类的别名,第二个参数代表数据库的表头名称
<result property="uid" column="uid"></result>//第一个参数代表实体类的别名,第二个参数代表数据库的表头名称
<result property="money" column="money"></result>
<association property="user" column="uid" javaType="com.itdfbz.entity.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>
</association>
</resultMap>
//查询数据SQL语句
<select id="findById" parameterType="int" resultMap="accountMap">
SELECT * FROM account a left join user u on a.uid = u.id where accountId=#{id}
</select>
一对多映射
<resultMap id="userMapper" 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="accounts" column="uid" ofType="com.itdfbz.entity.Account">
<id property="accountId" column="accountId"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
<select id="findId" parameterType="int" resultMap="userMapper">
SELECT * FROM user u left join account a on u.id = a.uid where u.id=#{id}
</select>
多对多映射
<resultMap id="roleResultMap" type="role">
<id property="id" column="rid"></id>
<result property="role_name" column="role_name"></result>
<result property="role_desc" column="role_desc"></result>
<collection property="userList" ofType="user" column="uid">
<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="findById" parameterType="int" resultMap="roleResultMap">
SELECT
u.*,
r.id roleId,
r.role_name,
r.role_desc
from
role r
left join user_role ur on ur.rid = r.id
left join user u on u.id=ur.uid
where
r.id = #{id}
</select>
ofType 与javaType 区别
1、javaType:指的是属性,譬如一个实体类里面的属性名(username,password)
2、ofType:指的是整个实体类,List集合
一级缓存机制
发送请求查询一级缓存,一级缓存查不到数据,就会发送请求查询数据库,数据库返回结果一级缓存,一级缓存返回数据给请求语句,结束一次请求。第二次请求,直接在一级缓存机制找到数据,不需要访问数据库,直接返回数据给请求语句。当执行close语句,关闭数据流,清空一级缓存机制。
二级缓存机制
首先发送请求查询二级缓存机制,二级缓存没有数据就会去查询一级缓存,一级缓存查不到数据,就会发送请求查询数据库,数据库返回结果一级缓存,一级缓存返回数据给请求语句,结束第一次请求。第二次请求,继续首先查询二级缓存机制,二级缓存没有数据就会去查询一级缓存,直接在一级缓存机制找到数据,不需要访问数据库,直接返回数据给请求语句。当执行close语句,关闭数据流,清空一级缓存机制,并把一级缓存数据序列化的存进二级缓存。下一次开启数据流,请求二级缓存,二级缓存有数据,二级缓存会反序列化的输出给请求语句。
注意:
二级缓存返回的数据结果虽然一样,但是反序列化输出的地址值不一样,所以上图的 user3 != user4