Mybatis全面学习资料

8 篇文章 0 订阅
5 篇文章 0 订阅

Mybatis全面学习资料:

mybatis是什么:

​ 更加简化jdbc代码,简化持久层,sql语句从代码中分离,利用反射,将表中数据与java bean 属性一一映射 即 ORM(Object Relational Mapping 对象关系映射)。

特点:

半自动化:
  • 表需要手动进行设计

  • 提供sql

  • 依赖与数据库平台

  • 优点:学习使用简单(基于原生jdbc封装),优化灵活,适合做互联网项目

mybatis环境搭建(导入jar包):(连接oracle数据库)

官网: https://mybatis.org/mybatis-3/zh/index.html

导包

​ 需要导数据库驱动ojdbc6的包,mybatis的包,以及mybatis用到的包

image01

核心配置文件:

<?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>
    <environments default="myOracle">
        <environment id="myOracle">
            <transactionManager type="JDBC"/>
            <!--数据库连接池-->
            <dataSource type="POOLED">
                <!--连接信息-->
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
                <property name="username" value="SCOTT"/>
                <property name="password" value="TIGER"/>
            </dataSource>
        </environment>
    </environments>

    <!--sql映射文件-->
    <mappers>
        <mapper resource="com/shsxt/mappers/user.xml"/>
    </mappers>
</configuration>

mybatis sql映射文件:

<?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="com.shsxt.mappers.user">
   <select id="findAll" resultType="com.shsxt.pojo.User">
   		 select * from usertest
  </select>
    
</mapper>

测试:

public static void main(String[] args) throws IOException {
        //加载主配置文件
        InputStream in = Resources.getResourceAsStream("mybatis.xml");
        //得到工厂对象
        SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
        //得到SqlSession对象
        SqlSession session = factory.openSession();
        //调用方法
        List<String> list = session.selectList("com.shsxt.mappers.user.findUname");
        list.forEach(System.out::println);
        //关闭资源
        session.close();
    }

三种查询方式:

selectList("命名空间.id");
selectList("命名空间.id",Object obj);//Object obj为传入参数
    
selectOne("命名空间.id"); 
selectOne("命名空间.id",Object obj);//Object obj为传入参数

selectMap("命名空间.id",key的字段名);
selectMap("命名空间.id",key的字段名,Object obj);//Object obj为传入参数

主配置文件:

<!ELEMENT configuration (properties?,
                         settings?, 
                         typeAliases?, 
                         typeHandlers?, 
                         objectFactory?, 
                         objectWrapperFactory?, 
                         reflectorFactory?, 
                         plugins?, 
                         environments?, 
                         databaseIdProvider?, 
                         mappers?)>
对连接数据库的操作进行软编码:
<properties resource="db.properties"></properties>//导入外部db.properties文件,实现软编码
    
    
    
    <environments default="myOracle">
        <environment id="myOracle">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
  
设置类的别名:
  <typeAliases>
      <!--com.shsxt.pojo下面的Emp类的别名为e,大小写不敏感-->
        <typeAlias type="com.shsxt.pojo.Emp" alias="e"></typeAlias>
      <!--没有给alias属性,默认别名为类名,大小写不敏感-->
        <typeAlias type="com.shsxt.pojo.Emp"></typeAlias>
      <!--整个pojo包下面的类都设置别名,别名为类名,大小写不敏感-->
        <package name="com.shsxt.pojo"/>
    </typeAliases>
Mybatis自带映射关系:
别名*映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator
<mapper namespace="com.shsxt.mappers.GoodsMapper">
    
sql映射文件xml利用根标签namespace的值进行标识,
    

DML语句分析:

例select语句:

<select id="find" resultType="" parameterType="" >
        select * from tablename
</select>

id为方法的唯一标识

resultType返回结果类型

parameterType 传入参数类型

默认增删改返回值都是 影响行数

如果执行的是条件查询,DML,需要在调用方法的时候传递参数,此时, 可以在sql标签中通过parameterType属性指定参数的类型(别名|权限定名).在sql语句,通过#{}的方式获取参数。

parameterType入参类型:

parameterType: 基本数据类型(四类八种) 包装类 String, Date, Javabean,Map ,List ,数组 …

入参类型为List,数组是需用使用到foreach

foreach遍历参数list或者数组:

​ collection=“array” 参数类型 array | list
​ item : 指代每次循环从集合或者数组中拿出的数据(变量名)
​ separator: 每个数据之间额分隔符
​ open: 所有遍历输出的的数据之前以什么内容开始
​ close : 所有遍历输出的的数最后以什么结束

resultType结果类型:

基本数据类型(包装类) String, Date, JavaBean, List ,Map ,List-Map List可以实现多表查询。

**接口绑定方案:

实现方式:

定义接口:
/*
* 接口定义了对用户的操作 
*/ 
public interface UserMapper { 
    //查询所有用户 
    public List<User> queryAll(); 
}
映射文件:

1.xml文件名要与接口名保持一致

2.namespace属性值必须与接口的全限定名相同

3.语句的id属性必须要与抽象方法名保持一致

4.返回值类型和参数类型与方法的返回值和参数保持一致

<?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: 对应的接口的权限定名相同 -->
<mapper namespace ="com.shsxt.mapper.UserMapper"> 
        <!-- id 与 方法名一致 -->
		<select id="queryAll" resultType="User"> 
        		select * from t_user 
        </select> 
 </mapper>
在核心配置文件中扫描接口:

三种方式:

 <!--sql映射文件-->    
 <mappers>
     //扫描单个xml文件
     <!--        <mapper class="com.shsxt.mappers.GoodsMapper"></mapper>-->
     <!--        <mapper resource="com/shsxt/mappers/GoodsMapper.xml"/>--> 
         //扫描包下所有xml文件
         <package name="com.shsxt.mappers"/>    
 </mappers>
使用:
/** 测试接口绑定 */ 
@Test 
public void test(){ 
    SqlSession session = MybatisUtils.getSession(); 
    //getMapper()获取接口实现类对象,参数为接口的class对象,通 过参数指定接口 
    UserMapper mapper =session.getMapper(UserMapper.class); 
    //通过对象调用方法 
    List<User> list = mapper.queryAll(); 
    System.out.println(list); session.close(); 
}

通过接口绑定解决多参数传递问题 :

方式一:

接口定义方法

User selByUP(String username, String password);

映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{arg+数字},从arg0开始,或#{param+数字},从param1开始,的方式.

<select id="selByUP" resultType="user"> 
    select * from t_user where username=#{param1} and 
    password=#{param2} 
</select>
方式二:

接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语

句中使用。

接口中:

public List<Emp> findbyDeptno(@Param("deptno1") int deptno1,@Param("deptno2") int deptno2);

映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过

#{参数名称}或#{param+数字}的方式.

<select id="findbyDeptno" resultType="E">
        select * from emp where deptno in (#{deptno1},#{deptno2})
    </select>

批量操作:

批量新增:

插入时使用insert into table select 值1,值2 from dual union select 值1‘,值2’ from dual…

接口中:

public Integer insertDeptMore(List<Dept> depts);

xml文件中:

 <!--批量插入-->
    <insert id="insertDeptMore">
        insert into dept
        <foreach collection="list" item="item" separator="union">
            select #{item.deptno},#{item.dname},#{item.loc} from dual
        </foreach>
    </insert>
批量修改:

update table set 字段1=? where 字段2=?…foreach循环操作

begin

end;

接口中:

public Integer updateDeptMore(List<Dept>depts);

xml文件中:

 <!--批量更新-->
    <update id="updateDeptMore">
        <foreach collection="list" item="item" separator=";" open="begin" close=";end;">
            update dept set loc=#{item.loc}  where deptno=#{item.deptno}
        </foreach>
    </update>
批量删除:

delete table where 字段 in(foreach)

接口中:

public Integer deleteDeptMore(int[]deptno);

xml文件中:

 <!--批量删除-->
    <delete id="deleteDeptMore">
        delete dept where deptno in(
        <foreach collection="array" item="item" separator=",">
            #{item}
        </foreach>
        )
    </delete>

动态SQL:

if:

用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件。

<select id="sel" resultType="user"> 
    select * from t_user where 1=1 
    <if test="username != null and username != ''"> 
        and username=#{username} </if> 
    <if test="password != null and password != ''">
            and password=#{password} </if> 
</select>
 select * from emp
        <where>
            <if test="ename!=null and ename !=''">
                and ename=#{ename}
            </if>
            <if test="deptno!=0 and ename !=''">
                and deptno=#{deptno}
            </if>
        </where>

where标签:

  1. 如果没有条件, 不会生成 where 关键字

  2. 如果有条件, 会自动添加 where 关键字

  3. 如果第一个条件中有 and, 去除之

 select * from emp
        <where>
            <if test="ename!=null and ename !=''">
                and ename=#{ename}
            </if>
            <if test="deptno!=0 and ename !=''">
                and deptno=#{deptno}
            </if>
        </where>

choose…when…otherwise标签:

相当于java语言中的switch …case…default,when标签自带break

 select * from emp
        <where>
            <choose>
                <when test="ename!=null and deptno!=''" >
                    ename=#{ename}
                </when>
                <when test="deptno!=0 and deptno!=''">
                    deptno=#{deptno}
                </when>
                <otherwise></otherwise>
            </choose>
        </where>

set:

常用于更新语句中.

  1. 满足条件时, 会自动添加 set 关键字

  2. 会去除 set 子句中多余的逗号

  3. 不满足条件时, 不会生成 set 关键字

update emp
	<set>
       <if test="ename!=null and ename!=''" >
             ename=#{ename},
       </if>
       <if test="deptno!=0 and deptno!=''">
             deptno=#{deptno},
        </if>
            empno=#{empno}
    </set>
        where empno=#{empno}

trim:

  1. prefix, 在前面添加内容

  2. prefixOverrides, 从前面去除内容

  3. suwix, 向后面添加内容

  4. suwixOverrides, 从后面去除内容

     <select id="findTrim" resultType="Student">
            select * from student
            <trim prefix="where" prefixOverrides="jkl" suffix="and 1=1" suffixOverrides="opo">
            jkl
                <if test="sname!=null and sname !=''">
                    and sanme=#{sname}
                </if>
            opo
            </trim>
    </select>
    

bind:

用来进行模糊查询。

<select id="findByName" parameterType="String" resultType="Student">
     select * from student
    <where>
        <if test="sname!=null and sname!=''">
             <bind name="sname" value="'%'+sname+'%'"/>
                 sname like #{sname}
        </if>
     </where>
</select>

foreach:

  1. collection: 待遍历的集合

  2. open: 设置开始符号

  3. item: 迭代变量

  4. separator: 项目分隔符

  5. close: 设置结束符

select * from student where id in(
            <foreach collection="list" item="item" separator="," >
                #{item}
            </foreach>
        )

sql…include:

用于提取SQL语句的。

 <sql id="haha">sid,sname,s.cid,cname</sql>
    
     <select id="findAll" resultMap="student_map">
        select <include refid="haha"/> from student s join clazz c on s.cid=c.cid
    </select>

Mybatis缓存机制:

一级缓存:

在SqlSession生命周期中有效,

线程级别的缓存。

SqlSession关闭,缓存清空

​ 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 直接从 Map中获取数据;

​ 不同的 SqlSession 之间的缓存是相互隔离的;任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

用一个 SqlSession, 可以通过配置使得在查询前清空缓存flushCache=“true”

session.clearCache(); //session缓存刷新

 <select id="testFind" resultType="com.shsxt.pojo.Emp" flushCache="true">   //缓存刷新

二级缓存:

进程级别的缓存,SqlSessionFactory的缓存

在一个SqlSession生命周期中有效,可以在多个SqlSession生命周期中共享

默认关闭的,需要在使用的时候为某个命名空间

在session第一次关闭的时候进行缓存

<!--主配置文件中-->
<!--默认开启项目下的二级缓存-->
 <setting name="cacheEnabled" value="true"/>
    
mapper文件中:
     <!--开启二级缓存,要求实体类进行序列化-->
    <cache/>

列名和属性名不一致问题:

列别名:

select ename name from emp 

使用resultMap:

<resultMap id="student_map" type="student">
        <id column="sid" property="sid"/>     <!--主键-->
        <result column="sname" property="sname"/>
        <result column="age" property="age"/>
        <result column="cid" property="cid"/>
</resultMap>

关系映射查询:

一对一:

association:

 <resultMap id="student_map" type="student">
        <id column="sid" property="sid"/>     <!--主键-->
        <result column="sname" property="sname"/>
        <result column="age" property="age"/>
        <result column="cid" property="cid"/>
        <association property="clazz" javaType="Clazz">
        <id column="cid" property="cid"/>         <!--主键-->
        <result column="cname" property="cname"/>
        </association>
    </resultMap>

一对多:

collection :

<resultMap id="clazz_map" type="Clazz">
        <id property="cid" column="cid"/>
        <result property="cname" column="cname"/>
        <collection property="list" javaType="list" ofType="Student">
            <id property="sid" column="sid"/>
            <result property="sname" column="sname"/>
            <result property="age" column="age"/>
            <result property="cid" column="cid"/>
        </collection>
    </resultMap>

注解开发:

@select

​ 查询语句

@Select("select * from emp")
List<Emp>testfind2();

@Insert

​ 插入语句

@Insert("insert into student values(#{sid},#{sname},#{age})")
public int register(Student student);

@Update

​ 更新语句

@Update("Update student set sname=#{sname} where sid=#{sid}")
public int update(@Param("sname") String sname,@Param("sid") int sid);

@Delete

​ 删除语句

@Delete("Delete student where sid=#{sid}")
public int delete(Student student);

@results

​ 相对于xml中resultMap标签

@result

​ 相当于xml中resultMap的子标签id或result

@One:

​ 一对一映射

 @Select("select * from clazz")
    @Results(value = {
            @Result(property = "cid",column = "cid",id = true),
            @Result(property = "cname",column = "cname"),
            @Result(property = "studentList", many = @Many(select = "com.shsxt.mappers.StudentMapper.findByCid"),column = "cid")
    })
    public List<Clazz>findAll();

@Many:

​ 一对多映射

@Select("select sid,sname,cid from student ")
    @Results(value = {
            @Result(column = "sid", property = "sid",id = true),
            @Result(column = "sname",property = "sname"),
            @Result(column = "cid", property = "cid"),
            @Result(property = "clazz",one = @One(select = "com.shsxt.mappers.ClazzMapper.findById"), column="cid")

    })
    List<Student>findAll();

逆向工程:

mybatis-generator是一款mybatis自动代码生成工具,可以

通过配置,快速生成pojo,mapper和xml文件.

官方网址:http://mybatis.org/generator/configreference/ xmlconfig.html

@Result(property = "cname",column = "cname"),
        @Result(property = "studentList", many = @Many(select = "com.shsxt.mappers.StudentMapper.findByCid"),column = "cid")
})
public List<Clazz>findAll();

@Many:

​	一对多映射

```java
@Select("select sid,sname,cid from student ")
    @Results(value = {
            @Result(column = "sid", property = "sid",id = true),
            @Result(column = "sname",property = "sname"),
            @Result(column = "cid", property = "cid"),
            @Result(property = "clazz",one = @One(select = "com.shsxt.mappers.ClazzMapper.findById"), column="cid")

    })
    List<Student>findAll();

逆向工程:

mybatis-generator是一款mybatis自动代码生成工具,可以

通过配置,快速生成pojo,mapper和xml文件.

官方网址:http://mybatis.org/generator/configreference/ xmlconfig.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值