MyBatis的简单了解(一)

本文详细介绍MyBatis框架的安装、配置与基本使用方法,对比JDBC开发的不足,展示MyBatis如何简化数据库操作,提高代码可维护性和开发效率。

沉迷于黑与白世界中的人,无论怎么挣扎,都逃不过被同化的命运。前世看见了什么,那么今世便是什么。

上一章简单介绍了S2SH框架整合开发版(十一),如果没有看过,请观看上一章

一. JDBC 形式的缺点

MyBatis 是数据持久层的操作,是对数据库的处理, 在介绍它之前,先来了解一下,原来的jdbc 的处理,有哪些缺点,然后看看MyBatis 是如何进行改变的。
先来简单写一个User 类,只有id,name,age,sex,description 五个简单的字段,是简单的pojo 类。 对其进行简单的查询操作:

一.二 JDBC类

package com.yjl.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
 @author:yuejl
 @date: 2019年6月15日 上午11:53:34
 @Description 类的相关描述
*/
public class DBUtils {
	public static Connection getConnection(){
		Connection connection=null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8", 
					"root","abc123");
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return connection;
	}
	public static void close(ResultSet resultSet,Statement statement,Connection connection){
		if(resultSet!=null){
			try {
				resultSet.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		if(statement!=null){
			try {
				statement.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		if(connection!=null){
			try {
				connection.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
	}
}

一.三 根据id 编号进行查询的方法

@Test
	public void oldTest() throws SQLException{
		Connection connection=DBUtils.getConnection();
		String sql="select * from user where id=?";
		PreparedStatement statement=connection.prepareStatement(sql);
		statement.setInt(1, 1);
		ResultSet resultSet=statement.executeQuery();
		User user=null;
		while(resultSet.next()){
			user=new User();
			user.setId(resultSet.getInt("id"));
			user.setName(resultSet.getString("name"));
			user.setAge(resultSet.getInt("age"));
			user.setSex(resultSet.getString("sex"));
			user.setDescription(resultSet.getString("description"));
		}
		DBUtils.close(resultSet,statement,connection);
		System.out.println(user);
	}

运行之后,会显示:
在这里插入图片描述
仔细观察,会发现这种写法,有很多的不足之处。

一.四 原始JDBC 开发的不足

  1. 数据库的连接。 数据库在使用时被创建,不使用就释放, 对数据库进行频繁的连接开启和关闭,造成数据库资源浪费,影响数据库的性能。
  2. 数据库信息被硬编码。
connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8", 
					"root","abc123");

数据库的连接信息被硬编码到连接数据库类中,如果更换数据库,则需要改变相应的信息,重新编码。即使可以写在 jdbc.properties 等配置文件里面,那么还需要写一个单独的读取 jdbc.properties 文件信息的类。

  1. sql 语句被硬编码
String sql="select * from user where id=?";

如果sql 被修改, 实际开发中,是常常被修改的, 那么就必须重新编译,不利用系统维护。

  1. 向PreparedStatement 设置值时,对参数的位置 和值,硬编码到程序里面。 不利于系统维护。 如 设置 ? 时,id 放在了第一位, 如果有name, name放在了第二位, 那么在传参的时候,必须把id 放在第一个,name 放在第二个。
statement.setInt(1, 1);
  1. 遍历结果集数据时, 将获取表的字段值,进行了硬编码。不利用系统维护。
			user=new User();
			user.setId(resultSet.getInt("id"));
			user.setName(resultSet.getString("name"));
			user.setAge(resultSet.getInt("age"));
			user.setSex(resultSet.getString("sex"));
			user.setDescription(resultSet.getString("description"));

如,如果修改了数据库的字段,description, 现在要改成desc, 那么就都得改变,列名硬编码到程序中。 当然,可以通过 getInt(1),getString(2) 这样的索引顺序来取得,那么列名就不硬编码了,但是 索引顺序就硬编码了。 改变sql 前后值的顺序,就有可能出错。

  1. 某些功能无法实现。
    如 根据传过来的值,来动态的显示列。 即 前台传入列的名称,来动态的显示 列。 前台传入name 和sex, 就查询name 和sex 列, 前台传入name,sex,age 就动态查询name,sex,age 列。

二. MyBatis

二.一 MyBatis 的出现

在MyBatis 之前,是叫 ibatis, 是Apache 组织的开发的。 现在交由github 管理了。 还有一种 持久化ORM ,叫Hibernate. 前面讲过。 可以看:
Hibernate开发环境的简单搭建及常见错误(一)
将Hibernate 与 MyBatis 进行比较性 开发。

MyBatis 的下载网址是:
https://github.com/mybatis/mybatis-3
在这里插入图片描述
下载之后:
在这里插入图片描述
其中, mybatis-3.4.5.jar 是开发的jar 包, mybatis-3.4.5.pdf 是帮助文档, lib 是常用的关联jar 包。
在这里插入图片描述

二.二 MyBatis 的作用

mybatis是一个持久层的框架,是apache下的顶级项目。
mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

三. MyBatis 的简单开发

通过Mybatis, 对user 表进行查询,按照id 进行查询和 查询全部。
其中,数据库表 user 为: 两条数据。
在这里插入图片描述
创建简单的Java 项目即可,暂时先不用创建Web项目。

三.一 导入jar包

需要导入 mybatis 的jar包, mybatis 的关联包, 和mysql驱动 的jar包。
在这里插入图片描述

三.二 创建User.java 简单类

package com.yjl.pojo;
/**
 @author:yuejl
 @date: 2019年6月15日 上午11:11:02
 @Description Mybatis 使用的基本类 User
*/
public class User {
	/**
	 * @param id id编号,自增
	 * @param name 姓名
	 * @param age 年龄
	 * @param sex 性别
	 * @param description 描述
	 */
	private Integer id;
	private String name;
	private Integer age;
	private String sex;
	private String description;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", description=" + description
				+ "]";
	}
}

三.三 创建UserDao 接口和UserDaoImpl 实现类

UserDao 接口:

package com.yjl.dao;

import java.util.List;

import com.yjl.pojo.User;

/**
 @author:yuejl
 @date: 2019年6月15日 上午11:26:23
 @Description 类的相关描述
*/
public interface UserDao {
	User getById(int id);
	List<User> findAll();
}

UserDaoImpl 实现类:

package com.yjl.dao.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.yjl.dao.UserDao;
import com.yjl.pojo.User;
import com.yjl.util.SqlSessionFactoryUtils;

/**
 @author:yuejl
 @date: 2019年6月15日 上午11:26:36
 @Description 类的相关描述
*/
public class UserDaoImpl implements UserDao{

	@Override
	public User getById(int id) {
		return null;
	}

	@Override
	public List<User> findAll() {
		return null;
	}

}

三.四 创建测试类

package com.yjl.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.junit.Test;

import com.yjl.dao.UserDao;
import com.yjl.dao.impl.UserDaoImpl;
import com.yjl.pojo.User;
import com.yjl.util.DBUtils;

/**
 @author:yuejl
 @date: 2019年6月15日 上午11:14:56
 @Description 类的相关描述
*/
public class UserTest {
	@Test
	public void getByIdTest(){
		UserDao userDao=new UserDaoImpl();
		User user=userDao.getById(1);
		System.out.println(user);
	}
	@Test
	public void findAllTest(){
		UserDao userDao=new UserDaoImpl();
		List<User> allList=userDao.findAll();
		allList.forEach(n ->System.out.println(n));
	}
}

三.五 MyBatis 的核心配置文件 SqlMapConfig.xml

在src 目录下,创建 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>
	<!-- 开发环境  development -->
	<environments default="development">
		<environment id="development">
			<!-- 事务管理 -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- 数据源 ,为pooled 连接池 -->
			<dataSource type="pooled">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8"/>
				<property name="username" value="root"/>
				<property name="password" value="abc123"/>
			</dataSource>	
		</environment>
	</environments>
	<mappers>
		<!-- 引入文件资源 -->
		<mapper resource="com/yjl/pojo/User.xml"/>
	</mappers>
</configuration>

三.六 MyBatis 的工具类 SqlSessionFactoryUtils ,用于获取SqlSession

package com.yjl.util;

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;

/**
 @author:两个蝴蝶飞
 @date: 2019年6月15日 上午11:13:26
 @Description 类的相关描述
*/
public class SqlSessionFactoryUtils {
	/*创建SqlSession的工厂 SqlSessionFactory对象*/
	private static SqlSessionFactory sqlSessionFactory=null;
	private SqlSessionFactoryUtils(){
		
	}
	/**
	 * 单例模式 获取实例
	 * @author 两个蝴蝶飞
	 * @return
	 */
	public static SqlSessionFactory getInstance(){
		synchronized(SqlSessionFactoryUtils.class){
			if(sqlSessionFactory==null){
				InputStream input=null;
				// Mybatis 核心配置文件名
				String resource_name="SqlMapConfig.xml";
				try {
					input=Resources.getResourceAsStream(resource_name);
					sqlSessionFactory=new SqlSessionFactoryBuilder().build(input);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return sqlSessionFactory;
	}
	/**
	 * 
	 * @author 两个蝴蝶飞
	 * @return 获取当前的Session
	 */
	public static SqlSession getSession(){
		if(sqlSessionFactory==null){
			getInstance();
		}
		return sqlSessionFactory.openSession();
	}
}

三.七 MyBatis 的实体配置文件 User.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.yjl.pojo.User">
	<select id="getById" parameterType="int" resultType="com.yjl.pojo.User">
		<!--正常的sql 语句。 -->
		select * from user where id=#{id}
	</select>
	<select id="findAll" resultType="com.yjl.pojo.User">
		select * from user
	</select>
</mapper>

三.八 引入log4j.properties 日志文件

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
## 配置mybatis 的日志级别为debug
log4j.logger.org.mybatis=debug
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=debug, stdout

配置完成后的,目录结构如下:
在这里插入图片描述

三.九 UserDaoImpl 类的 getById() 方法实现

@Override
	public User getById(int id) {
		//调用selectOne 方法,进行查询。 第一个传入的是id 值,为User.xml 的 namespace+id 的值。
		SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
		User user=null;
		try{
			user=sqlSession.selectOne("com.yjl.pojo.User.getById",userId);
		}finally{
			sqlSession.close();
		}
		return user;
	}

三.十 UserDaoImpl 类的findAll() 方法实现

@Override
	public List<User> findAll() {
		SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
		List<User> allList=new ArrayList<User>();
		try{
			allList=sqlSession.selectList("com.yjl.pojo.User.findAll");
		}finally{
			sqlSession.close();
		}
		
		return allList;
	}

四. 测试方法

四.一 测试getById() 方法

观察log4j 日志输出。
在这里插入图片描述

  1. 打开jdbc 连接
  2. 创建连接
  3. 设置自动提交 为false.
  4. 查询sql 语句
  5. 传参数 1
  6. 查询记录,为1 条。

四.二 测试findAll() 方法

在这里插入图片描述

谢谢!!!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值