MyBatis 学习笔记

 

目录

一、MyBatis 简介

二、MyBatis 的运行原理

三、搭建 MyBatis 的开发环境

四、删除和更新数据

五、原生 Dao 实现

六、MyBatis 的动态代理 -- Dao的实现

七、配置类型的别名

八、数据源写法优化

九、输入输出映射

1、输入映射

2.输出映射

十、动态 SQL 语句

十一、对单个对象映射

1.自动映射

2.手动映射

十二、对集合对象映射

十三、Spring 整合 MyBatis 框架

1.搭建环境需要准备的 jar 包文件

2.需要准备的配置文件

3.配置 Spring 的 beans.xml 核心配置文件

 4.配置数据源信息db.properties 文件

5.配置 SqlMapConfig.xml 文件

6.使用原生 Dao 实现方式来整合

7.使用 Mapper 映射文件实现


一、MyBatis 简介

【官方介绍】

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

MyBatis 主要是一个持久层框架,负责与数据库进行交互。同样功能的常用框架是 Hibernate,其中 Hibernate 是一个全自动的持久层框架,也就是不再需要我们手动写 SQL 语句了。MyBatis 是一个半自动的持久层框架,在书写映射文件的时候,还需要我们手动添加一些 SQL 语句。后面,为了优化这个操作,我们采用“逆向工程工具”来自动生成常用的操作方法,就可以免掉手写 SQL 的痛苦。

官网:http://www.mybatis.org/mybatis-3/zh/index.html 中文文档

下载:https://github.com/mybatis/mybatis-3/releases

Maven 构建:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>x.x.x</version>
</dependency>

二、MyBatis 的运行原理

每个人基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以突然荣国 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出SqlSessionFactory 的实例。

也就是,我们如果想要跟数据库打交道的话,必须要有个 sqlSession 会话对象,这个对象只能通过 SqlSessionFactory 生产出来。

三、搭建 MyBatis 的开发环境

1.下载 jar 文件,其目录如下图,包括核心 jar 包,和它依赖的其他 jar 文件。

2.新建 web 动态工程。

3.添加 MyBatis 的 SqlMapConfig.xml 核心配置文件。约束为 mybatis-3-config.dtd

<?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>
	<!-- 配置环境(可以有多个) -->
	<environments default="abc">
		<!-- 配置数据源环境 -->
		<environment id="abc">
			<!-- 事务管理器 -->
			<transactionManager type="JDBC" />
			<!-- 数据源(mybatis 自己的) -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql:///hello" />
				<property name="username" value="root" />
				<property name="password" value="1234" />
			</dataSource>
		</environment>
	</environments>
	<!-- 配置映射文件-->
	<mappers>
		<mapper resource="com/neuedu/pojo/User.xml" />
	</mappers>
</configuration>

4.新建 User 类

public class User {

	private Integer id;
	private String username;
	private String sex;
	private Date birthday; // 以后都是选择 java.util.Date 包,如果有问题,就需要额外添加转换器
	private String address;

	// 添加 get 和 set 方法
	// 添加 toString 方法
}

5.给 User 类添加一个 User.xml 映射文件 mybatis-3-mapper.dtd

<?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="test">

	<!-- 添加数据 -->
	<insert id="addUser" parameterType="com.neuedu.pojo.User">
		insert into user(username, address)  values( #{username}, #{address});
	</insert>

	<!-- id 是一个唯一标识
		resultType 是返回值类型
		parameterType 是参数类型
		timeout 设置操作的超时时间
	-->
	<select id="findUserById" resultType="com.neuedu.pojo.User" 
parameterType="java.lang.Integer">
		select * from user where id = #{id}
	</select>
	
	<!-- 模糊查询:%花%  MyBatis 的底层,默认会将 resultType 都转成集合形式。 List<User>  -->
	<select id="findUserByName" resultType="com.neuedu.pojo.User" 
parameterType="java.lang.String">
		<!-- select * from user where username like #{name} -->
		select * from user where username like '%${value}%'
	</select>
	 
</mapper>

6.添加测试类

public class UserTest {
	
	@Test
	public void fun1() throws IOException{
		// 1. 需要加载核心文件
		InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
		// 2. 获取 SqlSessionFactory 对象
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
		// 3. 获取 SqlSession 对象
		SqlSession session = factory.openSession();
		// 4. 执行 SQL
		// findUserById
		// User user = session.selectOne("findUserById", 1);
		
		// findUserByName
		// List<User> userList = session.selectList("findUserByName", "%花%");
		// List<User> userList = session.selectList("findUserByName", "花");
		//for (User user : userList) {
			//System.out.println(user);
		//}
		
		// addUser
		User user = new User();
		user.setUsername("小三");
		user.setAddress("开发区");
		
		session.insert("addUser", user);
		
		// 注意:在插入数据的时候,需要提交
		session.commit();
		
		// 5. 关闭资源
		session.close();
	}
}

四、删除和更新数据

1.编辑 User,xml 文件,添加对应的语句

<!-- 更新数据 
	修改数据的思路:先查,后改
-->
<update id="updateUserById" parameterType="com.neuedu.pojo.User">
	update user set username = #{username} where id = #{id}
</update>

<!-- 删除数据 -->
<delete id="deleteUserById" parameterType="java.lang.Integer">
	delete from user where id = #{id}
</delete>

2.编辑  User.java 测试类

// deleteUserById
session.delete("deleteUserById", 5);
session.commit();
		
// updateUserById
User user = new User();
user.setUsername("猪肉荣");
user.setId(3);
		
session.update("updateUserById", user);
session.commit();

五、原生 Dao 实现

1.新建 UserDao 接口类和 UserDaoImpl 实现类

public class UserDaoImpl implements UserDao {
	
	// 此处我们不加载核心配置文件,我们交给调用去调用,如果他要的话,再去加载。

	private SqlSessionFactory factory;

	// 通过有参构造器来初始化变量的值
	public UserDaoImpl(SqlSessionFactory factory) {
		this.factory = factory;
	}

	@Override
	public User findUserById(Integer id) throws Exception {

		// 1. 获取 SqlSession 对象
		SqlSession session = factory.openSession();
		return session.selectOne("findUserById", id);
	}

	@Override
	public List<User> findUserByName(String userName) throws Exception {

		// 1. 获取 SqlSession 对象
		SqlSession session = factory.openSession();
		return session.selectList("findUserByName", userName);
	}
}

2.编辑 UserTest 测试类

public class UserTest {
	
	private SqlSessionFactory factory;
	
	// @Before 中的内容会在执行 @Test 之前进行执行
	@Before
	public void preConfig() throws Exception {
		
		// 1. 需要加载核心文件
		InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
		
		// 2. 获取 SqlSessionFactory 对象
		factory = new SqlSessionFactoryBuilder().build(is);
	}
	
	@Test
	public void fun2() throws Exception{
		
		UserDao dao = new UserDaoImpl(factory);
		
		// 根据 id 找用户
		User user = dao.findUserById(2);
		System.out.println(user);
		
		// 根据 name 模糊查询
		List<User> userList = dao.findUserByName("花");
		
		for (User user2 : userList) {
			System.out.println(user2);
		}
	}

六、MyBatis 的动态代理 -- Dao的实现

使用前请记住:添加 mapper 包,添加 XxxMapper.java 接口类和 XxxMapper.xml 映射文件。文件的名字,必须是一致的。

1.新建 UserMapper.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.neuedu.mapper.UserMapper">

	<!-- mapper 接口代理实现需要注意的几个事项
		1. 映射文件中 namespace 中的值需要填需要映射的接口类的权限名。
		2. 映射文件中 sql 语句中的 id 值要跟接口类中的方法名一致,给调用者进行调用。
		3. 映射文件中传入的参数类型要和接口类中的方法参数类型一致。
		4. 映射文件中返回结果的类型和接口类中的方法返回值类型一致。
	-->
	<select id="findUserById" resultType="com.neuedu.pojo.User" 
parameterType="java.lang.Integer">
		select * from user where id = #{id}
	</select>
	
	<select id="findUserByName" resultType="com.neuedu.pojo.User" 
parameterType="java.lang.String">
		select * from user where username like '%${value}%'
	</select>
	
	<insert id="insertUser" parameterType="com.neuedu.pojo.User">
		insert into user (username, address ) values (#{username}, #{address})
	</insert>
	 
</mapper>

2.新建 UserMapper 接口类

public interface UserMapper {
	
	public User findUserById(Integer id);
	public List<User> findUserByName(String userName);
	public void insertUser(User user);
}

3.编辑 UserTest 测试类

public class UserTest {
	
	private SqlSessionFactory factory;
	
	// @Before 中的内容会在执行 @Test 之前进行执行
	@Before
	public void preConfig() throws Exception {
		
		// 1. 需要加载核心文件
		InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
		
		// 2. 获取 SqlSessionFactory 对象
		factory = new SqlSessionFactoryBuilder().build(is);
	}
	
	@Test
	public void fun() throws Exception{
		
		SqlSession session = factory.openSession();
		
		// 通过 getMapper() 方法来实例化接口
		// 简单理解,就是调用了方法之后,在底层会自动给一个实现类,自动执行功能
		UserMapper mapper = session.getMapper(UserMapper.class);
		
		// 根据 id 找用户
		User user = mapper.findUserById(2);
		System.out.println(user);
		
		// 根据 name 模糊查询
		List<User> userList = mapper.findUserByName("花");
		
		for (User user2 : userList) {
			System.out.println(user2);
		}
		
		// 插入数据
		User user3 = new User();
		user3.setUsername("肉肉");
		user3.setAddress("广州黄埔");
		
		mapper.insertUser(user3);
		
		session.commit();
	}
}

七、配置类型的别名

如果是自定义类的话,则需要在 SqlMapConfig.xml 核心配置文件中,通过使用 <typeAliases> 标签列设置类型的别名。

如果是基本数据类型,可以直接写对应的小写名字,即可使用。比如 String 类型,写 string;Integer 类型,写 int。

<typeAliases>
	<typeAlias type="com.neuedu.pojo.User" alias="User"/>
</typeAliases>

常见的基本和包装类型别名:

byte       _byte

long              _long

short      _short

int         _int

int          _integer

double   _double

float              _float

boolean  _bolean

 

String    string

Byte       byte

Long      long

Short      short

Integer   int

Integer   integer

Double   double

Float      float

Boolean  boolean

Date       date

BigDecimal    bigdecimal

BigDecimal    bicimal

Map              map

基本类型,就是每一种变成语言都有的,不需要 new 就可以直接使用的。包装类型,本质就是一个对象来的,每个变成语言都不一定相同。需要通过 new 获取实例使用。

百度搜“Java 包装类”,看帖,整理。

八、数据源写法优化

1.提供 db.properties 文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///hello
username=root
password=1234

2.在 SqlMapConfig.xml 核心文件中,引入 db.properties 文件

注意:xml 文件中有书写的约束,需要放在顶端。
<!-- 引入 db.properties 配置文件 -->
<properties resource="db.properties"/>

3.修改获取的方式

<dataSource type="POOLED">
	<property name="driver" value="${driver}" />
	<property name="url" value="${url}" />
	<property name="username" value="${username}" />
	<property name="password" value="${password}" />
</dataSource>

九、输入输出映射

1、输入映射

1)新建 QueryBean 类,添加 User 类型字段和 get/set 方法。

public class QueryBean implements Serializable {
	
	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
}

2)编辑 UserMapper.xml 配置文件。

<!-- 根据 QueryBean 查找用户 -->
<select id="findUserByQueryBean" parameterType="QueryBean" resultType="User">
    select * from user where username like '%${user.username}%' and sex = #{user.sex}
</select>

3)编辑 UserMapper 接口类

public List<User> findUserByQueryBean(QueryBean queryBean);

4)编辑 UserTest 测试类

@Test
public void fun2() throws Exception{
		
	SqlSession session = factory.openSession();
	UserMapper mapper = session.getMapper(UserMapper.class);
		
	// 创建 QueryBean 实例
	QueryBean queryBean = new QueryBean();
		
	// 创建 User 实例
	User user = new User();
	user.setUsername("肉");
	user.setSex("男");
		
	queryBean.setUser(user);
		
	List<User> userList = mapper.findUserByQueryBean(queryBean);
		
	for (User user2 : userList) {
		System.out.println(user2);
	}
}

2.输出映射

1)编辑 UserMapper.xml 文件

<select id="findUserCount" resultType="int">
	select count(*) from user;		
</select>

2)编辑 UserMapper 接口文件

public Integer findUserCount();

3)编辑 UserTest 测试文件。

@Test
public void fun3() throws Exception{
	SqlSession session = factory.openSession();
	UserMapper mapper = session.getMapper(UserMapper.class);
		
	System.out.println("总人数为:" + mapper.findUserCount() + " 人。");
}

十、动态 SQL 语句

https://blog.csdn.net/weidong_y/article/details/81740636

十一、对单个对象映射

1.自动映射

新建一张中间表

2.手动映射

resultMap、association

https://blog.csdn.net/weidong_y/article/details/80557941

十二、对集合对象映射

https://blog.csdn.net/weidong_y/article/details/80557941

十三、Spring 整合 MyBatis 框架

1.搭建环境需要准备的 jar 包文件

1)Spring 的 jar 包

2)MyBatis 的 jar 包

3)mybatis-spring 整合包:mybatis-spring-1.2.2.jar

4)数据驱动包:mysql-connector-java-5.1.7-bin.jar

5)数据源:dbcp、c3p0

6)日志包:log4j,在使用的时候,需要加 logging 包和 log4j.properties

2.需要准备的配置文件

1)Spring 的核心配置文件:beans.xml

2)MyBatis 的核心配置文件:SqlMapConfig.xml

3)数据连接信息:db.properties

4)日志文件:log4j.properties

3.配置 Spring 的 beans.xml 核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 加载配置文件 -->
	<context:property-placeholder location="classpath:db.properties" />
	<!-- 数据库连接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxActive" value="10" />
		<property name="maxIdle" value="5" />
	</bean>

	<!-- 整合Sql会话工厂归spring管理 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 指定mybatis核心配置文件 -->
		<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
		<!-- 指定会话工厂使用的数据源 -->
		<property name="dataSource" ref="dataSource"></property>
	</bean>

	<!-- 配置原生Dao实现 注意:class必须指定Dao实现类的全路径名称 -->
	<bean id="userDao" class="com.neuedu.dao.UserDaoImpl">
		<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
	</bean>

	<!-- Mapper接口代理实现 -->
	<!-- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> -->
	<!-- 配置mapper接口的全路径名称 -->
	<!-- <property name="mapperInterface" 
		value="com.neuedu.mapper.UserMapper"></property> -->
	<!-- <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> -->
	<!-- </bean> -->

	<!-- 使用包扫描的方式批量引入Mapper 扫描后引用的时候可以使用类名,首字母小写. -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<!-- 指定要扫描的包的全路径名称,如果有多个包用英文状态下的逗号分隔 -->
		<property name="basePackage" value="com.neuedu.mapper"></property>
	</bean>
</beans>

 4.配置数据源信息db.properties 文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/hello?characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234

5.配置 SqlMapConfig.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>

	<typeAliases>
		<!-- 使用包扫描的方式批量定义别名 定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写 -->
		<package name="com.neuedu.pojo" />
	</typeAliases>

	<mappers>
		<mapper resource="User.xml" />

		<!-- 使用class属性引入接口的全路径名称: 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 -->
		<!-- <mapper class="com.neuedu.mapper.UserMapper"/> -->

		<!-- 使用包扫描的方式批量引入Mapper接口 使用规则: 1. 接口的名称和映射文件名称除扩展名外要完全相同 2. 接口和映射文件要放在同一个目录下 -->
		<!-- <package name="com.neuedu.mapper"/> -->
	</mappers>
</configuration>

6.使用原生 Dao 实现方式来整合

1)新建 UserDao 接口类和UserDaoImpl 实现类。

需要继承 SqlSessionDaoSupport 类,因为我们可以直接通过它使用 SqlSession 对象。然后,父类中还有 sqlSessionFactory 属性,可以让我们设置关联自动实现。

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
	
	// 会话
	// SqlSession 是一个线程不安全的,然后像这种线程不安全最好放在一个代码块使用
	// 比如一般情况下,建议直接在方法体中使用即可
	// private SqlSession session = this.getSqlSession();

	@Override
	public User findUserById(Integer id) {
		SqlSession session = this.getSqlSession();
		return session.selectOne("findUserById", id);
		// 因为我们现在的 session 已经交给 spring 管理了,是不能手动关闭的
		// 如果你关了之后,其他地方则不可用
		// session.close();
	}

	@Override
	public List<User> findUserByName(String username) {
		SqlSession session = this.getSqlSession();
		return session.selectList("findUserByName", username);
	}
}

2)将 UserDaoImpl 交给 Spring 管理。

<!-- 配置原生Dao实现 注意:class必须指定Dao实现类的全路径名称 -->
<bean id="userDao" class="com.neuedu.dao.impl.UserDaoImpl">
    <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>

3)添加 UserDaoTest 测试类。

public class UserDaoTest {
	
	private ApplicationContext context;
	
	@Before
	public void addConfig(){
		
		context = new ClassPathXmlApplicationContext("classpath:beans.xml");
	}

	@Test
	public void run() {
		
		UserDao userDao = (UserDao)context.getBean("userDao");
		
		User user = userDao.findUserById(10);
		System.out.println("---------------------" + user);
		
		List<User> userList = userDao.findUserByName("明");
		
		for (User user2 : userList) {
			System.out.println(user2);
		}
	}
}

7.使用 Mapper 映射文件实现

1)编辑 beans.xml 文件,设置包扫描方式。

<!-- 使用包扫描的方式批量引入Mapper 扫描后引用的时候可以使用类名,首字母小写. -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	<!-- 指定要扫描的包的全路径名称,如果有多个包用英文状态下的逗号分隔 -->
	<property name="basePackage" value="com.neuedu.mapper"></property>
</bean>

2)编辑 UserMapper.xml 文件

<mapper namespace="com.neuedu.mapper.UserMapper">
    <select id="findUserByName" resultType="com.neuedu.pojo.User" parameterType="java.lang.String">
        select * from user where username like '%${value}%'
    </select>
</mapper>

3)编辑 UserMapper 接口类。

public interface UserMapper {
	public List<User> findUserByName(String name);
}

4)编辑 UserDaoTest 测试类。

@Test
public void run2(){
		
	// 因为我们使用了包扫描方式
	// 所以可以根据类的名字(首字母小写)来加载对应的实例
	UserMapper mapper = (UserMapper) context.getBean("userMapper");
		
	List<User> list = mapper.findUserByName("明");
		
	for (User user : list) {
		System.out.println(user);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值