快速学会使用MyBatis

MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。

MyBatis封装了JDBC,并提供对象映射。他减少了几乎所有JDBC的代码和手动配置,只需要进行简单的XML或注解配置,就能灵活地完成数据库操作。

MyBatis与spring组合使用可以发挥出更加强大的作用。

MyBatis有两种使用方法:通过xml配置文件配置,或通过java注解配置。实际项目开发中,可以灵活地在两种方式间切换使用。这篇文章主要介绍xml的配置方式。

这里用一个简单的案例来演示如何使用MyBatis。


本项目环境:JDK1.8 , mybatis3.3.0,mysql。

新建java项目,导入mybatis及mysql JDBC的jar包(如需使用日志等功能还需导入其他包).如图:



在数据库中创建一张book表,有id,书名,价格三个字段,并插入几条测试数据:



在java项目中创建与数据库对应的bean类:

public class Book {
	private int id;
	private String bookName;
	private double price;

	//省略相应的GetSet、toString、构造方法、

}

到这里,准备工作就做完了。MyBatis的任务就是从数据库中查询出我们需要的数据,并映射给bean类。或反过来将bean类insert/update/delete到数据库中。

配置mybatis:

mybatis-config是mybatis的基础配置文件,需要配置jdbc连接方式,引用所有mapper文件。

工程下新建一个mybatis-config.xml配置文件:

<?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>

	<!-- settings元素下是一些高级选项,可以改变mybatis运行中的行为。非必须 -->
	<settings>
		<!-- 开启数据库中下划线命名字段对java类中驼峰命名的映射关系。如:book_name与bookName互相映射 -->
		<setting name="mapUnderscoreToCamelCase" value="true" />
	</settings>
	
	<!-- 给长字符串起一个别称。非必须 -->
	<typeAliases>
		<typeAlias alias="book" type="com.lxy.beans.Book" />
	</typeAliases>

	<!-- 数据库连接环境。这里使用的是mysql的jdbc,事务管理及连接池也是用jdbc。 -->
	<!-- 这部分可由spring管理 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost/myschool" />
				<property name="username" value="root" />
				<property name="password" value="111112" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- mappers中列出所有定义的mapper文件 -->
	<mappers>
		<mapper resource="com/lxy/mappers/BookMapper.xml" />
	</mappers>
</configuration>

创建mapper文件

一个mapper文件通常与一个bean类对应,里面定义了数据表与javabean类的映射关系,以及要执行的sql语句。
其中id为方法标识,用于调用方法;resultType标识了返回值类型;parameterType标识了入参类型。

这里创建一个BookMapper.xml,并定义了两个方法:

<?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.lxy.mappers.BookMapper">

	<!-- 简单查询方法 -->
	<select id="selectAll" resultType="book">
		select * from book;
	</select>

	<!-- 新增方法 -->
	<insert id="insertBook" parameterType="book">
		insert book	(book_name,price) values(#{bookName},#{price});
	</insert>

</mapper>

测试方法

package com.lxy.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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

import com.lxy.beans.Book;

public class UserTest {

	public static void main(String[] args) throws IOException {
		// SqlSessionFactory的作用域应为整个应用的生命周期。可以使用单例实现,但通常通过spring的依赖注入实现
		InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

		// SqlSession的作用域应在线程内。给每个request重新开启一个session。
		// sqlsession有selectOne,selectList,insert,update,delete,commit,rollback等方法
		SqlSession session = factory.openSession();
		try {
			Book b = new Book("java进阶", 36.7d);
			session.insert("com.lxy.mappers.BookMapper.insertBook", b);
			session.commit();

			List<Book> lst = session.selectList("com.lxy.mappers.BookMapper.selectAll");
			for (Book book : lst) {
				System.out.println(book);
			}
		} finally {
			// 每次会话结束后关闭session
			session.close();
		}

	}
}

至此,就完成了Mybatis的基本查询及新增功能。


resultMap

mapper文件中的resultType标识了方法返回的类型,它会将数据库查询出的字段自动映射到对应名称的bean类中。

retultType可以应对大多数简单查询的情况。但如果查询情况变得复杂,比如多表联查,就需要使用resultMap来对字段进行手动映射了。

来看个例子:

现在我们将刚才的书本表稍微改造一下,关联上作者表的信息:


相应的bean类也进行改造:

public class Book {
	private int id;
	private String bookName;
	private double price;
	private Author author;

	@Override
	public String toString() {
		return "Book [id=" + id + ", bookName=" + bookName + ", price=" + price+ ", author_name=" + author.getAuthorName() + "]";
	}
	//...省略getset方法
	
}
public class Author {
	private int id;
	private String authorName;

	//...省略getset方法

}

Author的信息作为属性保存在Book类中。此时要查询出book和Author信息并映射到Book类中,该怎么实现呢?

首先在mapper中编写sql语句:

	<!-- 复杂查询 -->
	<select id="selectBookInfo" resultMap="BookMap">
		select 
		b.id as book_id,
		book_name,
		price,
		a.id as author_id,
		author_name
		from book b left join author a on b.author_id=author_id
		where b.id = #{id}
	</select>

然后手工映射BookMap:

	<resultMap type="Book" id="BookMap">
		<id property="id" column="book_id" />
		<result property="bookName" column="book_name" />
		<result property="price" column="price" />
		<association property="author" javaType="Author">
			<id property="id" column="author_id" />
			<result property="authorName" column="author_name" />
		</association>
	</resultMap>

id – 一个 ID 结果;标记结果作为 ID 可以帮助提高整体效能
result – 注入到字段或 JavaBean 属性的普通结果
association – 一个复杂的类型关联;许多结果将包成这种类型
column – 数据库表中的字段名


这样就配置完成了。写个测试方法测试一下

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;

import com.lxy.beans.Book;

public class UserTest {

	public static void main(String[] args) throws IOException {
		// SqlSessionFactory的作用域应为整个应用的生命周期。可以使用单例实现,但通常通过spring的依赖注入实现
		InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

		// SqlSession的作用域应在线程内。给每个request重新开启一个session。
		// sqlsession有selectOne,selectList,insert,update,delete,commit,rollback等方法
		SqlSession session = factory.openSession();
		try {			
			Book book = session.selectOne("com.lxy.mappers.BookMapper.selectBookInfo",5);
			System.out.println(book);
		} finally {
			// 每次会话结束后关闭session
			session.close();
		}

	}
}

输出结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值