Mybatis学习总结-02

Mybatis学习总结

学习的内容如下:

  1. 封装 MyBatis 简单工具类
  2. Mybatis 中带条件的查询
  3. 通过 Mybatis 完成增、删、改、查等操作
  4. Mybatis 中类型别名的配置

1、Mybatis 简单工具类的封装

public class MyBatisUtil {
    // 声明工厂对象
    private static SqlSessionFactory factory;

    // 通过静态代码块对工厂进行初始化, 只初始化一次
    static {
        try {
            InputStream is = Resources.getResourceAsStream("mybatis.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("工厂无法初始化...");
        }
    }

    /**
     * 获取SqlSession对象
     *
     * @return
     */
    public static SqlSession getSession() {
        return factory.openSession();
    }
}

2、Mybatis 中带条件的查询

在 Mybatis 中,提供了一些方法可以接受执行 SQL 语句时的参数,但是,不同形式的传参获取方式不同,获取方式有两种:

2.1、#{} 占位符

类似于 JDBC 中通过 PreparedStatement 进行操作的方式,会将 sql 语句中需要参数的位置使用 ? 进行占位,后续由传进来的参数进行参数的绑定,当使用 #{} 接收参数时,参数传递的方式有三种:

2.1.1、 简单类型参数的传递

简单类型指的是:基本数据类型、包装类型、String、java.sql.*等等;

当参数是基本数据类型时,Mybatis 会忽略 SQL 语句中参数的个数和占位符的名称,然后将参数进行自动绑定

parameterType属性可以定义参数的类型, 如果定义, 传参时要求参数类型必须和指定的类型一致, 否则抛出ClassCastException.

<mapper namespace="com.bjsxt.mapper">
    <select id="selById" resultType="com.j9a.pojo.User">
        select * 
        from tb_user 
        where id=#{id}
    </select>
</mapper>
@Test
public void test1() {
    SqlSession session = MyBatisUtil.getSession();

    User user = session.selectOne("selById", "2");
    System.out.println(user);

    session.close();
}
2.1.2、 Map类型参数的传递

Map是KV结构, 可以通过key定位value

当参数是 Map 集合时, SQL 语句中的 #{} 里应该写 Map 集合的 key 值, MyBatis 会通过 key 值找到 value 然后进行参数绑定. 如果 key 不存在, 不会报错, 会使用 null 进行参数绑定.

<mapper namespace="com.bjsxt.mapper">
    <select id="selByMap" resultType="com.j9a.pojo.User">
        select * 
        from tb_user 
        where username=#{username} and password=#{password}
    </select>
</mapper>
@Test
public void testLogin() {
    SqlSession session = MyBatisUtil.getSession();

    Map<String, String> params = new HashMap<>();
    params.put("username", "zhangsan");
    params.put("password", "123");

    User user = session.selectOne("selByMap", params);
    System.out.println(user);

    session.close();
}
2.1.3、对象类型参数的传递

除了简单类型和Map类型以外的其他类型。

当参数是对象类型时, SQL语句中的#{}里应该写对象的getter方法对应的属性名. 当getter不存在时, 抛出异常:

<mapper namespace="com.bjsxt.mapper">
    <select id="selByObject" resultType="com.j9a.pojo.User">
        select * 
        from tb_user 
        where username=#{username1} and password=#{password}
    </select>
</mapper>
@Test
public void testLogin2() {
    SqlSession session = MyBatisUtil.getSession();

    User params = new User();
    params.setUsername("lisi");
    params.setPassword("123");

    User user = session.selectOne("selByObject", params);
    System.out.println(user);

    session.close();
}
2.2、${}占位符

类似于jdbc中通过Statement进行操作的方式, 会直接将传递的参数和SQL语句进行字符串的拼接. 一般当SQL语句结构不确定时使用.

<select id="sel2" resultType="com.j9a.pojo.User">
    select * 
    from ${tableName} 
    where ${columnName}=${columnValue} order by ${order}
</select>
@Test
public void testSel2() {
    SqlSession session = MyBatisUtil.getSession();

    Map<String, Object> params = new HashMap<>();
    params.put("tableName", "tb_user");
    params.put("columnName", "age");
    params.put("columnValue", 18);
    params.put("order", "birthday desc");

    List<User> list = session.selectList("sel2", params);
    System.out.println(list);

    session.close();
}

3、Mybatis 实现增、删、改(CUD)操作

CUD 操作会破坏数据库中原有的数据,所以必须要进行事务管理;

事务的四大特性ACID(原子性、一致性、隔离性、持久性);

JDBC中, 通过Connection对象对事务进行管理;

  • 开启手动事务管理: Connection.setAutoCommit(false);
  • 事务提交: Connection.commit();
  • 事务回滚: Connection.rollback();

MyBatis中, 事务管理通过SqlSession对象进行.

mybatis默认的SqlSessionFactory是DefaultSqlSessionFactory,它openSession()的源码是:

public SqlSession openSession() {
        return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
    }
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;

        DefaultSqlSession var8;
        try {
            Environment environment = this.configuration.getEnvironment();
            TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            Executor executor = this.configuration.newExecutor(tx, execType);
            var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
        } catch (Exception var12) {
            this.closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
        } finally {
            ErrorContext.instance().reset();
        }

        return var8;
    }

可以看到,mybatis默认每次获取session都会开启一个事务,且不自动提交事务。如果更新操作完成后不手动commit,则在连接断开时会将更新操作回滚。

SqlSession session = MybatisUtil.getSession(); // 通过Mybatis封装工具类获取 SqlSession对象
UserMapper userMapper = session.getMapper(UserMapper.class);
try{
    UserDomain newUserDomain = new UserDomain();
    newUserDomain.setAge(10);
    newUserDomain.setName("scp2");
    newUserDomain.setSchool("高中");
    userMapper.insert(newUserDomain);
    session.commit();// 手动commit   如果不commit,连接断开时操作会被回滚
}
catch (Exception e){
    System.out.println(e);
}
finally {
    if (null != session) {session.close();}
}
3.1、增
<insert id="insUser">
    insert into tb_user values (default, #{username}, #{password}, #{realname},
    #{age}, #{birthday}, #{regTime})
</insert>
@Test
public void testAdd() {
    SqlSession session = MyBatisUtil.getSession(); // 通过SqlSession操作数据库

    User user = new User();
    user.setUsername("wukong");
    user.setPassword("111");
    user.setRealname("悟空");
    user.setAge(10);
    user.setRegTime(new Date());

    try {
        session.insert("insUser", user);
        session.commit(); // 手动commit
    } catch (Exception e) {
        e.printStackTrace();
        session.rollback();
    }

    session.close();
}
3.2、改
<update id="updateUser">
    update tb_user 
    set age=#{age} 
    where id=#{id}
</update>
@Test
public void testUpd() {
    SqlSession session = MyBatisUtil.getSession(); // 通过SqlSession操作数据库

    Map<String, Object> map = new HashMap<>();
    map.put("age", 10);
    map.put("id", 2);

    try {
        session.update("updateUser", map);
        session.commit(); // 手动commit
    } catch (Exception e) {
        session.rollback();
        e.printStackTrace();
    }

    session.close();
}
3.3、删除
<delete id="deleteUser">
    delete from tb_user where id=#{id}
</delete>
@Test
public void testDel() {
    SqlSession session = MyBatisUtil.getSession(); // 通过SqlSession操作数据库

    try {
        session.delete("deleteUser", 3);
        session.commit(); // 手动commit
    } catch (Exception e) {
        session.rollback();
        e.printStackTrace();
    }

    session.close();
}

4、Mybatis 类型别名配置

在mybatis的配置文件中加上以下内容;

<typeAliases>
    <!--<typeAlias type="com.j9a.pojo.User" alias="u" />-->
    <package name="com.bjsxt.pojo" />
</typeAliases>
4.1、密码加密
package com.j9a.util;

import java.security.MessageDigest;

public class Md5Util {
    /**
     * 接收一个明文密码, 返回加密以后的密文
     ** @param pwd
     * @return
     */
    public static String md5(String pwd) throws Exception {
        // 创建MessageDigest对象
        MessageDigest digest = MessageDigest.getInstance("MD5");
        // 对明文进行加密
        byte[] temp = digest.digest(pwd.getBytes());
        // 准备StringBuilder用于保存结果
        StringBuilder builder = new StringBuilder();
        // 遍历字节数组, 一个字节转换为长度为2的字符串
        for (byte b : temp) {
            // 去除负数
            String s = Integer.toHexString(b & 0xff);
            // 补零
            if(s.length() == 1) {
                builder.append(0);
            }
            builder.append(s);
        }
        return builder.toString();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值