Mybatis学习笔记

SqlSessionFactoryBuilder ->SqlSessionFactory->SqlSession->SQL Mapper

SqlSessionFactoryBuilder :根据配置生成SqlSessionFactory , 构建完所有SqlSessionFactory

SqlSessionFactory:依靠工厂生成SqlSession ,单例,整个生命周期

SqlSession:可以发送SQL执行并返回结果,也可以获取Mapper接口 及时关闭

SQL Mapper:java interface+XML 给出sql映射规则,发送SQL执行并返回结果 一个SqlSession事务方法中使用,然后废弃

SqlMapConfig.xml 全局配置文件

properties(属性)

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


db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root

/*

其中 properties 配置分为 1.xml中 2.db.properties 3.程序参数 ,优先级由低到高。

*/

相应的SqlMapConfig.xml

​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​
​ ​

typeAliases 不区分大小写

<typeAliases>
​	<!-- 单个别名定义 -->
​	<typeAlias alias="user" type="com.pojo.User"/>
​	<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大小写都可以) -->
​	<package name="com.pojo"/>  //配合 @Alias("user")  为空则 首字母变小写 如:UserType  -> userType
</typeAliases>

typeHandlers 负责javatype与数据库类型转换 ,可自定义,如枚举类型转化,性别 0 men 1 weman

environments 数据源配置

<environments default="1">

​	<environment id="1">

​		<transactionManager type="JDBC">

​			<property  name="autoCommit" value="false"/>			

​		</transactionManager>

​		<dataSource type="POLLED">   //POLLED  UNPOLLED  JNDI  也可自定义  type="   替换即可  "

​			</property>   // name pwd....

​		</dataSource>

​	</environment>

​	<environment id="2">

​	</environment>

</environments>

select详解

<?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="对应DAO接口">
<select id="对应DAO接口方法名" parameterType=“Integer” resultType="org.chench.test.mybatis.model.Test">
select * from test where id = #{id}
</select>
</mapper>
/*                          可以开启驼峰命名自动映射 mapUnderscoreToCamelCase=true
namespace="对应DAO接口"
id="对应DAO接口方法名"
parameterType 类全名、别名,方法参数类型
resultType 查询返回值类型
resultMap  定义数据库表字段与POJO一一对应

*/
传递多个参数
<select id="对应DAO接口方法名" parameterType="map"  resultMap="xxx">
select * from test where id = #{id}
</select>


public List<Role> getList(Map<String,String> params);
其中  params.put("name","xxx");
​    params.put("sex","xxx");
<select id="对应DAO接口方法名" parameterType=“map” resultMap="xxx">
select * from test where name = #{name} and sex=#{sex} 
</select>


public List<Role> getList(@Param("userName")String username);
<select id="对应DAO接口方法名"  resultMap="xxx">
select * from test where name = #{userName} 
</select>
 //userName ...与Role属性一致
public List<Role> getList(Role role);
<select id="对应DAO接口方法名" parameterType="org.chench.test.mybatis.model.Role" resultMap="xxx">
select * from test where name = #{userName} and sex=#{sex} 
</select> 
​    
<resultMap id="唯一" type="对应pojo全限定名">
​    <id property="id" column="id"></id>
​    <result property="userName" column="user_name"></result>
</resultMap>
id:标识主键

插入值,并返回插入的主键值 给 传入的对象的对应属性 表设计应该设置为自增

​ ​ insert into t_tole(name,sex) values(#{roleName},#{sex})

​ int insertRole(Role role);
​ ​
​ Role r = new Role();
​ ​ r.setName();
​ ​ r.setSex();
​ myDao.insertRole®;
​ sout(r.getId()); //获取插入的记录的 主键id值

当然可以 自定义规则, 如当前表为空则置为1 ,否则当前基础上+2 此时数据库表的自增 关闭


​ ​
​ ​ select if(max(id) is null,1,max(id)+2) as newId from t_role
​ ​
​ ​ insert into t_tole(id,name,sex) values(#{id},#{roleName},#{sex})

定义参数属性不允许换行

sql元素

<sql id  = "role_columns">
id,sex,phone
</sql>

<select parameterType="long" id = "getRole" resultMap="roleMap">
	select <include refid="role_columns"/> from role where id = #{id}
</select>


<sql id  = "role_columns">
	#{prefix}.id,#{prefix}.sex,#{prefix}.phone
</sql>

<select parameterType="string" id = "getRole" resultMap="roleMap">
	select 
	<include refid="role_columns">
		<property name="prefix" value="r"></property>
	</include>
	from role where id = #{id}
</select>


<sql id  = "some_include">
​	select * from <include  refid="${tableName}" />
</sql>

resultMap 作用 :定义映射规则、级联更新、定制类型转换器等

<resultMap>   //id="唯一" type="对应pojo全限定名"
	<constructor>   //配置构造方法     有的javabean不存在无参数构造器
		<idArg>   //注入同时  为主键
		</idArg>
		<arg>
		</arg>
	</constructor>
	
	<id/>       //表明为主键  <id property="id" column="id"></id>
	
	<result/>   //定义映射规则 property="javabean属性" column="sql列名"  javaType 
	           // jdbcType    typeHandler自定义规则
	
	<association/>  //支持级联的一部分 一对一、一对多、多对多  解决一对一
                    //property="javabean属性"   column="传给dao方法的参数"  select="指向一个dao方法"
                    //这个属性在在 ProvienceDao中
                    //如:省份表 id 名字      别名表 id 别名   AliasDao  findById(Integer id)   
                    //javabean  id  名字  别名
                    //  property="别名"  column ="id"  select="com.qmylzx.base.dao.AliasDao"
                    //select*from provience where id = #{id}   select*from alias where id = #{id}
	<connection/>  //支持级联的一部分 一对一、一对多、多对多  解决一对多
                 // property="cities" column="id" select="base.dao.findCityByPid"/>

	<discriminator> //鉴别器级联 解决多对多
		<case/>
	</discriminator>
</resultMap>

public class Province {
​ private Long id;
​ private String name;
​ private Alias alias;
​ private List cities; //城市表中有一个pid字段,该字段表示这个城市是属于哪个省份的
​ //省略getter/setter
}

public interface CityMapper {
List findCityByPid(Long id);
}

discriminator 定义多个resultMap extends 标记type的javabean继承的父类

<?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="dao.ProvinceMapper">
	<resultMap id="provinceResultMapper" type="org.sang.bean.Province">
		<id column="id" property="id"/>
		<discriminator javaType="int" column="area">  // javaType   column 以这个作为区分
			<case value="1" resultMap="noodleResultMap"></case>
			<case value="2" resultMap="riceResultMap"></case>
		</discriminator>
	</resultMap>
	<resultMap id="noodleResultMap" type="org.sang.bean.Province" extends="provinceResultMapper">
		<collection property="foods" column="area" select="org.sang.db.NoodleMapper.findNoodleByArea"/>
	</resultMap>
	<resultMap id="riceResultMap" type="org.sang.bean.Province" extends="provinceResultMapper">
		<collection property="foods" column="area" select="org.sang.db.RiceMapper.findRiceByArea"/>
	</resultMap>
	<select id="getProvince" resultMap="provinceResultMapper">
	  SELECT * FROM province
	</select>

</mapper>

PS: 使用级联 超过三层 复杂度上升、查询到无用数据,造成性能下降, 为了解决这个问题考虑延迟加载

全局延迟加载:setting中设置 lazyLoadingEnable = true aggressiveLazyLoading=ture

//仅开启延迟加载还是会加载所有信息 , 开启层级加载(aggressiveLazyLoading)后才会只加载一部分,即使用的部分

局部延迟加载association 、connection 属性fetchType eager、lazy

使用map存储结果集 :一般而言,任何select语句都可用map

<select id = "findColorByNote" parameterType="string" resultType="map">
	select id color note from t_color where note like  concat('%',#{note},'%')
</select>

使用POJO

缓存

系统缓存(一级缓存、二级缓存):默认开启一级缓存,即同一个SQLSession查询后,若未声明需要刷新或无缓存超时,则再次查询,只会从缓存中获取数据,而不会再次发送sql到数据库(相同的mapper、参数和方法)

往往我们需要开启二级缓存,使得在SQLSessionFactory层面上能够提供给各个SQLSession对象共享,

开启二级缓存:POJO需要可序列化(implements Serializable)、并在映射xml文件配置

PS:select语句会缓存、insert、update、delete会刷新缓存,系统使用默认的LRU算法来回收

根据时间表,如NO Flush Interval(无刷新间隔),缓存不会以任何时间顺序来刷新

缓存会存储列表集合或对象的1024个引用

缓存是可读可写的,即对象检索不共享,而且可以安全的被调用者修改

cache 的属性

eviction=“LRU” //回收策略 LRU、FIFO、SOFT软引用(基于GC)、WEAK(这里也是LRU,更积极基于GC)

flushInterva=" " //不配置默认sql执行才刷新缓存

size //引用数目,不适合太大,容易OOM

readOnly //默认为false

type=“com.qmylzx.MyCache” //自定义缓存,如使用redis 只需要实现mybatis 提供的接口类

//以下,在MyCache中若有setHost(String host) 方法,则在初始化的时候会调用

动态SQL

if //单条件分支判定

select id,name,note from t_role where 1=1 and name like concat('%',#{roleName},'%')

choose(when、otherwise) //多条件

select id,name,note from t_role where 1=1 and id=#{roleId} and note is not null

trim(where、set) // 用于处理一些sql拼装问题

   where
<select id="findRoles" parameterType="string"  resultMap="xxx">
    select id,name,note from t_role 
    <where>   //以上 if  choose where 1=1 没有会报错,这里可以用 where标签
        <if test="roleName!=null and roleName!=''">
                and name like concat('%',#{roleName},'%') 
        </if>
    </where>
</select>

   trim   去掉一些特殊字符串  prefixOverrides代表要去掉的字符串 prefix代表前缀
<select id="findRoles" parameterType="string"  resultMap="xxx">
    select id,name,note from t_role 
    <trim prefix="where" prefixOverrides="and"> 
        <if test="roleName!=null and roleName!=''">
                and name like concat('%',#{roleName},'%') 
        </if>
    </trim>
</select>


            set   防止更新某列导致的全部字段都要发送一次  ,节省带宽
<update>
 update role 
    <set>
       <if test="roleName!=null and roleName!=''">
                roleName=#{roleName}
        </if>
           <if test="sex!=null and sex!=''">
                sex=#{sex}
        </if>
    </set>
    where roleId=#{roleId}
</update>  
//以上set 可以替换为   <trim prefix="set" prefixOverrides=","> 

foreach // 在in语句等列举条件常用

select * from t_user where sex in #{sex} //其中collection为传入参数名称,可以是 数组、list、set等集合 //item是循环中当前元素,index当前元素在集合的下标

bind //用于 mybatis 自己的方式 实现自定义的函数语法,而不用关心数据库实现 mysql 的concat与oracle的 ||

<select id="findRoles" parameterType="string"  resultMap="xxx">
<bind name="pattern_roleName" value="'%'+roleName+'%'"></bind>
<bind name="pattern_note" value="'%'+note+'%'"></bind>
    select id,name,note from t_role 
    where name like #{pattern_roleName}
and note like #{pattern_note}
</select>
public List<Role> findRole(@Param("roleName")String roleName ,@Param("note")String note);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值