MyBatis的入门及简单使用

本文介绍MyBatis框架的基础知识,包括其历史背景、特点及如何搭建一个简单的MyBatis项目。涵盖配置数据库连接、创建实体类、DAO层接口、XML映射文件等内容,并通过示例演示基本的CRUD操作。

一.概述

先来看看百度百科怎么说的:MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

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

mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。mybatis通过 xml 或注解的方式将要执行的各种statement配置起来,并通过java对象和statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

二.JDBC编程的回顾

public static void main(String[] args) {
	Connection connection = null;
	PreparedStatement preparedStatement = null;
	ResultSet resultSet = null;
try {
	//加载数据库驱动
	Class.forName("com.mysql.jdbc.Driver");
	//通过驱动管理类获取数据库链接
	connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","root", "root");
	//定义 sql 语句 ?表示占位符
	String sql = "select * from user where username = ?";
    //获取预处理 statement
	preparedStatement = connection.prepareStatement(sql);
	//设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的参数值
	preparedStatement.setString(1, "王五");
	//向数据库发出 sql 执行查询,查询出结果集
	resultSet = preparedStatement.executeQuery();
	//遍历查询结果集
	while(resultSet.next()){
		System.out.println(resultSet.getString("id")+""+resultSet.getString("username"));
	}
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		//释放资源
		if(resultSet!=null){
		try {
			resultSet.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	if(preparedStatement!=null){
		try {
			preparedStatement.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	if(connection!=null){
		try {
			connection.close();
		} catch (SQLException e) {
		// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	}
}

分析可知:

1、数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2、Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java
代码。
3、使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能
多也可能少,修改 sql 还要修改代码,系统不易维护。
4、对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记
录封装成 pojo 对象解析比较方便。

三.MyBatis入门

三.Mybatis入门

1.创建maven工程,在pom文件中导入Mybatis所需坐标

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.4.5</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.26</version>
 </dependency>
 <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
 </dependency>

2.创建实体类及数据库对应的表

//实体类
public class User implements Serializable{
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //构造函数及set和get方法
}
//创建数据库及表
create database review_mybatis;
use review_mybatis;
//创建表user,注意表中字段名和实体类一致
create table user(
    id int,
    username VARCHAR(20),
    birthday date,
    sex VARCHAR(1),
    address VARCHAR(20)
);

3.创建dao层访问数据库的接口

public interface IUserDao {
	//查询全部
    List<User> findAll();
    //根据id查询
    User findById(Integer userId);
    //保存用户信息
    int saveUser(User user);
    //更新用户,返回影响数据库记录条数
    int updateUser(User user);
    //删除用户
    int deleteUser(Integer userId);
    //根据名称模糊查询
    List<User> findByName(String username);
    //使用聚合函数查询总记录
    int findTotal();
}

4.创建Mybatis配置数据库连接信息的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>
    <!-- 配置 mybatis 的环境 -->
    <environments default="mysql">
        <!-- 配置 mysql 的环境 -->
        <environment id="mysql">
            <!-- 配置事务的类型 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置连接数据库的信息:用的是数据源(连接池) -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!-- 自己的数据库review_mybatis -->
                <property name="url" value="jdbc:mysql://localhost:3306/review_mybatis"/>
                <!-- 数据库登录名 -->
                <property name="username" value="root"/>
                <!-- 数据库登录密码 -->
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 告知 mybatis 映射配置的位置,即书写sql的xml文件 -->
    <mappers>
        <mapper resource="com/xjz/aq/dao/IUserDao.xml"/>
    </mappers>
</configuration>

5.创建映射的SQL语句文件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">
<!-- namespace写的路径是对应接口的路径 -->
<mapper namespace="com.xjz.aq.dao.IUserDao">
    <!-- id为接口中的方法名,resultType为返回值类型的全路径 -->
    <select id="findAll" resultType="com.xjz.aq.pojo.User">
        select * from user
    </select>

    <!-- 测试 mybatis 的 crud 操作 -->
    <!-- 根据 id 查询 -->
	<select id="findById" resultType="com.itheima.domain.User" parameterType="int">
		select * from user where id = #{uid}
	</select>
    <!--
	细节:
		resultType  属性:用于指定结果集的类型。
		parameterType 用于指定传入参数的类型。
		sql  语句中使用#{} 字符 :
			它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据				是由#{}里面的内容决定的。
		#{} 中内容的写法:由于数据类型是基本类型,所以此处可以随意写。
	-->
    <!-- 保存用户-->
	<insert id="saveUser" parameterType="com.itheima.domain.User">
		insert into user(username,birthday,sex,address)
					values(#{username},#{birthday},#{sex},#{address})
	</insert>
    <!--\细节:
 parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。
 sql 语句中使用#{}字符:它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
	具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。
	它用的是 ognl 表达式。
	ognl 表达式:它是 apache 提供的一种表达式语言,全称是:Object Graphic Navigation Language 对象图导航语言
	它是按照一定的语法格式来获取数据的。
	语法格式就是使用 #{对象.对象}的方式#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用
getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.
	而直接写 username
-->
    <!--新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相
当于我们要在新增后将自动增长 auto_increment 的值返回。-->
	<insert id="saveUser" parameterType="USER">
		<!--  配置保存时获取插入的 id -->
		<selectKey keyColumn="id" keyProperty="id" resultType="int">
			select last_insert_id();
		</selectKey>
		insert into user(username,birthday,sex,address)
					values(#{username},#{birthday},#{sex},#{address})
	</insert>
    
    <!-- 更新用户 -->
	<update id="updateUser" parameterType="com.itheima.domain.User">
		update user set username=#{username},birthday=#{birthday},sex=#{sex},
						address=#{address} where id=#{id}
	</update>
    
    <!-- 删除用户 -->
	<delete id="deleteUser" parameterType="java.lang.Integer">
		delete from user where id = #{uid}
	</delete>
    
    <!-- 根据名称模糊查询 -->
<select id="findByName" resultType="com.itheima.domain.User" parameterType="String">
	select * from user where username like #{username}
</select>
    <!-- 查询总记录条数 -->
	<select id="findTotal" resultType="int">
		select count(*) from user;
    </select>
</mapper>
<!--
#{} 表示一个占位符号,通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 	jdbc 类型转换,#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值,#{}括号中可以是 value 或其它名称。
${} 表示拼接 sql 串通过${}可以将 parameterType 传入的内容拼接在 sql中且不进行 jdbc 类型转换, ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
-->

6.测试

public class Demo {
    @Test
    public void test1() throws IOException {
        //1.读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapperConfig.xml");
        //2.创建 SqlSessionFactory 的构建者对象
        SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
        //3.使用构建者创建工厂对象 SqlSessionFactory
        SqlSessionFactory build = factoryBuilder.build(in);
        //4.使用 SqlSessionFactory 生产 SqlSession 对象
        SqlSession session = build.openSession();
        //5.使用 SqlSession 创建 dao 接口的代理对象
        IUserDao mapper = session.getMapper(IUserDao.class);
        //6.使用代理对象执行查询所有方法
        List<User> list = mapper.findAll();
        for (User user : list) {
            System.out.println(user);
        }
        //关闭资源
        session.close();
        in.close();
    }
}
<!-- 另建一个类,测试 mybatis 的 crud 操作 -->
public class MybastisCRUDTest {
	private InputStream in ;
	private SqlSessionFactory factory;
	private SqlSession session;
	private IUserDao userDao;
    //根据id查询
	@Test
	public void testFindOne() { 
		//6.执行操作
		User user = userDao.findById(41);
		System.out.println(user);
	}
    //保存用户
    @Test
	public void testSave(){
		User user = new User();
		user.setUsername("modify User property");
		user.setAddress("北京市顺义区");
		user.setSex("男");
		user.setBirthday(new Date());
		System.out.println("保存操作之前:"+user);
		//5.执行保存方法
		userDao.saveUser(user);
		System.out.println("保存操作之后:"+user);
	}
    //修改用户
    @Test
	public void testUpdateUser()throws Exception{
		//1.根据 id 查询
		User user = userDao.findById(52);
		//2.更新操作
		user.setAddress("北京市顺义区");
		int res = userDao.updateUser(user);
		System.out.println(res);
	}
    //删除用户
    @Test
	public void testDeleteUser() throws Exception {
		//6.执行操作
		int res = userDao.deleteUser(52);
		System.out.println(res);
	}
    //根据用户名模糊查询
    @Test
	public void testFindByName(){
        //5.执行查询一个方法
		List<User> users = userDao.findByName("%王%");
		for(User user : users){
			System.out.println(user);
		}
	}
    //使用聚合函数查询总记录条数
    @Test
	public void testFindTotal() throws Exception {
		//6.执行操作
		int res = userDao.findTotal();
		System.out.println(res);
	}
	@Before//在测试方法执行之前执行
	public void init()throws Exception {
		//1.读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2.创建构建者对象
		SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
		//3.创建 SqlSession 工厂对象
		factory = builder.build(in);
		//4.创建 SqlSession 对象
		session = factory.openSession();
		//5.创建 Dao 的代理对象
		userDao = session.getMapper(IUserDao.class);
	}
    
	@After//在测试方法执行完成之后执行
	public void destroy() throws Exception{
		session.commit();
		//7.释放资源
		session.close();
		in.close();
	}
    
}

7.MyBatis使用注解方式配置

1.在接口的方法上加注解

public interface IUserDao {
	/**
	* 查询所有用户
	* @return
	*/
	@Select("select * from user")
	List<User> findAll();
}

2.在核心配置文件中修改映射文件指向并移除映射配置文件

<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
    <!-- 接口的全路径-->
	<mapper class="com.itheima.dao.IUserDao"/>
</mappers>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值