Mybatis学习

Mybatis学习

1.安装Mybatis依赖

用Maven项目配置Mybatis依赖

<dependency>
  <groupId>org.mybatisgroupId>
  <artifactId>mybatisartifactId>
  <version>x.x.xversion>
dependency>

2.MyBatis XML配置文件

2.1配置文件的基本骨架



<configuration>
    
configuration>

2.2properties元素

在配置文件中通过在properties配置一些property,这些property可以在配置文件的其他位置通过${propertyname}的方式来进行引用。

<properties resource="org/mybatis/example/config.properties">
  <property name="driver" value="com.mysql.jdbc.Driver"/>
  <property name="url" value="jdbc:mysql://localhost:3306/User"/>
  <property name="username" value="root"/>
  <property name="password" value="123456"/>
properties>

在整个配置文件中用来替换需要动态配置的属性值,比如:

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

属性配置的优先级:

  • 通过java方法传递的配置
  • 通过properties中的resource对应的配置文件
  • 当前properties 属性中指定的属性

2.3settings元素

在MyBatis的XML配置文件中可以通过settings字段元素配置MyBatis 的运行时行为

<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="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <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>

2.4 typeAliases元素

我们可以通过typeAliases元素来配置java类中类路径名的别名,以后要写类的全路径名时,就可以用简短的别名来代替。

<typeAliases>
  <typeAlias alias="User" type="com.book.User"/>
  <typeAlias alias="ShopList" type="com.book.ShopList"/>
typeAliases>

也可以这样配置,通过扫描包下的所有类并以类名为全路径名:

<typeAliases>
  <package name="com.book"/>
typeAliases>

或者在写代码的通过注解的方式设置

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

2.5 objectFactory元素

objectFactory元素可以配置设置自己的对象工厂。MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。

自定义工厂类

这里工厂类有四个方法。

前两个方法分别对应处理默认无参构造方法和处理有参构造,可以在这两个方法添加一些类创建前的处理。

后两个方法setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。

// ExampleObjectFactory.java
    public class ExampleObjectFactory extends DefaultObjectFactory {
     
      public Object create(Class type) {
     
        return super.create(type);
      }
      public Object create(Class type, List constructorArgTypes, List constructorArgs) {
     
        return super.create(type, constructorArgTypes, constructorArgs);
      }
      public void setProperties(Properties properties) {
     
        super.setProperties(properties);
      }
      public  boolean isCollection(Class type) {
     
        return Collection.class.isAssignableFrom(type);
      }}

在xml中指定自己的工厂类


<objectFactory type="org.mybatis.example.ExampleObjectFactory">
  <property name="someProperty" value="100"/>
objectFactory>

2.6plugins元素

MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。MyBatis 允许使用插件来拦截的方法调用包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

创建自己的插件类

/**
 * @Intercepts 拦截器注解,包括一个或多个 @Signature
 * @Signature 拦截的目标类信息,包括 type、method、args
 * * type 要拦截的接口类型(对应Executor,ParameterHandler,ResultSetHandler,StatementHandler)
 * * method 接口中的方法名(接口中的方法)
 * * args 方法的所有入参类型
 */
@Intercepts({
     
        @Signature(
        type = StatementHandler.class, 
        method = "prepare", 
        args = {
     Connection.class, Integer.class}
        )
})
public class ExamplePlugin implements Interceptor {
     
    //自定义的拦截逻辑
	@Override
    public Object intercept(Invocation invocation) throws Throwable {
     
        //invocation为调用对象
    	// MetaObject 是 Mybatis 提供的一个用于访问对象属性的对象
        MetaObject metaObject = SystemMetaObject.forObject(invocation);
        
        //通过getValue获取信息
        //拦截的对象
        metaObject.getValue("target");
        //拦截的sql语句
        metaObject.getValue("target.delegate.boundSql.sql");
        
		//setValue设置信息
        //更改sql语句
        //metaObject.setValue("target.delegate.boundSql.sql", newSQL);
        
        
        // 返回执行结果(调用执行并传递给下一步)
        return invocation.proceed();
    }
     public Object plugin(Object target) {
     
        return Plugin.wrap(target, this);
      }
      public void setProperties(Properties properties) {
     
      }
}

配置插件


<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  plugin>
plugins> 

2.7environments元素

MyBatis 可以配置成适应多种环境,例如,开发、测试和生产环境需要有不同的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多类似的用例。

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    transactionManager>
    <dataSource type="POOLED">
      
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    dataSource>
  environment>
    
    
    ......
environments>
  • environments default=“development” 环境(开发,测试,生产环境)
  • environment id=“development” 环境ID号,用于标识环境
  • transactionManager type=“JDBC” 设置MyBatis 中有两种类型的事务管理器(JDBC|MANAGED)
  • dataSource type=“POOLED” 连接池模式

2.8mappers元素

映射器(mappers),用于配置SQL语句的映射,但是首先我们需要告诉 MyBatis 到哪里去找到这些语句。通过mappers字段配置XML映射文件的位置。

<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
mappers>

或者这样

<mappers>
  <package name="org.mybatis.builder"/>
mappers>

3.mybatis的XML映射文件

3.1映射文件的骨架

namespace="org.mybatis.example.BlogMapper"标明映射的mapper接口命名空间。每个mapper映射文件都对应一个映射器。每个mapper映射器都要注册到Mybatis的配置文件。(上面的mappers元素中配置)

映射器:



<mapper namespace="org.mybatis.example.BlogMapper">
    
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  select>
mapper>

对应的映射接口:

package org.mybatis.example;
public interface BlogMapper {
     
  Blog selectBlog(int id);
}

使用java注解映射SQL语句

除了通过xml设置sql语句还可以在代码里面通过java注解的方式来实现SQL语句的映射。

package org.mybatis.example;
public interface BlogMapper {
     
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
    
  @Delete("delete from blog where id = #{id}")
  void deleteBlog(int id);
  
}

MyBatis 的真正强大在于它的映射语句,mybatis通过SQL 映射语句,将实体类中属性与数据库中字段映射。比较常用的映射如下:

  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句

MyBatis 通过Mapper XML 文件来配置映射语句。

3.1 select

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
select> 

<select id="selectPerson" parameterType="int" resultType="com.book.pojo.author">
  SELECT * FROM author WHERE ID = #{id}
select> 
  • select的id属性是在命名空间中唯一的标识符,用来引用这条语句。
  • #{id} 是传递的id
  • parameterType=“int” 传递的参数类型
  • resultType=“hashmap” 指定期望从这条语句中返回值。(可以指定项目实体类)
  • 关于select字段的属性可以参考官方文档:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html

3.2 insert update delete

跟select一样,SQL语句写在字段之间,并且通过唯一的ID号来标识该SQL语句。

<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
insert>

<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
update>

<delete id="deleteAuthor">
  delete from Author where id = #{id}
delete>

更多的配置应该参考官方文档,而本文章跟注重如何快速使用mybatis,使用下面直接讲如何使用java调用这些配置好的SQL语句。

4.用SqlSession执行SQL

MyBatis 的主要 Java 接口就是 SqlSession。你可以通过该接口来执行SQL命令。SqlSession通过:

  • SqlSessionFactoryBuilder ——> SqlSessionFactory ——> SqlSession

上面的流程可以知道,创建SqlSession要先创建SqlSessionFactory,要创建 SqlSessionFactory 要通过SqlSessionFactoryBuilder来创建。

4.1 SqlSessionFactoryBuilder

首先先new一个SqlSessionFactoryBuilder

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

SqlSessionFactoryBuilder通过build 方法来创建SqlSessionFactory,SqlSessionFactoryBuilder 有五个 build() 方法,每一种都允许你从不同的资源中创建一个 SqlSessionFactory 实例。

SqlSessionFactory build(InputStream inputStream)
SqlSessionFactory build(InputStream inputStream, String environment)
SqlSessionFactory build(InputStream inputStream, Properties properties)
SqlSessionFactory build(InputStream inputStream, String env, Properties props)
SqlSessionFactory build(Configuration config)
  • inputStream 指向 MyBatis XML配置文件
  • environment 决定加载哪种环境(回想一下xml配置文件中的environments元素)
  • properties 传递的配置属性 (回想一下xml配置文件中的properties元素,这个是Java代码方式的传递)

创建SqlSessionFactory官方示例:

String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);

4.2 SqlSessionFactory

SqlSessionFactory是用来创建SqlSession,SqlSessionFactory可以认为是在数据源中获得数据库连接然后封装在SqlSession中供程序员使用。

SqlSessionFactory 有多个方法创建 SqlSession 实例。

SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)

默认的 openSession() 方法没有参数,它会创建具备如下特性的 SqlSession:

  • 事务作用域将会开启(也就是不自动提交)。
  • 将由当前环境配置的 DataSource 实例中获取 Connection 对象。
  • 事务隔离级别将会使用驱动或数据源的默认设置。
  • 预处理语句不会被复用,也不会批量处理更新。

参数:

  • autoCommit 事务自动提交

  • connection 自己的数据库连接

  • TransactionIsolationLevel 事务隔离级别

    • NONEREAD_UNCOMMITTEDREAD_COMMITTEDREPEATABLE_READSERIALIZABLE
  • execType 执行类型

  • ExecutorType.SIMPLE:该类型的执行器没有特别的行为。它为每个语句的执行创建一个新的预处理语句。

  • ExecutorType.REUSE:该类型的执行器会复用预处理语句。

  • ExecutorType.BATCH:该类型的执行器会批量执行所有更新语句,如果 SELECT 在多个更新中间执行,将在必要时将多条更新语句分隔开来,以方便理解

4.3 SqlSession

SqlSession包含了所有执行语句、提交或回滚事务以及获取映射器实例的方法。SqlSession用于执行SQL。

执行sql语句

<T> T selectOne(String statement, Object parameter)
<E> List<E> selectList(String statement, Object parameter)
<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<T> Cursor<T> selectCursor(String statement, Object parameter)
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
int insert(String statement, Object parameter)
int update(String statement, Object parameter)
int delete(String statement, Object parameter)

旧版本 MyBatis

这里的org.mybatis.example.BlogMapper.selectBlog对应mapper映射器+执行语句的ID。如:

  • org.mybatis.example.BlogMapper 对应BlogMapper.xml中的namespace
  • selectBlog 对应mapper映射器中的selectBlog方法
try (SqlSession session = sqlSessionFactory.openSession()) {
     
  Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}

新版本MyBatis

较新的版本官方建议通过getMapper来获取映射的接口先,再执行接口的方法。

try (SqlSession session = sqlSessionFactory.openSession()) {
     
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
}

5.小整理

快速使用mybatis的过程:

  1. 创建mybatis配置文件并编写配置信息(如:环境,属性等)
  2. 创建实体类(如:User.class)
  3. 创建mapper接口 (如:UserMapper)
  4. 创建xml映射文件 (如:UserMapper.xml)
  5. 注册映射器到mybatis配置文件 (在mappers元素中配置)
  6. 创建SqlSessionFactoryBuilder,再创建SqlSessionFactory,然后获取SqlSession
  7. 通过SqlSession的getMapper获取mapper(映射器)
  8. 通过Mapper调用mapper接口的方法.

6.spring整合mybatis

6.1maven安装相关依赖:

<dependency>
  <groupId>org.mybatisgroupId>
  <artifactId>mybatis-springartifactId>
  <version>2.0.6version>
dependency>

spring整合mybatis后,mybatis中的SqlSessionFactory和SqlSession都交由spring来进行托管。

6.2 配置数据源

首先要在spring的配置文件中配置数据源,数据源可以是多种,c3p0,DBCP,spring自带的等都行。

<bean id="dataSource"  
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />   
    <property name="url" value="jdbc:mysql://localhost:3306/User?useSSL=true" />   
    <property name="username" value="root" />   
    <property name="password" value="root">   
bean>    

6.3 配置sqlSessionFactoryBean

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="dataSource" ref="dataSource" />
   
  <property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
bean>

6.4 配置SqlSessionTemplate

官方解析:

SqlSessionTemplate 是 MyBatis-Spring 的核心。作为 SqlSession 的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的 SqlSessionSqlSessionTemplate 是线程安全的,可以被多个 DAO 或映射器所共享使用。注意这里标的“无缝代替”。

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  <constructor-arg index="0" ref="sqlSessionFactory" />
bean>

6.5注入SqlSessionTemplate

先编写UserDao接口的实现类

public class UserDaoImpl implements UserDao {
     

  private SqlSession sqlSession;

  public void setSqlSession(SqlSession sqlSession) {
     
    this.sqlSession = sqlSession;
  }

  public User getUser(String userId) {
     
    return sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}

注入SqlSessionTemplate,并将实现类给spring托管。

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSession" ref="sqlSession" />
bean>

6.6使用SqlSessionDaoSupport的方式

官方提供了一个SqlSessionDaoSupport,SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
     
  public User getUser(String userId) {
     
    return getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
  }
}

使用SqlSessionDaoSupport就可以跳过配置SqlSessionTemplate的这一步,在进行注入的时候,不在是SqlSessionTemplate,而是直接引用sqlSessionFactory。

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>

你可能感兴趣的:(java,mybatis,spring,mysql,java,spring,boot)