mybatis
Mybatis
(本篇为mybaits基本概括)
 
一、概念
1.mybatis是什么
Mybatis:MyBatis 本是apache的一个开源项目iBatis,优秀的持久层框架,对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身。
2.为什么使用mybatis
首先看看有哪些持久层框架:Hibernate,jdbc,SpringDAO ,有这些为什么还要使用mybatis?
对比如下:
Hibernate:老旧的框架,不用写语句但处理复杂业务时,灵活度差, 复杂的HQL难写难理解,例如多表查询的HQL语句。
jdbc:固定模式,开发麻烦
二、基本Demo
1.导包
- mybatis-3.1.1.jar
- commons-logging-1.1.1.jar
- log4j-1.2.16.jar
- cglib-2.2.2.jar
- asm-3.3.1.jar
导入mysql/oracle开发包:mysql-connector-java-5.1.7-bin.jar
2.创建数据库表和实体类stu

3.MyBati主配置文件:src下创建:SqlMapConfig.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>
<!-- typeAliases 标签 :。。。。 -->
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理 -->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url"
                    value="jdbc:mysql://localhost:3306/hibernatetest?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    
<!-- 映射配置 -->
<mappers>
<mapper  resource="test/mapper/Stu.xml"/>
</mappers>
    
主配置中相关标签说明:
(1)typeAliases :简化书写,l例如 配置后在mapper.xml配置中resultType="test.entity.Stu" 可以直接写为 resultType="Stu"
 <typeAliases>
<package name="test.entity"></package>
</typeAliases>
(2)mapper 标签 另一种写法
<mappers> <mapper resource="test/mapper/Stu.xml"/> </mappers>
改为 使用条件:stuMapper.xml 和StuMapper接口类 都在Mapper文件夹下,并且两个都同名为StuMapper
<mappers>
<package name="test.mapper.StuMapper"/>
</mappers>
(3)延迟加载:
<!-- 全局配置参数 -->
    <settings>
        <!-- 延迟加载总开关 -->
        <setting name="lazyLoadingEnabled" value="true" />    
        <!-- 设置按需加载 -->
        <setting name="aggressiveLazyLoading" value="false" />
    </settings>
4.配置实体与表的映射文件:stuMapper.xml (路径:test/mapper/Stu.xml)
配置: CRUD
<?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"> <!-- namespace:命名空间,用于隔离sql,还有一个很重要的作用,后面会讲 --> <mapper namespace="stu">
<!-- 添加
resultMap标签
--> <!-- findById --> <select id="findById" parameterType="Integer" resultType="test.entity.Stu"> select * from stu where id=#{v} </select>
<!-- 模糊查询 findByName -->
<select id="findByName"   parameterType="String"  resultType="test.entity.Stu">
select *from stu where name like '%${value}%'
</select>
<!-- 添加 insert -->
<select id="InsertStu"  parameterType="String"  resultType="test.entity.Stu">
 insert into stu (name,age) values(#{name},#{age})
</select> 
<!-- 更新 -->
<update id="updateById" parameterType="String"  resultType="test.entity.Stu">
 update stu
 set name=#{name},age=#{age}
 where id=#{ijklkd}
</update>
<!--删除-->
<delete id="deleteById" parameterType="Integer">
delete from stu
where id=#{idddd}
</delete>
</mapper>
补充:resultMap标签
当我们数据表的字段和JavaBean的属性名称不是相同时,我们就需要使用resultMap设置一下。取代resultType
写法:
<resultMap id="userListResultMap" type="Stu" >
<!-- 列名
当实体类是id_ ,而数据库中是id时
当实体类是username_,而数据库中是username时
当实体类是birthday_ ,而数据库中是birthday时
-->
<id column="id_" property="id"/>
<result column="username_" property="username"/>
<result column="birthday_" property="birthday"/>
</resultMap>
resultMap和resultType区别
resultType :指定输出结果的类型(pojo、简单类型、hashmap..),将sql查询结果映射为java对象 。(<select id="InsertStu" parameterType="String" resultType="Stu">)
resultMap:将sql查询结果映射为java对象。(<select id="InsertStu" parameterType="String" resultType="userListResultMap">)
- 如果sql查询列名和最终要映射的pojo的属性名不一致,使用resultMap将列名和pojo的属性名做一个对应关系 (列名和属性名映射配置)
5.Test
@Test public void tes() throws IOException { String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); // ID查询 Stu selectOne = sqlSession.selectOne("stu.findById",1); System.out.println(selectOne); //结果: Stu [id=1, name=a, age=aa] // 模糊查询 List<Stu> selectOne2 = sqlSession.selectList("stu.findByName", "b"); for (Stu s : selectOne2) { System.out.println(s); } //添加 insert Stu s=new Stu(); s.setName("adsaasd"); s.setAge("sddsad"); sqlSession.insert("stu.InsertStu", s); sqlSession.commit(); //更新 Stu s1=new Stu(); s1.setId(6); s1.setName("cccscscsc"); s1.setAge("aaasds"); sqlSession.update("stu.updateById", s1); sqlSession.commit(); //删除 sqlSession.delete("stu.deleteById",5); sqlSession.commit(); inputStream.close(); sqlSession.close();
6.工作流程:
(1)通过Resources对象读取Mybatis映射文件 ( String resource = "sqlMapConfig.xml";)
(2)通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象 ( SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);)
(3)获取当前线程的SQLSession ( SqlSession sqlSession = sqlSessionFactory.openSession();)
(4)事务默认开启
(5)通过SQLSession读取映射文件中的操作编号,从而读取SQL语句
(6)提交事务 (sqlSession.commit();)
(7)关闭资源测试类test(inputStream.close(); sqlSession.close();)
7.分页测试
分页操作: 当需要接收多个参数的时候,我们使用Map集合来装载! 1.映射文件中添加 <select id="listCategory" resultType="Category"> select * from category_ <if test="start!=null and count!=null"> limit #{start},#{count} </if> </select> 2.test public class Test { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); xmlWay(session); session.commit(); session.close(); } private static void xmlWay(SqlSession session) { Map<String,Object> params = new HashMap<>(); params.put("start", 0); params.put("count", 5); List<Category> cs =session.selectList("listCategory", params); for (Category c : cs) { System.out.println(c); }
三、优化
1.Mapper动态代理
使用接口类
(1)创建一个 接口类 :StuMapper (路径:test.mapper.StuMapper)
package test.mapper; import test.entity.Stu; public interface StuMapper { public Stu findById(Integer id); public Stu findByName(String name); public void InsertStu(Stu stu); public void updateById(Stu stu); public void deleteById (Integer id); }
(2)修改:把stu。xml中配置name改为 Stumapper的路径 (<mapper namespace="test.mapper.StuMapper">)
(3)stu.xml不变,主配置文件不变
(4)test
@Test
public void testMapper() throws IOException{
String resource = "sqlMapConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); StuMapper mapper = sqlSession.getMapper(StuMapper.class); /* 1. Stu s = mapper.findById(2); System.out.println(s);*/ /* 2. Stu s = mapper.findByName("b"); System.out.println(s);*/ /*3.
Stu s1=new Stu(); s1.setId(6); s1.setName("aaaaaaaascsc"); s1.setAge("aaasds"); mapper.updateById(s1); sqlSession.commit();*/ /*4. mapper.deleteById(7); sqlSession.commit();*/ inputStream.close(); sqlSession.close();
2.动态SQL
(1)if where
<!-- 通过name和age查找 --> <select id="selectStuByAgeAndName" parameterType="Stu" resultType="Stu">
select *from stu <where> <if test="name!=null and name!=''"> name=#{name} and </if> <if test="age!=null and age!=''"> age=#{age} </if> </where> </select>
(2)SQL片段 (提取重复语句)
<sql id= "selectSql">
select *from stu
</sql>
<select id="findById" parameterType="Integer" resultType="Stu">
<include refid="selectSql"/>
where id=#{v}
</select>
(3)foreach
delete from students where id in <foreach collection="array" open="(" close=")" separator="," item="ids"> #{ids} </foreach>
3.一对多、多对多
参考:https://segmentfault.com/a/1190000013690643#articleHeader6
4.缓存
- mybatis一级缓存是一个SqlSession级别,sqlsession只能访问自己的一级缓存的数据。一级缓存默认开启。
- 二级缓存是跨sqlSession,是mapper级别的缓存,对于mapper级别的缓存不同的sqlsession是可以共享的。
二级缓存 :
(1)mybatis二级缓存需要将查询结果映射的pojo实现 java.io.serializable接口
(2)开启
 <!-- 全局配置参数 -->
    <settings>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>(3)禁用
在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。、、
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">5.逆向工程
使用工程包
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号