美文网首页
Java学习day-60:MyBatis框架(2)

Java学习day-60:MyBatis框架(2)

作者: 开源oo柒 | 来源:发表于2019-10-15 21:48 被阅读0次

一、MyBatis中标签和属性的配置:

1.TypeAliases标签配置别名:

用于给 java 类型定义别名, 方便在配置文件中使用。

  • 使用方式:
    (1)type属性中为全限定类名,alias属性中为别名;
<!-- typeAliases给类型起别名 --> 
<typeAliases>  
<!-- 给User类起别名为user -->  
<typeAlias type="com.bjsxt.pojo.User" alias="u" /> 
</typeAliases> 

(2) <typeAlias>中, 可以省略 alias 属性, 表示类别名为类名, 大小写不敏感 。

<typeAliases> 
 <!-- 给User类起别名, 别名为user -->
  <typeAlias type="com.bjsxt.pojo.User" /> 
</typeAliases> 

(3) 可以通过<package>给整个包下的所有类定义别名为类名

<typeAliases>  
<!-- 给包下的所有类定义别名为类名 -->  
<package name="com.bjsxt.pojo" /> 
</typeAliases> 

2.配置parameterType属性:

如果执行的是条件查询, 需要在调用方法时传参数进来, 此时, 可以在select标签中通过parameterType属性指定参数的类型;而在 SQL 语句中, 可以通过#{}的方式获取参数。

(1)通过@Param标签查询:

/**
     * 多参数使用@param注解
     * @param map
     * @return
     */
    User selByNameandPass2(@Param("username")String userName, @Param("userpass")String userPass);
<select id="selByNameandPass2" resultType="user">
    select * from t_user where userName = #{username} and userPass = #{userpass} 
    </select>
@Test
    public void selectByNameAndPass2() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selByNameandPass2("张三", "123");
        System.out.println(user);
    }
结果

(2)使用Map集合封装属性:

<select id="selByNameandPass" resultType="user" parameterType="java.util.Map">
    select * from t_user where userName = #{userName} and userPass = #{userPass} 
    </select>
@Test
    public void selectByNameAndPass() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        Map<String, String> map = new HashMap<String, String>();
        map.put("userName", "张三");
        map.put("userPass", "123");
        User user = mapper.selByNameandPass(map);
        System.out.println(map);
    }
结果

(3)封装为对象:

<select id="sel" resultType="user" parameterType="user">  
<!-- 如果参数是对象, 可以通过#{属性名}来获取 -->  
select * from t_user where username=#{username} and password=#{password}
</select> 
@Test public void sel() {  
    SqlSession session = null;  
        try {   
              session = new SqlSessionFactoryBuilder()                  
            .build(Resources.getResourceAsStream("mybatis-cfg.xml"))    
            .openSession(); 
 
        User u = new User();   
        u.setUsername("张小三");   
        u.setPassword("1234"); 
 
       User user = session.selectOne("com.bjsxt.mapper.UserMapper.sel", u);               
       System.out.println(user);  
    } catch (IOException e) {  
     e.printStackTrace();  
    } finally {  
         session.close(); 
       } 
    } 

3.MyBatis中的事务管理:

(1)事务是数据库操作的最小单元,有 ACID 的特性,应该保证一个事务的的 SQL 语句要么同时成功, 要么都不成功。
(2)MyBatis 中配置了事务管理器,type 属性设置为 JDBC;表示 MyBatis 采用和原生 JDBC 相同的事务管理机制。
(3)在 MyBatis 执行的开始时, 将自动提交功能关闭了;所以,在执行 DML 操作时, 需要手动提交事务。

  • 提取简单工具类:
package com.zlw.util;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisUtil {
    private static SqlSessionFactory factory = null;
    static {
        try {
            InputStream is = Resources.getResourceAsStream("mybatis.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession getSqlSession() {
        SqlSession session = null;
        if(factory!=null) {
            session = factory.openSession();
        }
        return session;
    }
}
  • 新增操作:
<!-- 新增 --> 
<insert id="insUser" parameterType="user">  
insert into t_user values (default, #{username}, #{password}) 
</insert>
@Test
    public void testIns() {
        SqlSession session = MyBatisUtil.getSession();
        User user = new User();
        user.setUsername("小明");
        user.setPassword("123");
        int num = session.insert("com.bjsxt.mapper.UserMapper.insUser", user);
        if (num > 0) {
            // 提交事务 
            session.commit();
            System.out.println("SUCCESS!");
        } else { // 回滚事务
        }
        session.rollback();
        System.out.println("FAILED!");
    } 
    // 关闭资源
    session.close(); 
    }
  • 修改操作:
<!-- 修改 --> 
<update id="updUser" parameterType="user">  
update t_user set username=#{username}, password=#{password} where id=#{id} 
</update> 
@Test
    public void testUpd() {
        SqlSession session = MyBatisUtil.getSession();

        User user = new User();
        user.setId(1);
        user.setUsername("张三");
        user.setPassword("1234");

        int num = session.update("com.bjsxt.mapper.UserMapper.updUser", user);
        if (num > 0) {
            System.out.println("SUCCESS");
            session.commit();
        } else {
            System.out.println("FAILED");
            session.rollback();
        }
        session.close();
    }
  • 删除操作:
<!-- 删除 -->
 <delete id="delUser" parameterType="int">  
delete from t_user where id=#{0} 
</delete> 
@Test
    public void testDel() {
        SqlSession session = MyBatisUtil.getSession();

        int num = session.delete("com.bjsxt.mapper.UserMapper.delUser", 4);
        if (num > 0) {
            System.out.println("SUCCESS");
            session.commit();
        } else {
            System.out.println("FAILED");
            session.rollback();
        }
        session.close();
    }

4.MyBatis接口绑定:

MyBatis 中,提供了一套接口绑定方案,程序员可以提供一个接口,然后提供对应接口的一个 mapper.xml 文件;MyBatis 会自动将接口和 xml 文件进行绑定,实际上就是MyBatis 会根据接口和对应的 xml 文件创建接口的实现类; 换言之, 就是可以得到接口类型的对象, 方便方法的调用。

  • 四个一致:

(1)namespace必须与Mapper接口的全限定类名保存一致(包名+类名);
(2)statement的id必须与Mapper接口中的方法名称保存一致 ;
(3)resultType的类型必须与方法的返回值类型或集合的泛型保存一致;
(4)parameterType的类型必须与Mapper中方法的参数类型保存一致 。

  • 实现方式:
    (1)定义接口:
package com.zlw.mapper;

import java.util.List;
import com.zlw.pojo.User;

public interface UserMapper {
    
    List<User> selAll();
}

(2)编写对应的映射文件:

<mapper namespace="com.zlw.mapper.UserMapper">
    <select id="selAll" resultType="user">
        select *from t_user
    </select>
</mapper> 

(3)在核心配置文件中扫描接口:

<mappers>  
  <mapper class="com.zlw.mapper.UserMapper" /> 
</mappers> 

(4)使用:

@Test
    public void selectAll() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        
        List<User> list = mapper.selAll();
        for (User user : list) {
            System.out.println(user);
        }
        session.close();
    }
结果

二、MyBatis中的动态SQL

1.if_where标签:

If:用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件。
where:用于管理 where 子句. 有如下功能:
a) 如果没有条件, 不会生成 where 关键字 ;
b) 如果有条件, 会自动添加 where 关键字 ;
c) 如果第一个条件中有 and, 去除之;

  • 使用方式:
    (1)UserMapper.xml:
<select id="sel" resultType="user">
        select *from t_user 
        <!--  
            if用于条件判断
            test属性用于设定判断条件,类似于java中if括号中的条件
        -->
        <where>
        <if test="username != null and username !=''">
            and userName = #{username}
        </if>
        <if test="userpass !=null and userpass !=''">
            and userPass = #{userpass}
        </if>
        </where>
    </select>

(2)测试:

@Test
    public void select() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper  =session.getMapper(UserMapper.class);
        
        List<User> list = mapper.sel("张小三", "1234");
        for (User user : list) {
            System.out.println(list);
        }
        session.close();
    }
结果

2.choose_when_otherwise标签:

这是一套标签, 功能类似于 switch...case... ;

  • 使用方式:
    (1)UserMapper.xml:
<!-- choose 
        按照顺序执行,第一个满足则结束,否则执行到最后一条
    -->
    <select id="sel2" resultType="user">
        select* from t_user
        <where>
            <choose>
            
                <when test="username!= null and username!= ''">
                    and username = #{username}
                </when>
                <when test="userpass!= null and userpass!= ''">
                    and userpass = #{userpass}
                </when>
                <otherwise>
                    and 1=1
                </otherwise>
            </choose>
            
        </where>
    </select>

(2)测试:

@Test
    public void select2() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper  =session.getMapper(UserMapper.class);
        
        List<User> list = mapper.sel2("李四", "1234");
        for (User user : list) {
            System.out.println(user);
        }
        session.close();
    }
结果

3.set标签:

用于维护 update 语句中的 set 子句. 功能如下:
a) 满足条件时, 会自动添加 set 关键字 ;
b) 会去除 set 子句中多余的逗号 ;
c) 不满足条件时, 不会生成 set 关键字 ;

  • 使用方式:
    (1)UserMapper.xml:
<!-- set用于修改 -->
    <update id="update" parameterType="user">
        update t_user
        <set>
            userId = #{userId},
            <if test="userName!= null and userName!= ''">
                userName =#{userName},
            </if>
            <if test="userPass != null and userPass != ''">
                userPass = #{userPass},
            </if>
        </set>
        where userId =#{userId}
    </update>

(2)测试:

@Test
    public void update() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setUserId(1);
//      user.setUserName("张三");
        user.setUserPass("1234");
        int num = mapper.update(user);
        if(num>0) {
            System.out.println("修改成功!");
            session.commit();
        }else {
            System.out.println("修改失败!");
            session.rollback();
        }
        session.close();
    }

4.trim_bind标签:

<trim> :用于在前后添加或删除一些内容,属性;
a) prefix, 在前面添加内容;
b) prefixOverrides, 从前面去除内容 ;
c) suffix, 向后面添加内容 ;
d) suffixOverrides, 从后面去除内容 ;
<bind> :用于对数据进行再加工, 用于模糊查询 。

  • 使用方式:
    (1)UserMapper.xml:
<!-- bind多用于模糊查询 -->
    <select id="sel3" resultType="user">
        select *from t_user
        <where>
        <if test="username != null and username!=''">
            <bind name="username" value="'%'+username+'%'"/>
            and username like #{username}
            </if>
        </where>
    </select>
    <!-- trim标签可以进行都种操作
            prefix: 前缀, 表示向前面添加内容
            prefixOverrides: 从前面删除内容
            suffix: 后缀, 表示向后面添加内容
            suffixOverrides: 从后面删除内容
         -->
    <update id="update2" parameterType="user"> 
        update t_user
        <trim prefix="set" prefixOverrides="" suffix="" suffixOverrides=",">
        userName = #{userName},
        </trim>
        where userId = #{userId}
    
    </update>

(2)测试:

@Test 
    public void select3() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        
        List<User> list = mapper.sel3("张", "123");
        for (User user : list) {
            System.out.println(user);
        }
        session.close();
    }
    @Test
    public void update2() {
        
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setUserId(1);
        user.setUserName("张小三");
//      user.setUserPass("");
        
        int num = mapper.update2(user);
        if(num>0) {
            System.out.println("修改成功!");
            session.commit();
        }else {
            System.out.println("修改失败!");
            session.rollback();
        }
    }
结果 结果

5.foreach和sql-include标签:

<foreach> :用于在 SQL 语句中遍历集合参数, 在 in 查询中使用,属性:
a) collection: 待遍历的集合 ;
b) open: 设置开始符号 ;
c) item: 迭代变量 ;
d) separator: 项目分隔符 ;
e) close: 设置结束符号;
<sql><include> :
          <sql>用于提取 SQL 语句, <include>用于引用 SQL 语句 ;

  • 使用方式:
    (1)UserMapper.xml:
<select id="sel4" resultType="user" parameterType="list" >
        select <include refid="mysql"></include>from t_user where userId in
        <foreach collection="list" open="(" separator="," close=")" item="item">
            #{item}
        </foreach>
    </select>
    <sql id="mysql">
        userId,userName,userPass
    </sql>

(2)测试:

@Test
    public void selectByNameAndPass2() {
        SqlSession session = MyBatisUtil.getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = mapper.selByNameandPass2("张小三", "1234");
        System.out.println(user);
    }
结果

三、MyBatis的缓存机制:

MyBatis的缓存是使用SQL标签的ID作为缓存的唯一标识的;执行相同的标签可以使用缓存;不同的标签不能使用缓存。
优点: 缓存用于提高查询的效率。

1.一级缓存:

默认开启;线程级别的缓存, SqlSession 的缓存;
在一个 SqlSession 生命周期中有效. SqlSession 关闭;缓存清空。

  • 代码示例:
<mapper namespace="com.zlw.mapper.UserMapper">
    
    <select id="selAll" resultType="user">
        select* from t_user
    </select>
</mapper>
@Test
    public void Sel() throws IOException {
        InputStream is =  Resources.getResourceAsStream("mybatis.xml");
        
        SqlSessionFactory factory =  new SqlSessionFactoryBuilder().build(is);
        SqlSession session =  factory.openSession();
        List<User> list = session.selectList("com.zlw.mapper.UserMapper.selAll");
            System.out.println(list);
            
        
        List<User> list2 = session.selectList("com.zlw.mapper.UserMapper.selAll");
            System.out.println(list2);
        session.close();
    }
结果

2.二级缓存:

a) 进程级别的缓存, SqlSessionFactory 的缓存 ;
b) 在一个 SqlSessionFactory 生命周期中有效. 可以在多个SqlSession 生命中期中共享。
c) 默认关闭, 需要使用的时候, 要为某个命名空间开启二级缓存(在 mapper.xml 中配置<cache>);

  • 代码示例:
<mapper namespace="com.zlw.mapper.UserMapper">
    <cache></cache>
    <select id="selAll" resultType="user">
        select* from t_user
    </select>
</mapper>
@Test
    public void Sel() throws IOException {
        InputStream is = Resources.getResourceAsStream("mybatis.xml");

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        SqlSession session = factory.openSession();
        List<User> list = session.selectList("com.zlw.mapper.UserMapper.selAll");
        System.out.println(list);
        session.close();
        SqlSession session2 = factory.openSession();
        List<User> list2 = session2.selectList("com.zlw.mapper.UserMapper.selAll");
        System.out.println(list2);
        session2.close();
    }
结果

相关文章

网友评论

      本文标题:Java学习day-60:MyBatis框架(2)

      本文链接:https://www.haomeiwen.com/subject/knhemctx.html