MyBatis系列01——从零开始第一个MyBatis程序

MyBatis简介

MyBatis 是一款持久层框架,它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 映射成数据库中的记录【半自动化的ORM框架 (Object Relationship Mapping) -->对象关系映射】。

数据持久化

数据持久化是指将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数型据库来完成。一般的框架中,一般在DAO层来完成持久化工作的代码块。
简而言之:Mybatis就是帮助程序猿 将数据存入数据库中 , 和从数据库中取数据。

使用步骤

首先,代码结构是这样子的:
在这里插入图片描述

1. 搭建实验数据库

CREATE DATABASE `mybatis`;

USE `mybatis`;

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`name`,`pwd`) values (1,'狂神','123456'),(2,'张三','abcdef'),(3,'李四','987654');

2. 创建Maven项目

创建一个Maven项目,删除src目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:最好将编译器使用的maven 修改为自己下载的maven
在这里插入图片描述

3. 导入MyBatis相关 jar 包【pom.xml中添加如下代码】

<dependencies>
<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.5.2</version>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.47</version>
</dependency>
</dependencies>

在这里插入图片描述

4. 创建一个子模块

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建之后,在原来的pom.xml文件中就会自动生成modules标签,表示这些子模块都会共用父亲工程中pom文件的配置
在这里插入图片描述

5. 编写MyBatis核心配置文件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>
    <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:3306/mybatis_test"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="userMapper.xml"/>
    </mappers>
</configuration>

6. 编写MyBatis工具类

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 java.io.IOException;
import java.io.InputStream;

public class MybatisUtils {

   private static SqlSessionFactory sqlSessionFactory;

   static {
       try {
           String resource = "mybatis-config.xml";
           InputStream inputStream = Resources.getResourceAsStream(resource);
           sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      } catch (IOException e) {
           e.printStackTrace();
      }
  }

   //获取SqlSession连接
   public static SqlSession getSession(){
       return sqlSessionFactory.openSession();
  }

}

在这里插入图片描述

7. 创建实体类

public class User {

    private int id;  //id
    private String name;   //姓名
    private String pwd;   //密码

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append("id");
        sb.append(this.id);
        sb.append("name");
        sb.append(this.name);
        sb.append("pwd");
        sb.append(this.pwd);
        return sb.toString();
    }
}

在这里插入图片描述

8. 编写Mapper接口类

import java.util.List;

public interface UserMapper {
   List<User> selectUser();
}

9. 编写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="UserMapper">
 <select id="selectUser" resultType="User">
  select * from user
 </select>
</mapper>

10. 编写测试类【记得先导入Junit哦】

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class MyTest {
    @Test
    public void selectUser() {
        SqlSession session = MybatisUtils.getSession();
        //方法一:
        //List<User> users = session.selectList("com.kuang.mapper.UserMapper.selectUser");
        //方法二:
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> users = mapper.selectUser();

        for (User user : users) {
            System.out.println(user);
        }
        session.close();
    }
}

11. 运行

鼠标点击selectUser方法,然后右键-run as junit,运行,开始运行你的第一个程序吧~

Mybatis执行过程和作用域

在这里插入图片描述
在这里插入图片描述
作用域:

  • SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建SqlSessionFactory 的方法中,而不要让其长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
  • SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期
  • 由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域
  • SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try…catch…finally… 语句来保证其正确关闭。所以 SqlSession 的最佳的作用域是请求或方法作用域

增删改查操作

查找select

根据id和name查询用户

  1. 在UserMapper中添加对应方法
public interface UserMapper {
   //根据id和name查询用户
   User selectUserByIdName(int id, String name);
}
  1. 在UserMapper.xml中添加Select语句
<select id="selectUserByIdName" resultType="com.kuang.pojo.User">
select * from user where id = #{id} and name = #{name}
</select>
  1. 测试类中测试
@Test
public void tsetSelectUserById() {
   SqlSession session = MybatisUtils.getSession();  //获取SqlSession连接
   UserMapper mapper = session.getMapper(UserMapper.class);
   User user = mapper.selectUserByIdName(1,"sxy");
   System.out.println(user);
   session.close();
}

如果要向sql语句传递参数,有两种方法:

  • 方法1:直接在在接口方法的参数前加 @Param属性
User selectUserByIdName(@Param("id")int id, @Param("name")String name);

这种方式就不用在mapper.xml文件中再设置参数类型

<select id="selectUserByIdName" resultType="com.kuang.pojo.User">
select * from user where id = #{id} and name = #{name}
</select>
  • 方法2:使用万能的Map
User selectUserByIdName(Map<String,Object> map);

这种方式需要在mapper.xml文件中设置参数类型为map

<select id="selectUserByIdName" parameterType="map" resultType="com.kuang.pojo.User">
select * from user where id = #{id} and name = #{name}
</select>

使用时,就创建一个Map,存入值,然后调用方法即可。

Map<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("name","sxy");
User user = mapper.selectUserByIdName(map);

插入insert

会了select之后,其他三种使用起来都很类似,但是,要注意的是,对于增、删、改操作,最后一定要提交事务!!!

int addUser(User user);
<insert id="addUser" parameterType="com.kuang.pojo.User">
    insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);
   User user = new User(5,"王五","zxcvbn");
   int i = mapper.addUser(user);
   System.out.println(i);
   session.commit(); //提交事务,重点!不写的话不会提交到数据库
   session.close();

修改update

类似

<update id="updateUser" parameterType="com.kuang.pojo.User">
  update user set name=#{name},pwd=#{pwd} where id = #{id}
</update>

删除delete

<delete id="deleteUser" parameterType="int">
  delete from user where id = #{id}
</delete>

模糊查询

方法一:在Java代码中添加sql通配符

string wildcardname =%smi%;
mapper.selectlike(wildcardname);
<select id=”selectlike”>
select * from foo where bar like #{value}
</select>

方法二:在sql语句中拼接通配符,会引起sql注入

string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);
<select id="selectlike">
    select * from foo where bar like "%"#{value}"%"
</select>

补充:什么是SQL 注入?

SQL 注入其实就是 恶意用户 通过 在表单中填写包含 SQL 关键字 的数据来使数据库执行 非常规 代码的过程。
最简单的例子:
假设网页有一个输入框,功能:根据输入框中的名字name,从数据库student中查找数据,即:
name = "sxy"
sql = "select * from student where name = " + name
这个时候,如果有一个恶意用户,输入的名称为sxy;drop table student;
此时,sql语句就成了:sql = "select * from student where name = sxy;drop table student; "
这个时候,你的student表就被删除啦~

分页查询

如果查询大量数据的时候,我们往往使用分页进行查询,也就是每次处理小部分数据,这样对数据库压力就在可控范围内。

  • 方法一:使用Limit实现分页
    语法:SELECT * FROM table LIMIT stratIndex,pageSize
    比如:
    SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15 【pageSize为-1表示到最后一行】
    SELECT * FROM table LIMIT 5; //检索前 5 个记录行【如果只有一个参数,表示返回最大的记录行数目】
    使用:
    xml文件中使用select语句:<select>select * from user limit #{startIndex},#{pageSize}</select>
    Java使用SQLsession对象执行语句时传入两个参数即可:

    int currentPage = 1;  //第几页
    int pageSize = 2;  //每页显示几个
    Map<String,Integer> map = new HashMap<String,Integer>();
    map.put("startIndex",(currentPage-1)*pageSize);
    map.put("pageSize",pageSize);
    
  • 方法二:使用RowBounds在Java代码层面实现分页【不推荐使用】

RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);
List<User> users = session.selectList("getUserByRowBounds", null, rowBounds);
  • 方法三:使用第三方插件
    比如:PageHelper

配置解析

mybatis-config.xml

configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

configuration元素

xml配置文件最外一层就是<configuration></configuration>

environments元素

使用environments可以配置MyBatis的多套运行环境【指定多个environment】,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)。
使用模板:

<environments default="development">
 <environment id="development">
   <transactionManager type="JDBC"> 
     <property name="..." value="..."/>
   </transactionManager>
   <dataSource type="POOLED">
   	 <property name="..." value="..."/>
   </dataSource>
 </environment>
</environments>

dataSource元素

数据源dataSource用于配置数据库信息,包含在environment元素之下,类型主要包括以下四种形式:

  • unpooled:每次被请求时打开和关闭连接
  • pooled:利用“池”的概念将 JDBC 连接对象组织起来
  • jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用
  • 第三方实现:比如dbcp,c3p0,druid

mappers元素

定义 映射SQL语句 的文件。
使用模板:

  1. 在mybatis-config.xml文件中配置mappers
   <mappers>
       <mapper resource="com/kuang/dao/userMapper.xml"/>
   </mappers>

resource路径引入资源方式有:

  • 使用相对于类路径的资源引用:
    <mapper resource="org/mybatis/builder/PostMapper.xml"/>
  • 使用完全限定资源定位符(URL):
    <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  • 使用映射器接口实现类的完全限定类名:
    <mapper class="org.mybatis.builder.AuthorMapper"/>
  • 将包内的映射器接口实现全部注册为映射器,但是需要配置文件名称和接口名称一致,并且位于同一目录下:
    <package name="org.mybatis.builder"/>
  1. 在对应的mapper文件中配置类和sql语句
<mapper namespace="com.kuang.mapper.UserMapper">
   <select id="..." parameterType="..." resultType="..."></select>
   <insert...></insert>
   <update...></update>
   <delete...></delete>
</mapper>

注意:namespace的命名必须跟某个接口同名,接口中的方法与映射文件中sql语句id应该一一对应

properties 元素

在 属性文件 中配置 参数,再通过 properties 元素的子元素来传递

  1. 配置db.properties文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=123456
  1. 将文件导入properties 配置文件,在使用参数处,使用${参数名称} 来获取值【下面的代码中只体现了重点】
<configuration>
   <!--导入properties文件-->
   <properties resource="db.properties"/>
	...
	<property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    ...
</configuration>

typeAliases元素

类型别名,为 Java 类型设置一个短的名字,之后再使用的时候,可以直接使用这个别名。
使用模板:

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

当对包名使用别名时,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

<typeAliases>
   <package name="com.kuang.pojo"/>
</typeAliases>

每一个在包 com.kuang.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
若有注解,则别名为其注解值。比如:

@Alias("user")
public class User {
  ...
}

setting元素

配置其他跟 设置 有关的信息,比如 是否开启缓存、是否使用懒加载等。
一个配置完整的 settings 元素的示例如下:

<settings>
 <setting name="cacheEnabled" value="true"/>
 <setting name="lazyLoadingEnabled" value="true"/>
 <setting name="multipleResultSetsEnabled" value="true"/>
 <setting name="useColumnLabel" value="true"/>
 <setting name="useGeneratedKeys" value="false"/>
 <setting name="autoMappingBehavior" value="PARTIAL"/>
 <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
 <setting name="defaultExecutorType" value="SIMPLE"/>
 <setting name="defaultStatementTimeout" value="25"/>
 <setting name="defaultFetchSize" value="100"/>
 <setting name="safeRowBoundsEnabled" value="false"/>
 <setting name="mapUnderscoreToCamelCase" value="false"/>
 <setting name="localCacheScope" value="SESSION"/>
 <setting name="jdbcTypeForNull" value="OTHER"/>
 <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

参考链接:https://mp.weixin.qq.com/s/vy-TUFa1Rb69ekxiEYGRqw

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值