温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Mybatis怎么用

发布时间:2021-09-14 09:41:54 来源:亿速云 阅读:163 作者:小新 栏目:编程语言

这篇文章将为大家详细讲解有关Mybatis怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

1、Mybatis概述  

MyBatis 是支持普通 SQL 查询(相比较于Hibernate的封装,Mybatis是半自动化的JDBC封装,一个特点就是Mybatis执行的SQL查询语句需要自己在配置文件中写),存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索。MyBatis 可以使用简单的XML 或注解用于配置和原始映射,将接口和 Java 的 POJO(Plain Old Java Objects,普通的Java 对象)映射成数据库中的记录。

2、Mybatis原理解析

下面以Mybatis简单的执行流程

Mybatis怎么用

  1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。

  2、SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。

  3、SqlSession对象完成和数据库的交互:

  a、用户程序调用mybatis接口层api(即Mapper接口中的方法)

  b、SqlSession通过调用api的Statement ID找到对应的MappedStatement对象

  c、通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象

  d、JDBC执行sql。

  e、借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。

下面是Mybatis的框架原理图

  Mybatis怎么用

3、Mybatis简单实例

(1)导入相关jar包以及Mybatis运行环境核心jar包和连接数据库的包

Mybatis怎么用

(2)创建一张简单的数据表

Mybatis怎么用

(3)创建Java对象(PO类型)

package cn.mybatis.po; public class User {  private int id;  private String username;  private String password;  private String address;  private String sex;  public int getId() {  return id;  }  public String getUsername() {  return username;  }  public String getPassword() {  return password;  }  public String getAddress() {  return address;  }  public String getSex() {  return sex;  }  public void setId(int id) {  this.id = id;  }  public void setUsername(String username) {  this.username = username;  }  public void setPassword(String password) {  this.password = password;  }  public void setAddress(String address) {  this.address = address;  }  public void setSex(String sex) {  this.sex = sex;  }  @Override  public String toString() {  return "User{" +   "id=" + id +   ", username='" + username + '\'' +   ", password='" + password + '\'' +   ", address='" + address + '\'' +   ", sex='" + sex + '\'' +   '}';  } } User实体类

(4)创建Mybatis核心配置文件(SqlMapConfig.xml)

在核心配置文件配置连接数据库的相关信息,(如果是和Spring整合,则可以放在Spring配置文件中进行对数据库的配置)

<?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>  <!--加载资源文件--> <!-- <properties resource="jdbc.properties"></properties>  &lt;!&ndash;settings配置LOG4J输出日志 &ndash;&gt;  <settings>  <setting name="logImpl" value="LOG4J"/>  </settings>-->  <!--typeAliases配置包的别名-->  <!--environments配置了数据库连接,配置了driver、url、username、password属性-->  <environments default="development">  <environment id="development">   <transactionManager type="JDBC">   <!--<property name="" value="" />-->   </transactionManager>   <dataSource type="POOLED">   <property name="driver" value="com.mysql.jdbc.Driver" />   <property name="url" value="jdbc:mysql:///mybatis01" />   <property name="username" value="root" />   <property name="password" value="123" />   </dataSource>  </environment>  </environments>  <!--配置一个SQL语句和映射的配置文件-->  <mappers>  <mapper resource="UserMapper.xml" />  </mappers> </configuration> Mybatis核心配置文件

(5)创建一个Mapper.xml文件,对应编写所需要的Sql查询操作

<?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指定了命名空间--> <mapper namespace="test">  <!--定义一个SELECT查询-->  <!--parameterType:指定输入参数的类型-->  <!--#{}表示占位符-->  <!--#{id}:其中的id表示的就是接受的输入参数,   参数名称就是id,  这里指出:如果输入参数是简单类型,#{}中的参数名可以任意设置(value或者其他名称)-->  <!--resultType:指定输出类型(即指定输出结果所映射的Java对象类型)-->  <select id="findUserById" parameterType="int" resultType="cn.mybatis.po.User">  SELECT * FROM t_user WHERE id = #{id}  </select> </mapper> UserMapper配置文件

(7)创建测试程序,对刚刚编写的select查询进行测试

package cn.mybatis.first; import cn.mybatis.po.User; 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 Test {  public User findUserById() throws IOException {  //得到mybatis配置文件  String resource = "SqlMapConfig.xml";  //得到配置文件的文件流信息  InputStream inputStream = Resources.getResourceAsStream(resource);  //创建会话工厂 传入mybatis的配置文件信息  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  //通过会话工厂得到SqlSession  SqlSession sqlSession = sqlSessionFactory.openSession();  //通过sqlSession来操作数据库  //第一个参数就是映射文件中statment的id:namespace +statment的id  //第二个参数就是制定映射文件中的parameterType类型的参数  User user = sqlSession.selectOne("test.findUserById",1);  //System.out.println(user);  //释放会话资源  try {   sqlSession.close();  } catch (Exception e) {   e.printStackTrace();  }  return user;  }  public static void main(String[] args) {  // TODO Auto-generated method stub  Test test = new Test();  try {   System.out.println(test.findUserById());  } catch (IOException e) {   e.printStackTrace();  }  } } Test测试程序

(8)加入Log4j日志文件

### direct log messages to stdout ### log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n Log4j.properties

(9)测试结果

Mybatis怎么用

4.其他CRUD操作

(1)insert操作

在Mapper文件中添加响应的SQL配置,以及使用MySQL中的LAST_INSERT_ID()函数得到增加的数据的主键值

<insert id="addUser" parameterType="cn.mybatis.po.User">  <!--  现在需要得到刚刚插入的记录中的主键值,只适用于自增主键的情况  LAST_INSERT_ID()  keyProperty:将查询到的主键值设置到parameterType指定对象中的那个属性  order:指定相对于insert的顺序  resultType:指定映射结果的结果类型  -->  <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">   SELECT LAST_INSERT_ID()  </selectKey>  INSERT INTO t_user(id,username,password,address,sex) VALUES(#{id},#{username},#{password},#{address}, #{sex});  </insert>

插入数据的日志信息,没有使用sqlSession.commit();之前的日志情况

Mybatis怎么用

从上面的图中可以看出,没有添加commit的时候,事务进行了回滚,所以要想添加数据,需要自己手动提交(在没有整合Spring之前)

Mybatis怎么用

附上insertUser的函数

public void inserUser() throws IOException {  //得到配置文件的文件流信息  InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  SqlSession sqlSession = sqlSessionFactory.openSession();  User user = new User("World","1234","武汉市","男");  sqlSession.insert("test.addUser",user);  System.out.println(user.getId());  sqlSession.commit();  //释放会话资源  try {   sqlSession.close();  } catch (Exception e) {   e.printStackTrace();  }  } inserUser函数

(2)模糊查询

首先配置Mapper文件,${}和#{}的简单区别如下:

<!--  模糊查询可能会查询多条记录  resultType:指定的就是查询结果对应的单条记录类型  ${}:表示将输入的参数不加任何的修饰,直接作为字符串拼接在SQL中  但是这样直接拼接,容易导致SQL注入的隐患  ${value}中的value表示接受的输入参数,注意如果输入参数是简单类型,其中的形参只能用value  -->  <select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.mybatis.po.User">  SELECT * FROM t_user WHERE username LIKE '%${value}%'  </select>

Mybatis怎么用

使用查询的时候碰到一个小错误,由于之前测试的insert方法,其中在User实体类中添加了有参构造函数,所以出现了下面的错误,分析原因就是:使用Mybatis查询的时候需要在实体类中加入无参构造方法(当然如果实体类本身没有构造函数,就会是默认的无参构造函数)

Mybatis怎么用

附上findByUsername的函数实现

public void findUserByUsername() throws IOException {  //得到配置文件的文件流信息  InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  SqlSession sqlSession = sqlSessionFactory.openSession();  List<User> userList = sqlSession.selectList("test.findUserByUsername","u");  System.out.println(userList);  //释放会话资源  try {   sqlSession.close();  } catch (Exception e) {   e.printStackTrace();  }  } findByUsername函数实现

(3)删除操作

首先在Mapper中配置删除的操作

 <delete id="deleteUser" parameterType="java.lang.Integer">   DELETE FROM t_user WHERE id = #{value}  </delete>

运行测试程序,同insert中一样,需要手动提交事务,如下面所示

Mybatis怎么用

最终结果:

数据表中删除了编号为10的数据记录

Mybatis怎么用

Mybatis怎么用

5.细节整理

(1)关于示例程序中一些相关类的理解

   a)SqlSessionFactoryBuilder

   用来创建SqlSessionFactory。因为SqlSessionFactory使用了单例模式,所以不需要使用单例模式来管理SqlSessionFactoryBuilder,只需要在创建SqlSessionFactory时 候使用一次就可以

   b)SqlSessionFactory

   会话工厂,用来创建SqlSession。可以使用单例模式来管理SqlSessionFactory这个会话工厂,工厂创建之后,就一直使用一个实例。

   c)SqlSession

   面向程序员的接口,提供了操作数据库的方法。SqlSession是线程不安全的(原因:在SqlSession实现类中除了接口中的操作数据库的方法之外,还有数据域的属性,比如说一些提交的数据等等,所以在多线程并发请求的时候,会导致线程不安全),所以我们可以将SqlSession使用在方法体里面,这样每个线程都有自己的方法,就不会冲突

(2)Mybatis中mapper映射文件

  如同解释Mybatis执行原理的时候一样,Mapper映射文件中配置的Sql语句,实际上在执行的时候都被封装称为一个个MapperStatment对象,即Mapper映射文件是按照statment来管理不同的Sql。在编写程序的时候,我们在使用SqlSession其中的操作数据库的方法(selectOne,selectList等等)的时候,传入的参数除了实参(id,模糊查询的字符串等等)之外,还需要传入的就是相应的Sql位置,而Sql是被Statment管理,所以就是传入namespace+statmentId

(3)占位符

   #{id}:其中的id表示的就是接受的输入参数,参数名称就是id,这里指出:如果输入参数是简单类型,#{}中的参数名可以任意设置(value或者其他名称)

   ${value}:表示将输入的参数不加任何的修饰,直接作为字符串拼接在SQL中但是这样直接拼接,容易导致SQL注入的隐患${value}中的value表示接受的输入参数,注意如果输入参数是简单类型,其中的形参只能用value

(4)别名定义

     ①单个别名的定义

<typeAliases>  <!--针对单个别名的定义-->  <typeAlias type="cn.mybatis.po.User" alias="user"></typeAlias>  </typeAliases>

      定义别名后的使用

 <select id="findUserByIdTest" parameterType="int" resultType="user">   SELECT * FROM t_user WHERE id = #{id}  </select>

     ②批量别名的定义

 <typeAliases>   <!--批量别名定义:Mybatis在定义别名的时候会自动扫描包中的po类,自动的将别名定义为类名(首字母大写或者小写都可以)-->   <package name="cn.mybatis.po"></package>  </typeAliases>

(5)在SqlMapConfig.xml中加载Mapper映射文件的时候,除了通过resource的方式,还可以使用mapper接口加载的方式来实现

  ①首先先注意一点:

     在配置mybatis-config.xml时,其中的节点是有顺序的,配置顺序依次为:

properties/settings/typeAliases/typeHandlers/objectFactory/objectWrapperFactory/plugins/environments/databaseIdProvider/mappers

     ②使用mapper加载的方式,要将mapper接口和mapper配置文件放在同一目录下面,并且文件名称一致,而且要遵循mapper代理的方式进行开发

 <mappers>   <mapper class="cn.mybatis.mapper.UserMapper"></mapper>  </mappers>

Mybatis怎么用

6.Mybatis开发dao方法简介

  (1)使用dao接口+实现类的方式

   a)首先编写接口,如同一般编写模式方式进行编写

package cn.mybatis.dao; import cn.mybatis.po.User; /**  * 原始Dao方式开发:dao接口+dao实现类的方式  */ public interface UserDao {  //根据id查询信息  public User findUserById(int id) throws Exception;  //添加信息  public void insertUser(User user) throws Exception;  //删除信息  public void deleteUser(int id) throws Exception; } dao接口

   b)然后编写接口实现

package cn.mybatis.dao.daoImpl; import cn.mybatis.dao.UserDao; import cn.mybatis.po.User; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.junit.Test; public class UserDaoImpl implements UserDao {  //使用构造方法注入SqlSessionFactory  private SqlSessionFactory sqlSessionFactory;  public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {   this.sqlSessionFactory = sqlSessionFactory;  }  @Override  @Test  public User findUserById(int id) throws Exception {   SqlSession sqlSession = sqlSessionFactory.openSession();   User user = sqlSession.selectOne("test.findUserById",id);   sqlSession.close();   return user;  }  @Override  public void insertUser(User user) throws Exception {   SqlSession sqlSession = sqlSessionFactory.openSession(); //  User user1 = new User("test1","123","洪山区","男");   sqlSession.insert("test.findUserById",user);   sqlSession.commit();   sqlSession.close();  }  @Override  public void deleteUser(int id) throws Exception {   SqlSession sqlSession = sqlSessionFactory.openSession();   sqlSession.delete("test.findUserById",id);   sqlSession.commit();   sqlSession.close();  } } dao接口实现类

   c)Mapper配置文件和SqlConfig配置文件不变

   d)使用Junit进行测试

package cn.mybatis.testdao; import cn.mybatis.dao.UserDao; import cn.mybatis.dao.daoImpl.UserDaoImpl; import cn.mybatis.po.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; public class UserDaoImplTest {  private SqlSessionFactory sqlSessionFactory;  @Before  public void setUp() throws Exception {   InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");   sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  }  @Test  public void testFindUserById() throws Exception{   //创建UserDao的对象   UserDao userDao = new UserDaoImpl(sqlSessionFactory);   //调用UserDao的方法   User user = userDao.findUserById(1);   System.out.println(user );  } } Junit测试

   e)测试结果

Mybatis怎么用

   f)原始dao方法的问题

    ①dao接口实现中存在大量的模板方法(即很多重复性的代码 )

    ②调用SqlSession方法的时候将statmentid硬编码了

    ③条用SqlSession方法的时候传入的参数,由于使用泛型,所以在编译阶段不会报错(即使传入参数错误)

  (2)使用Mapper代理的方法(即只需要Mapper接口)

  (a)使用mapper方式的规范

    ①在使用mapper代理的方式中,namespace的值应该是mapper接口的路径

    ②在mapper.java接口文件中的接口方法名称和mapper.xml中的statment的id一致

    ③在mapper.java接口文件中的接口方法的输入参数和mapper.xml中的statment的parameterType一致

    ④在mapper.java接口文件中的接口方法的返回值类型和mapper.xml中的statment的resultType一致

  (b)查询、删除操作实例

    ①编写mapper.xml配置文件,其中包含select和delete的sql配置

<?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指定了命名空间--> <!--在使用mapper代理的方式中,namespace的值应该是mapper接口的路径--> <mapper namespace="cn.mybatis.mapper.UserMapper">  <select id="findUserById" parameterType="int" resultType="cn.mybatis.po.User">   SELECT * FROM t_user WHERE id = #{id}  </select>  <delete id="deleteUser" parameterType="java.lang.Integer">   DELETE FROM t_user WHERE id = #{value}  </delete> </mapper> mapper.xml配置文件

    ②编写mapper接口,按照mapper代理的方式开发规范来编写mapper的接口

package cn.mybatis.testmapper; import cn.mybatis.mapper.UserMapper; import cn.mybatis.po.User; 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 org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; public class UserMapperTest {  private SqlSessionFactory sqlSessionFactory;  @Before  public void setUp() throws Exception {   InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");   sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  }  @Test  public void testFindUserById() throws Exception{   SqlSession sqlSession = sqlSessionFactory.openSession();   //得到UserMapper的代理对象   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   User user = userMapper.findUserById(9);   System.out.println(user);  }  @Test  public void testDeleteUser() throws Exception {   SqlSession sqlSession = sqlSessionFactory.openSession();   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   userMapper.deleteUser(9);   sqlSession.commit();  }  @After  public void tearDown() throws Exception {  } } mapper接口

    ③Junit测试

package cn.mybatis.testmapper; import cn.mybatis.mapper.UserMapper; import cn.mybatis.po.User; 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 org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.InputStream; public class UserMapperTest {  private SqlSessionFactory sqlSessionFactory;  @Before  public void setUp() throws Exception {   InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");   sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  }  @Test  public void testFindUserById() throws Exception{   SqlSession sqlSession = sqlSessionFactory.openSession();   //得到UserMapper的代理对象   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   User user = userMapper.findUserById(8);   System.out.println(user);  }  @Test  public void testDeleteUser() throws Exception {   SqlSession sqlSession = sqlSessionFactory.openSession();   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   userMapper.deleteUser(8);  }  @After  public void tearDown() throws Exception {  } } Junit测试

    ④查询结果展示

Mybatis怎么用

    ⑤删除结果展示

Mybatis怎么用

关于“Mybatis怎么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI