文档章节

MyBatis-基本语法

 啃不动地大坚果
发布于 2017/07/21 14:13
字数 3199
阅读 68
收藏 0

----------------------------------------------------------
第一节 MyBatis生命周期
1.MyBatis的基本构成
SqlSessionFactoryBuilder(构造器) > SqlSessionFactory(工厂接口 单例) > SqlSession (> SqlMapper)

2.获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

3.创建SqlSession
1)SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.Commit();

2)通过命名信息直接获取
MYPojo mypojo = sqlSession.selectOne("com.wdw.m1.MYPojoMapper.getAllData", 3);
3)通过映射器获取
MYPojoMapper myPojoMapper = sqlSession.getMapper(MYPojoMapper.class);
List<MYPojo> lstmyPojo = myPojoMapper.getAllData(1);

4.映射器Mapper
1)首先创建java接口
2)创建xml文件
<mapper namespace="com.wdw.m1.MYPojoMapper">
    <select id="getAllData" resultMap="MYPojo" >
        select * from tb_item_param WHERE id = #{id} and item_cat_id = #{item_cat_id}
    </select>
</mapper>

5.close SqlSession

----------------------------------------------------------
第二节 MyBatis配置文件解析

1.MYbatis配置文件

<configuration>
    <properties></properties><!-- 属性 -->
    <settings></settings><!-- 设置 -->
    <typeAliases></typeAliases><!-- 类型命名 -->
    <typeHandlers></typeHandlers><!-- 类型处理器 -->
    <objectFactory type=""></objectFactory><!-- 对象工厂 -->
    <plugins></plugins><!-- 插件 -->
    <environments default=""><!-- 配置环境 -->
        <environment id=""><!-- 环境 id-->
            <transactionManager type=""></transactionManager><!-- 事物管理器 -->
            <dataSource type=""></dataSource><!-- 数据源 -->
        </environment>
    </environments>
    <databaseIdProvider type=""></databaseIdProvider><!-- 数据库厂商标识 -->
    <mappers></mappers><!-- 映射器 -->
</configuration>

2.properties
1)property子元素
<properties>
    <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
    <property name="jdbc.url" value="jdbc:mysql://:3306/s1?allowMultiQueries=true"/>
</properties>
2)resource文件引入
<properties resource="dbconfig.properties"></properties>
3)优先级
a.首先读取<property>标签中定义的属性
b.读取resource文件中配置的属性 覆盖之前取得的值
c.读取方法参数中指定的属性 覆盖之前取得的值

3.settings
cacheEnabled 全局二级缓存
lazyLoading 延迟加载开关 可以使用fetchType具体到某一个查询

<settings>
    <setting name="cacheEnabled" value="true"/>
    <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>

4.typeAliases别名
<typeAliases>
    <typeAlias alias="Driver" type="com.mysql.jdbc.Driver"/>
    <package name="com.mysql.jdbc"/>类数量很多的时候可以使用package批量指定别名 即默认为类名的全小写
</typeAliases>

5.environments配置环境

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
        <property name=autoCommit" value="false"/>
    </transactionManager>
      <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>
  <environment id="test">
      ...
  </environment> 
</environments>

1)default指明要使用的环境ID
2)transactionManager 有3种type
JDBC JDBC方式管理事物
MANAGEN 不提交或回滚一个连接、让容器来管理事务的整个生命周期 JNDI等
自定义 
3)dataSource有四种方式
UNPOOLED 不使用连接池
POOLED 连接池数据库
JNDI JNDI数据源
自定义数据源 
通常我们会使用第三方连接池插件 需要实现DataSourceFactory接口
并要指定全类名<dataSource type="com.XXX.XXX.XXX">
4)在代码中可以指定是否自动提交
sqlSessionFactory.openSession(true)自动提交
sqlSessionFactory.openSession(false)不自动提交

6.mappers
<mappers>
  <package name="com.wdw.m1"/>
  <mapper class="com.wdw.m1.MYPojoMapper"/>
  <mapper resource="MyPojo.xml"/>
  <mapper url="file:///com/wdw/m1/MyPojo.xml"/>
</mappers>

----------------------------------------------------------
第三节 MyBatis映射器文件解析
cache –命名空间的二级缓存配置
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 自定义结果集映射
parameterMap – 已废弃!老式风格的参数映射
sql –抽取可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句

<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapper">
    <select id="getJoinDataAss" resultType="com.wdw.m1.MYPojo2">
        select t2.* from tb_item_param_item t2 where t2.id= #{id} and t2.lastName= #{lastName}
    </select>
     <select id="getEmpByIdReturnMap" resultType="map">
         select * from tbl_employee where id=#{id}
     </select>
    <insert id="insData">
        insert into tb_item_param(item_cat_id,param_data,created,updated) 
            values(#{item_cat_id},#{param_data},#{created},#{updated});
    </insert>
    <update id="updData">
        update tb_item_param 
           set param_data = #{param_data},
           updated = #{updated}
         where id= #{id}
    </update>
    <delete id="delData">
        delete from tb_item_param where id= #{id}
    </delete>
</mapper>

1.指定参数名
1)直接指定参数#{id}
public Employee getEmpByIdAndLastName(@Param("id")Integer id,@Param("lastName")String lastName);
不用@Param("id")指定时 默认参数名为param1,param2,paramN
2)用map指定参数
public Employee getEmpByMap(Map<String, Object> map);
3)用对象指定参数
public Long addEmp(Employee employee);
4)使用List set 数组 指定参数
public Long addEmp(List list);
public Long addEmp(Set set);
public Long addEmp(int[] array);
5)数据的取得
mybatis内部处理参数时
单个参数:mybatis不会做特殊处理,
    #{参数名/任意名}:取出参数值。
    
多个参数:mybatis会将其封装成 一个map,
    key:param1...paramN,或者参数的索引也可以
    value:传入的参数值
    用#{param1}就是从map中取出数据
用map指定参数时 使用#{key}取出数据
用对象指定参数时 使用#{对象.属性名}取出数据
用List set 数组 指定参数时 使用#{list0}#{set0}#{array0}取出数据

mybatis有两个默认内置参数:
_parameter:代表整个参数
    单个参数:_parameter就是这个参数
    多个参数:参数会被封装为一个map;_parameter就是代表这个map
_databaseId:如果配置了databaseIdProvider标签。
    _databaseId就是代表当前数据库的别名oracle

6)返回值类型
a.返回一条记录的map;key就是列名,值就是对应的值
public Map<String, Object> getEmpByIdReturnMap(Integer id);
b.多条数据用map封装时 指定key值
@MapKey("lastName")
public Map<String, Employee> getEmpByLastNameLikeReturnMap(String lastName);

2.resultMap

<resultMap type="com.atguigu.mybatis.bean.Employee" id="MySimpleEmp">
    <!--指定主键列的封装规则
    id定义主键会底层有优化;
    column:指定哪一列
    property:指定对应的javaBean属性
      -->
    <id column="id" property="id"/>
    <!-- 定义普通列封装规则 --><!-- 其他不指定的列会自动封装 -->
    <result column="did" property="dept.id"/>
</resultMap>

<!-- resultMap:自定义结果集映射规则;  -->
<!-- public Employee getEmpById(Integer id); -->
<select id="getEmpById"  resultMap="MySimpleEmp">
    select tbl_employee.*,tbl_dept.id as did 
      from tbl_employee,tbl_dept 
     where tbl_employee.id=#{id} 
       and tbl_employee.deptid=tbl_dept.id
</select>

3.association
1)分段查询

<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpByStep">
    <id column="id" property="id"/>
    <result column="last_name" property="lastName"/>
    <result column="email" property="email"/>
    <result column="gender" property="gender"/>
    <!-- association定义关联对象的封装规则
        select:表明当前属性是调用select指定的方法查出的结果
        column:指定将哪一列的值传给这个方法
        流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,
        并封装给property指定的属性
     -->
    <association property="dept" 
        select="com.atguigu.mybatis.dao.DepartmentMapper.getDeptById"
        column="d_id"> 
    <!-- coloumn为检索条件 当有多个检索条件时 
         column="{key1=column1,key2=column2}"-->
    </association>
</resultMap>
<select id="getEmpByIdStep" resultMap="MyEmpByStep">
    select * from tbl_employee where id=#{id}
</select>

4.collection
1)嵌套结果集 即POJO中某个属性为1:N的集合类型

<resultMap type="com.atguigu.mybatis.bean.Department" id="MyDept">
    <id column="did" property="id"/>
    <result column="dept_name" property="departmentName"/>
    <!-- 
        collection定义关联集合类型的属性的封装规则 
        ofType:指定集合里面元素的类型
    -->
    <collection property="emps" ofType="com.atguigu.mybatis.bean.Employee">
        <!-- 定义这个集合中元素的封装规则 -->
        <id column="eid" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </collection>
</resultMap>


2)collection分段查询

<resultMap type="com.atguigu.mybatis.bean.Department" id="MyDeptStep">
    <id column="id" property="id"/>
    <id column="dept_name" property="departmentName"/>
    <collection property="emps" 
        select="com.atguigu.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
        column="{deptId=id}" fetchType="lazy"></collection>
</resultMap>

column为检索条件 当有多个检索条件时 column="{key1=column1,key2=column2}"
fetchType="lazy":表示使用延迟加载;- lazy:延迟- eager:立即

5.主键自增
1)useGeneratedKeys="true";使用自增主键获取主键值策略 keyProperty;指定对应的主键属性

<insert id="addEmp" parameterType="com.atguigu.mybatis.bean.Employee"
    useGeneratedKeys="true" keyProperty="id" databaseId="mysql">
    insert into tbl_employee(last_name,email,gender) 
    values(#{lastName},#{email},#{gender})
</insert>

2)Oracle不支持自增;Oracle使用序列来模拟自增

<insert id="addEmp" databaseId="oracle">
    <!-- 
    keyProperty:查出的主键值封装给javaBean的哪个属性
    order="BEFORE":当前sql在插入sql之前运行 AFTER:当前sql在插入sql之后运行
    resultType:查出的数据的返回值类型
    -->
    <selectKey keyProperty="id" order="BEFORE" resultType="Integer">
        <!-- 编写查询主键的sql语句 -->
        <!-- BEFORE-->
        select EMPLOYEES_SEQ.nextval from dual 
        <!-- AFTER:
        select EMPLOYEES_SEQ.currval from dual -->
    </selectKey>
    
    <!-- 插入时的主键是从序列中拿到的 -->
    insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL) 
    values(#{id},#{lastName},#{email}) 
</insert>

----------------------------------------------------------
第四节 MyBatis 表达式与动态sql
1)表达式
if
choose (when, otherwise)
trim (where, set)
    prefix=""          前缀 prefix给拼串后的整个字符串加一个前缀 
    prefixOverrides="" 前缀覆盖: 去掉整个字符串前面多余的字符
    suffix=""          后缀 suffix给拼串后的整个字符串加一个后缀 
    suffixOverrides="" 后缀覆盖:去掉整个字符串后面多余的字符
foreach
    collection:指定要遍历的集合:list类型的参数会特殊处理封装在map中,map的key就叫list
    item:将当前遍历出的元素赋值给指定的变量
    separator:每个元素之间的分隔符
    open:遍历出所有结果拼接一个开始的字符
    close:遍历出所有结果拼接一个结束的字符
    index:索引。遍历list的时候是index就是索引,item就是当前值
          遍历map的时候index表示的就是map的key,item就是map的值

2)动态sql标签
<where><set><bind>

3)可抽取的sql片段
<sql id="insertColumn">
    employee_id,last_name,email
</sql>
sql片段取得
<include refid="insertColumn"></include>

4)示例

<!-- where -->
<select>
	select * from tbl_employee
	<where>
	  <if test="id!=null">
	     id=#{id}
	  </if>
	  <if test="lastName!=null and lastName!=''">
	     and last_name like #{lastName}
	  </if>
	  <if test="gender==0 or gender==1">
	      and gender=#{gender}
	  </if>
	</where>
</select>
<!-- trim -->
<select>
	select * from tbl_employee
	<trim prefix="where" suffixOverrides="and">
	   <if test="id!=null">
	       id=#{id} and
	   </if>
	   <if test="lastName!=null and lastName!=''">
	       last_name like #{lastName} and
	   </if>
	   <if test="gender==0 or gender==1">
	        gender=#{gender}
	   </if>
	</trim>
</select>
<!-- choose -->
<select>
	select * from tbl_employee 
	<where>
	    <choose>
	        <when test="id!=null">
	            id=#{id}
	        </when>
	        <when test="email!=null">
	            email = #{email}
	        </when>
	        <otherwise>
	            gender = 0
	        </otherwise>
	    </choose>
	</where>
</select>
<!-- set -->
<update>
	<set>
	    <if test="lastName!=null">
	        last_name=#{lastName},
	    </if>
	    <if test="email!=null">
	        email=#{email},
	    </if>
	    <if test="gender!=null">
	        gender=#{gender}
	    </if>
	</set>
	where id=#{id} 
</update>
<!-- foreach -->
<!--public List<Employee> getEmpsByConditionForeach(List<Integer> ids);  -->
<select id="getEmpsByConditionForeach" 
        resultType="com.atguigu.mybatis.bean.Employee">
    select * from tbl_employee
    <!--
        collection:指定要遍历的集合:list类型的参数会特殊处理封装在map中,map的key就叫list
        item:将当前遍历出的元素赋值给指定的变量
        separator:每个元素之间的分隔符
        open:遍历出所有结果拼接一个开始的字符
        close:遍历出所有结果拼接一个结束的字符
        index:索引。遍历list的时候是index就是索引,item就是当前值
                      遍历map的时候index表示的就是map的key,item就是map的值
        
        #{变量名}就能取出变量的值也就是当前遍历出的元素
      -->
    <foreach collection="ids" item="item_id" separator=","
        open="where id in(" close=")">
        #{item_id}
    </foreach>
</select>


<!-- 批量保存 -->
<!--public void addEmps(@Param("emps")List<Employee> emps);  -->
<!--MySQL下批量保存:可以foreach遍历   mysql支持values(),(),()语法-->
<insert id="addEmps">
    insert into tbl_employee(
        <include refid="insertColumn"></include>
    )
    values
    <foreach collection="emps" item="emp" separator=",">
        (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
    </foreach>
</insert>
<!-- Oracle数据库批量保存: 
Oracle不支持values(),(),()
Oracle支持的批量方式 多个insert放在begin - end里面
begin
    insert into employees(employee_id,last_name,email) 
    values(employees_seq.nextval,'test_001','test_001@atguigu.com');
    insert into employees(employee_id,last_name,email) 
    values(employees_seq.nextval,'test_002','test_002@atguigu.com');
end;-->
<insert id="addEmps" databaseId="oracle">
    <foreach collection="emps" item="emp" open="begin" close="end;">
        insert into employees(employee_id,last_name,email) 
            values(employees_seq.nextval,#{emp.lastName},#{emp.email});
    </foreach>
</insert>

----------------------------------------------------------
第五节 MyBatis缓存
MyBatis的两级缓存:
1.一级缓存:(本地缓存):sqlSession级别的缓存。一级缓存是一直开启的。
        与数据库同一次会话期间查询到的数据会放在本地缓存中。
        以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;

        一级缓存失效情况(没有使用到当前一级缓存的情况,效果就是,还需要再向数据库发出查询):
        1、sqlSession不同。
        2、sqlSession相同,查询条件不同.(当前一级缓存中还没有这个数据)
        3、sqlSession相同,两次查询之间执行了增删改操作(这次增删改可能对当前数据有影响)
        4、sqlSession相同,手动清除了一级缓存(缓存清空)
           sqlSession.clearCache()但只能呢个清除一级缓存 无法清除二级缓存

2.二级缓存:(全局缓存):基于namespace级别的缓存:一个namespace对应一个二级缓存:
        工作机制:
        1、一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中;
        2、如果会话关闭;一级缓存中的数据会被保存到二级缓存中;新的会话查询信息,就可以参照二级缓
             存中的内容;只有在会话提交或者关闭后才会保存到二级缓存
        3、不同namespace查出的数据会放在自己对应的缓存中(map)
            效果:数据会从二级缓存中获取
                查出的数据都会被默认先放在一级缓存中。
                只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中
        使用:
            1)、开启全局二级缓存配置:<setting name="cacheEnabled" value="true"/>
            2)、去mapper.xml中配置使用二级缓存:
                <cache></cache>
            3)、二级缓存的POJO需要实现序列化接口
3)和缓存有关的设置/属性:
            1)、cacheEnabled=true:false:关闭缓存(二级缓存关闭)(一级缓存一直可用的)
            2)、每个select标签都有useCache="true":
                    false:不使用缓存(一级缓存依然使用,二级缓存不使用)
            3)、【每个增删改标签的:flushCache="true":(一级二级都会清除)】
                    增删改执行完成后就会清楚缓存;
                    测试:flushCache="true":一级缓存就清空了;二级也会被清除;
                    查询标签:flushCache="false":
                        如果flushCache=true;每次查询之后都会清空缓存;缓存是没有被使用的;
            4)、sqlSession.clearCache();只是清楚当前session的一级缓存;
            5)、localCacheScope:本地缓存作用域:(一级缓存SESSION);当前会话的所有数据保存在
                 会话缓存中;STATEMENT:可以禁用一级缓存;

© 著作权归作者所有

共有 人打赏支持
粉丝 3
博文 99
码字总数 67420
作品 0
其它
程序员
Jeecg开源社区/minidao

MiniDao (超轻量级JAVA持久层框架) 当前最新版本: 1.6.2 (发布日期:20170818) ###MiniDao 简介及特征 MiniDao 是一款超级轻量的JAVA持久层框架,基于 SpringJdbc + freemarker 实现,具备...

Jeecg开源社区
2017/04/14
0
0
MiniDao 1.6.4 版本发布,轻量级 Java 持久化框架

MiniDao1.6.4 版本发布,MiniDao是轻量级Java持久化框架,也是Hibernate项目辅助利器。 MiniDao 简介及特征 MiniDao 是一款超轻量的JAVA持久层框架,具备Mybatis一样的SQL能力: 支持SQL分离...

Jeecg
06/04
0
0
使用mybatis3--注解方式

1.pom.xml文件搭建mybatis3环境 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.or......

阿宇_
2015/09/17
267
0
Mybatis Plus 2.0 Beta 发布,支持 ActiveRecord

Mybatis-Plus是一款MyBatis的增强 crud 工具包,简化 增 删 改 查 操作。启动加载 XML 配置时注入单表 SQL 操作 ,为简化开发工作、提高生产率而生。Mybatis-Plus 启动注入非拦截实现、性能更...

青苗
2016/11/07
3.3K
22
Java Web学习计划

--- 本月为入门阶段,从零开始,一步一步的做出一个实用的网站。 深入学习Java语言,初步掌握前端技术,使用JSP和MySQL完成一个简单的网站 第1周 Java高级编程学习目标:
1.深入了解JDK环境...

SVD
2016/12/01
55
0

没有更多内容

加载失败,请刷新页面

加载更多

设计模式之 明确责任 观察者模式 状态模式 责任链模式

观察者模式是任务分发的一种模式。 如果认为我们设计的系统的各个模块(或子系统)的最终目的是完成共同任务,那么这个任务如何分配到多个模块的就是我们遇到的第一个问题。简单设计场合我们...

backbye
16分钟前
2
0
14-利用思维导图梳理JavaSE-大汇总

14-利用思维导图梳理JavaSE-Java基础知识大汇总 主要内容 1.对象入门 2.一切都是对象 3.程序流程控制 4.初始化和消除 5.权限访问控制 6.复用类 7.多态 8.接口与抽象类 9.内部类 10.容器 11.异...

飞鱼说编程
51分钟前
5
0
利用Lombok编写优雅的spring依赖注入代码,去掉繁人的@Autowired

大家平时使用spring依赖注入,都是怎么写的? @Servicepublic class OrderService { @Autowired private UserService userService;} 是不是很熟悉的感觉?但是呢 如果你用...

HeyS1
58分钟前
25
0
IBATIS 写BLOB字段遇到的问题

1、 首先遇到的配置问题,通过设置typeHandler 来支持写入。接下来由此引出了事务的问题。 <typeHandler jdbcType="BLOB" javaType="[B" callback="org.springframework.orm.ibatis.support....

echo-neo
今天
1
0
37. Sudoku Solver

Description tags: backtrack,hash table difficulty: hard Write a program to solve a Sudoku puzzle by filling the empty cells.A sudoku solution must satisfy all of the following......

52iSilence7
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部