深入理解MyBatis核心技术01 --- MyBatis的2种基本使用方式详解(基于注解和xml)

        在我们的日常开发中MyBatis是使用的比较多的orm框架之一,以前本患者仅仅停留在会用的层面上,但是对于一些原理性的东西基本都是知其然不知其所以然。所以最近这段时间打算和大家一起讨论一下MyBatis的一些核心原理。

       首先今天先和大家分享一下本人使用MyBatis框架的两种方法,一种是基于注解的方式,另外一种是编写xml映射文件,首次我们来到官网:https://mybatis.org/mybatis-3/     进入之后是如下图所示的界面:

        从上图中可以看到MyBatis的基本介绍,但是最重要的一点是下方的五星红旗,激动吧,MyBatis官方网站上支持中文版本的,因此我们点击五星红旗,切换到中文版本,如下图所示:

      我们首先点击上图中的项目的GIT代码库 进入到MyBatis 的下载页面,如下图所示:

       首先我们点击下载最新的版本,进入到如下图所示的界面:

        点击下方的zip包的超链接,下载MyBatis框架的包, 其中mybatis-3.5.3这个是可运行的文件,下面的两个是源码文件包。下载完成之后我们解压mybatis-3.5.3这个包,解压后的目录如下所示:

        其中我们pdf就是MyBatis的使用手册,mybatis-3.5.3.jar就是我们需要导入到程序中的jar包,lib目录下存放的是我们可能要用到的一些jar包,并不是Mybatis依赖的jar包.      

       好了,关于mybatis 的下载就先到这里了,我们先来写一个入门级的demo。

       首先打开我们的开发工具,创建一个新的Java工程,并创建相应的包结构。如下图所示(开发工具暂时用的sts):

 

        其中我们在lib目录下导入数据库驱动包和Mybatis包,同时我们还需要一个日志的工具,这里我们使用log4g,日志包可以在Mybatis框架的lib目录中找到。conf目录是存放配置文件的目录。创建好了之后我们在pojo中新建一个实体类,Fruit,该类中易功有四个属性,分别是id,name,area,color,同时我们为这四个属性创建set/get方法,以及toString方法。具体代码如下图所示:

private Integer id;
	private String fruitName;
	private String area;
	private String fruitColor;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getFruitName() {
		return fruitName;
	}
	public void setFruitName(String fruitName) {
		this.fruitName = fruitName;
	}
	public String getArea() {
		return area;
	}
	public void setArea(String area) {
		this.area = area;
	}
	public String getFruitColor() {
		return fruitColor;
	}
	public void setFruitColor(String fruitColor) {
		this.fruitColor = fruitColor;
	}
	@Override
	public String toString() {
		return "Fruit [id=" + id + ", fruitName=" + fruitName + ", area=" + area + ", fruitColor=" + fruitColor + "]";
	}

     接着我们需要准备数据了,打开mysql ,新建一个数据库mybatis,然后再新建一张fruit表,表结构如下所示:

 

     好了,数据库环境准备完成之后我们就回到开发工具中,准备我们的第一个demo了。

     emmmm.........有点不知道怎么下手,还是先打开我们下载的zip包中的pdf文档吧,我们打开文档之后选择 Getting Started

    然后可以看到如下内容  : 

         这里说的意思就是从xml来构建SqlSessionFactory这个对象,并且给了一段示例的代码 ,这段代码的意思就是获取SqlSessionFactory这个对象,首先我们把这段代码复制到我们的工程中,我们知道这段代码肯定是会产生一个SqlSessionFactory对象的,因此我们新建一个util包,在该包中新建一个工具类,将上述示例代码封装成一个方法,代码如下:

public class CommonsUtils {
	
	public static SqlSessionFactory getSqlSessionFactory() throws IOException {
		
		String resource = "org/mybatis/example/mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory =
		new SqlSessionFactoryBuilder().build(inputStream);
		return sqlSessionFactory;
	}

}

      可以看到,上述代码实在加载一个xml文件,而SqlSessionFactory对象是根据这个配置文件来创建 的,所以我们也需要一个mybatis-config.xml的配置文件,好了,回到官方文档上,我们可以看到这样一句话:

        我们可以看到 上面说从 XML 文件中构建 SqlSessionFactory 的实例非常简单,我们可以用任意的InputStream实例来加载该文件 同时可以用字符串形式的xml或者在文件系统中使用任意的 URL 形式指定路径的文本文件都可以。但是他们建议我们在类路径下创建该文件,大概的意思看懂了就可以,这里就不逐字逐句的给大家翻译了 (英语能力实在有限,详细的中文意思推荐去官网上看)。 所以我们同从官方的建议,在类路径conf下创建一个mybatis-config.xml文件,这里解释一下conf默认和类路径一致。

       那么创建好了之后我们需要在该配置文件中写一些什么东西呢? 好了 ,我们回到文档上,会发现文档上提供了一个样例。如下图所示:

我们将上述的示例复制到我们创建的xml中去。如下图所示:

        按照我们以往的开发经验来猜测,dataSource标签中的内容应该是和数据源相关的,因此这里我们将自己数据库的信息写上去即可。那么还有一个mapper标签的中的内容应该写什么呢? 我们看到官方给出的也是一个xml文件,好了,我们继续看文档,发现文档中还有一种方式构建SqlSessionFactory,不使用xml配置文件:

         这里先放一放,稍后再给大家演示这种方式。我么继续往下看文档,发现后面是告诉我们怎么从SqlSessionFactory中获取 SqlSession对象,同样的给我们提供了一段简单的代码示例,如下所示:

我们继续将上述示例代码拷贝到我们的工具类中,封装成一个方法,如下图所示:

        到这里我们应该有一种直觉,Blog肯定是一个pojo对象,理论上应该对应一张数据表,好了,我们继续往下看文档,发现下面还有一段示例代码,如下图所示:

        可以看到官方更推荐下面这种方式的用法,使用一个接口来完成查询的操作,该接口定义了查询语句的参数和查询的结果类型。好了,我们继续将上述代码拷贝到工具类中单独封装成方法,稍后我们逐一来演示这两种方式。接着我们尝试将Blog修改成本次我们自己写的实体类Fruit,修改完成之后我们的工具类CommomUtils完整的代码如下:

public class CommonsUtils {
	
	public static SqlSessionFactory getSqlSessionFactory() throws IOException {
		
		String resource = "org/mybatis/example/mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory =
		new SqlSessionFactoryBuilder().build(inputStream);
		return sqlSessionFactory;
	}
	
	public static SqlSession getSqlSession(SqlSessionFactory sqlSessionFactory) {
		try (SqlSession session = sqlSessionFactory.openSession()) {
			Fruit blog = session.selectOne(
			"org.mybatis.example.BlogMapper.selectBlog", 101);
			}
		return null;
	}
	public static SqlSession getSqlSession2(SqlSessionFactory sqlSessionFactory){
		try (SqlSession session = sqlSessionFactory.openSession()) {
			FruitMapper mapper = session.getMapper(FruitMapper.class);
			Fruit fruit = mapper.selectFruit(101);
			}
		return null;
	}

}

    好了,为我们继续往下看文档,发现了下面还有一段基于xml映射语句的示例,我们发现了该xml中有一条sql语句,如下所示:

   我们再接着往下看,下面有两段话用来解释上述xml文件:

       官方说我们在一个sql映射文件中可以声明多个sql语句,我们上面的示例代码的意思就是通过一个namespace(名称空间)指定一个xml映射文件,映射文件中定义了一条id是selectBlog的sql语句,该sql语句的传入参数是id。我们调用的方式有两种:                    第一种就是通过SqlSession 对象的selectOne方法,该方法有两个参数,第一个参数是 namespace+sql语句的id组成字符串的形式,第二个参数是sql语句的执行条件参数。                                                                                                                                    第二种方式就是通过一个接口来指定查询的sql语句,接口的所在的包对应namespace,接口中的方法名对应sql映射文件中的sql语句的id ,方法的参数就是sql语句的执行条件。好了,我们仔细看一下文档中这个地方,这里描述的两种方式不就是上述提供的示例代码嘛。因此我们将这段示例的映射文件拷贝,再类路径下新建xml文件,并且将内容稍作修改如下图所示:

       这里需要注意的是我们的namespance要和包名以及映射文件的路径保持一致。并且我们将示例文件中的内容改成我们自己定义的内容。好了,接着我们再回到mybatis-config.xml文件中,再mapper标签中指定一下FruitMapper.xml的路径,代码如下图所示:

              

        这里需要注意的是如果是使用的resourcel属性的话我们需要写相对路径,即从类路径开始写。到这里基本的准备工作已经差不多了,我们将CommonsUtils类在稍作一些修该,修改之后的代码如下所示:

public class CommonsUtils {
	
	public static SqlSessionFactory getSqlSessionFactory() throws IOException {
		
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory =
		new SqlSessionFactoryBuilder().build(inputStream);
		return sqlSessionFactory;
	}
	
	public static Fruit getFruit(SqlSessionFactory sqlSessionFactory) {
		Fruit fruit = null;
		try (SqlSession session = sqlSessionFactory.openSession()) {
				fruit = session.selectOne(
			"com.wcan.poet.mybatis.mapper.FruitMapper.selectFruit", 1);
			}
		return fruit;
	}
	public static Fruit getFruit2(SqlSessionFactory sqlSessionFactory){
		Fruit fruit = null;
		try (SqlSession session = sqlSessionFactory.openSession()) {
			FruitMapper mapper = session.getMapper(FruitMapper.class);
			fruit = mapper.selectFruit(1);
			}
		return fruit;
	}
}

修改完成之后我们在测试包test下新建一个测试类MybatisTest,并且在该类中调用utils中的getFruit方法,代码如下:

public class MyBatisTest {
	
	@Test
	public void test01() throws IOException {
		SqlSessionFactory sessionFactory = CommonsUtils.getSqlSessionFactory();
		Fruit fruit = CommonsUtils.getFruit(sessionFactory);
		System.out.println(fruit);
	}
}

       在该方法中,我们先获取一个SqlSessionFactory对象,再将该对象传入到getfruit方法中,最后返回一个Fruit对象。我们执行该方法,发现报出来一个异常,该异常信息如下所示:

org.apache.ibatis.exceptions.PersistenceException: 
	### Error building SqlSession.
	### The error may exist in com/wcan/poet/mybatis/mapper/FruitMapper.xml
	### Cause: org.apache.ibatis.builder.BuilderException: 
	Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException:
 	Error parsing Mapper XML. The XML location is 'com/wcan/poet/mybatis/mapper/FruitMapper.xml'.
  	Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. 
  	Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'Fruit'.  
  	Cause: java.lang.ClassNotFoundException: Cannot find class: Fruit
	... 35 more

       上述的异常信息就是说我们在 com/wcan/poet/mybatis/mapper/FruitMapper.xml文件中定义的Fruit类找不到,这里我们在回到Fruit类中,发现resultType属性我们写了一个Fruit ,但是没有加包名,因此Mybatis在运行的时候找不到这个类,于是我们先来加上包名,将resultType属性的值改成: com.wcan.poet.mybatis.pojo.Fruit  即可,接着我们继续执行,可以发现在控制台打印出了sql语句,但是查询结果是空的。如下图所示:

好了,到这里说明我们的代码应该没有问题了,我们在数据库中先放一条数据,

        接着再次执行一遍test01方法,发现还是返回的null对象,我们再来看一下映射文件中的SQL语句,查询条件是* 也就是说默认查询所有的字段,但是有一个问题,我们在程序中的变量名是驼峰命名方式,而数据库中则是采用下划线连接。两个并不是对应的,所以即使查询到了数据也无法封装到对象中,熟悉sql 的同学此时肯定想到了别名,是的,别名可以解决这个问题,我们修改sql语句,为每个字段加上别名,如下所示:

select id,fruit_name fruitName,area,fruit_color fruitColor  from fruit where id = #{id}

再次运行即可查询到一条结果了:

  好了,接下来我们继续调用第二种方法来查询数据,编写test02方法,代码如下:

	
	@Test
	public void test02() throws IOException {
		SqlSessionFactory sessionFactory = CommonsUtils.getSqlSessionFactory();
		Fruit fruit = CommonsUtils.getFruit2(sessionFactory);
		System.out.println(fruit);
	}

      发现同样的可以查询到数据。好了,入门程序就先介绍到这里了。明天可继续给大家讲解通过注解的方式来使用Mybatis框架,小编要去睡觉了。晚安 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值