MyBatis框架教程「工具类的使用」

工具类的使用

上篇文章我们熟悉运用MyBatis进行增删改查,并且手写了一个mybatis的工具类,学习了一些关于单元测试和关于日志的配置,没有看的读者请移步:MyBatis框架教程「实践与工具类封装」

这篇文章我们将通过一个案例继续学习MyBatis,并且达到熟练使用工具类的目的,注意:实践开发中的项目式不会使用工具类方式开发的,但是为了让读者学习的更全面理解这个框架,我就要更认真更系统的写教程。

小案例基本思路是:

我们在 MyBatisTest.java 中进行单元测试,单元测试中调用dao层实现类UserDaoImpl中的方法。在 UserDaoImpl.java 中运用我们手写的mybatis工具类进行获取sqlsession,执行映射文件中的sql,并把查询结果返回MyBatisTest.java中的调用方法以输出显示。

mybatis工具类用来完成加载核心配置文件,创建sqlsession工厂等工作,接下来继续我们案例的完成。

1. 项目截图

2. 导入Jar包

右键项目->Build Path 添加JUnit单元测试的支持

3. 添加Log4J的配置:

# Global loggingconfigurationlog4j.rootLogger=ERROR,stdout#注意 namespace为我们自己需要日志处理的路径名log4j.logger.com.jujidi.model.User=TRACE# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p[%t]-%m%n

4. 配置文件

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTDConfig 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
 <configuration>
   <!-- 配置环境 -->
  <environments default="jujidi">
   <environment id="jujidi">
    <transactionManager type="JDBC"></transactionManager>
     <dataSource type="POOLED">
     <property name="driver" value="com.mysql.jdbc.Driver"/>
     <property name="url" value="jdbc:mysql://localhost:3306/dbname"/>
     <property name="username" value="root"/>
     <property name="password" value="root"/>
    </dataSource>
  </environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
  <mapper resource="com/jujidi/model/UserMapper.xml"/>
</mappers>
</configuration>

这是Mybatis框架的核心配置文件,其中配置了相关环境和加载映射文件,环境中确定数据源,在数据源中配置你需要链接数据库的相关信息,比如用户名、密码。映射文件就是你编写SQL的xml,通过此核心配置文件进行加载关联。

5. MyBatisUtil.java

public finalclass MybatisUtil {
  private MybatisUtil(){}
  private static final String PATH = "mybatis-config.xml";
  private static InputStream is = null;
  privates tatic SqlSessionFactory sqlSessionFactory = null;
  static{
   try{
     //加载核心配置文件
     is = Resources.getResourceAsStream(PATH);
     //创建sqlsession工厂 -->相当于connection
     sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
   }catch(IOException e){
     e.printStackTrace();
     throw new RuntimeException("加载映射文件失败可能是你的映射文件写错了原因:"+e.getMessage());
    }
  }

   //获取sqlsession -->相当于执行sql语句对象
   public static SqlSession getSqlSession(){
   return sqlSessionFactory.openSession();
   }
   public static void closeSqlSession(SqlSession sqlSession){
  if(sqlSession!=null){
   sqlSession.close();
  }
}
}

上方是一个MyBatis的工具类,根据核心配置文件创建sqlsession工厂,每一个SQL操作都要创建sqlsession工厂,我们就把创建工厂和获取sqlsession的共同代码提前出来,封装成工具类,便于以后调用。

6. UserDao.java

public interface UserDao {
 User load(Integer user_id);
 User login(Map<String , Object> map);
 User loginByUser(User user);
}

7. UserDaoImpl.java

public class UserDaoImpl implements UserDao {
 SqlSession sqlSession = null;
 @Override
 public User load(Integer user_id ) {
  try{
     sqlSession = MybatisUtil.getSqlSession();
     //User.classgetName()是获取User model的全路径名
     User user = sqlSession.selectOne(User.class.getName()+".load",user_id);
     return user;
     }catch(Exception e){
       e.printStackTrace();
       throw new RuntimeException("查询失败"+e.getMessage());
        }finally{
      MybatisUtil.closeSqlSession(sqlSession);
   }
}

@Override
public User login(Map<String ,Object> map ) {
 try{
     sqlSession = MybatisUtil.getSqlSession();
     User user = sqlSession.selectOne(User.class.getName()+".login",map);
     return user;
    }catch(Exception e){
      e.printStackTrace();
      throw new RuntimeException("登录失败"+e.getMessage());
    }finally{
     MybatisUtil.closeSqlSession(sqlSession);
   }
 }
 

@Override
public User loginByUser(User user ) {
  try{
      sqlSession = MybatisUtil.getSqlSession();
      User u = sqlSession.selectOne(User.class.getName()+".loginByUser",user);
      return;
    }catch(Exception e){
      e.printStackTrace();
      throw new RuntimeException("登录失败"+e.getMessage());
    }finally{
      MybatisUtil.closeSqlSession(sqlSession);
   }
  }   
}

上面式UserDao接口的实现类,其中有三个方法:load、login、loginByUser,这些方法都是调用工具类来获取sqlSession,利用sqlSession来执行映射文件中的SQL,并且传递相关参数。可以通过全限定类名来找到对应的映射文件SQL。

8. User.java

public class User {
    private Integer userId;
    private String userName;
    private String account;
    private String pwd;
    private Integer status;
}

注意:此处要生成getter,setter和tostring方法,为了更良好的浏览体验此处没有给出。

9. UserMapper.xml

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTDMapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jujidi.model.User">
  <sql id="jujidi">
    user_name userName,user_iduserId,account,password pwd,status
  </sql>


  <select id="load" parameterType="integer"resultType="com.jujidi.model.User">
    select 
         <include refid="jujidi"></include>
     from user where user_id=#{user_id}
  </select>

  <select id="login" parameterType="map"resultType="com.jujidi.model.User">
   select <include refid="jujidi"></include> from user where account=#{account} and password=#{password}
  </select>

  <select id="loginByUser" parameterType="com.jujidi.model.User" resultType="com.jujidi.model.User">
   select <include refid="jujidi"></include> from user where account=#{account} and password=#{pwd}
  </select>
</mapper>

对于上方的配置文件我们给出两个注意:

注意一:上方的配置文件中的sql标签:

<sql id="jujidi">
  user_name userName,user_iduserId,account,password pwd,status
</sql>

上方SQL标签,可以在下方的Select语句中通过<include>标签来引入这条sql语句。

值得注意的是,我们上一篇文章讲过如果model 中的属性名和数据库中字段名称不相同是获取不到值的,但是我们现在可以通过上方sql标签的方法解决。

也就是说我们数据库中数据字段名称为:user_name,而我们的model中User的属性名字为:userName,我们可以通过类似下方语句:

Select user_name as userName from user

添加别名的方解决,当然 as 可以省略。

注意二:

<select id="login" parameterType="map"resultType="com.jujidi.model.User">
 select <include refid="jujidi"></include> from user where account=#{account} and password=#{password}
</select>

password=#{password} 中的#{password}必须是参数map的key,#{}会默认给包含的值加上单引号

key 就是下方 MyBatisTest.java 文件中的map.put("password",value)的第一个参数。

并且 标签配置中password=#{password}中的 password(等号前的字段)要和数据库中的字段对应。

10. MyBatisTest.java:

public class MybatisTest {
UserDao userDao = null;
@Before
public void init(){
  userDao = new UserDaoImpl();
}

@Test
public void load() {
  User user = userDao.load(1);
  System.out.println(user);
}

@Test
public void login() {
  Map<String , Object> map = new HashMap<String, Object>();
  map.put("account" , "admin");
  map.put("password" , "admin");
  User user = userDao.login(map);
  System.out.println(user);
}

@Test
public void loginByUser() {
  User user = new User();
  user.setAccount("admin");
  user.setPwd("admin");
  User u = userDao.loginByUser(user);
  System.out.println(u);
 }    
}

上方是测试类,使用 @Before和 @Test 注解之前必须导入JUnit的相关Jar包,关于JUnit的介绍我们已经在前面文章讲过,可以翻翻MyBatis教程系列查看。在测试方法中分别测试3个方法,来完成对mybatis工具类的使用。

总结

这里我们已经可以熟练运用自己手写的MyBatis工具类了,而且我们掌握了单元测试基本的用法和简单的MyBatis的操作,对于工作中复杂的业务逻辑,仅仅简单的CRUD是无法胜任,我们在以后的文章将会讲解:模糊查询,动态sql语句等知识。

重要说明:实际开发中是不会使用Mybatis工具类来进行开发的,而是SSM框架整合后,通过接口代理的方式来实现对数据库的操纵。

为了使初学者对Mybatis框架有一个独立且系统的认识,所以采用这种系统的教学方式,而不是一开始就是整合我们会在学习过程中逐渐拓展,最终达到实际开发所需要的本领。

原文发布于微信公众号 - Web项目聚集地(web_resource)

原文发表时间:2018-08-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coolblog.xyz技术专栏

MyBatis 源码分析 - 插件机制

一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展。这样的好处是显而易见的,一是增加了框架的灵活性。二是开发者可以结合实际需求,对框架进行拓展...

1193
来自专栏运维小白

10.3 top命令

监控系统状态 top 命令,查看进程使用资源情况 top -c 显示详细的进程信息 top -bn1 静态显示所有进程 q 键退出,数字1显示所有核cpu,大写...

2325
来自专栏MasiMaro 的技术博文

派遣函数

驱动程序的主要功能是用来处理IO请求,而大部分的IO请求是在派遣函数中完成的,用户模式下所有的IO请求都会被IO管理器封装为一个IRP结构,类似于Windows...

1361
来自专栏编程心路

SSH框架之旅-hibernate(2)

下面展示了两种方式来删除一条记录,但建议使用第一种,先查询后删除的方式,应该避免第二种直接设置主键对应属性值的方式。

1253
来自专栏java学习

Mybatis学习笔记1

本章目录 Mybatis学习笔记1 1、mybatis的介绍 2、使用jdbc操作数据库存在的问题 3、 Mybatis的架构 4、Mybatis的入门程序 ...

4026
来自专栏weixuqin 的专栏

mybatis 学习笔记(四):mybatis 和 spring 的整合

在这里我们通过原始 dao 开发和,mapper 代理开发 dao 层两种方式来举例 mybatis 和 spring 整合的操作。

1602
来自专栏美团技术团队

聊聊MyBatis缓存机制

前言 MyBatis是常见的Java数据库访问层框架。在日常工作中,开发人员多数情况下是使用MyBatis的默认缓存配置,但是MyBatis缓存机制有一些不足之...

4687
来自专栏Felix的技术分享

《一个操作系统的实现》笔记(5)--内核雏形

1984
来自专栏linjinhe的专栏

Linux常用命令:top

1785
来自专栏码农阿宇

ASP.NET Core轻松入门之Middleware管道模型

Middleware指的是微软的的asp.net core的管道模型。其原理可以用微软官方的下图展示: ? 原理如上图,随着Request的发起,HttpCon...

3235

扫码关注云+社区

领取腾讯云代金券