Mybatis使用详情

本文详细介绍了Mybatis ORM的配置流程,包括jar包引入、主配置文件编写、工具类的实现、实体类与接口设计,以及SQL映射文件的编写。涵盖了事务管理、级联查询、多参数传递和配置文件的高级技巧,适合初学者和进阶开发者参考。
摘要由CSDN通过智能技术生成

ⅩⅣ.Mybatis

ORM(Object Relational Mapping)
编写程序的时候,以面向对象的方式处理数据
保存数据的时候,却以关系型数据库的方式存储
ORM解决方案包含下面四个部分
在持久化对象上执行基本的增、删、改、查操作
对持久化对象提供一种查询语言或者API
对象关系映射工具
提供与事务对象交互、执行检查、延迟加载以及其他优化功能

Mybatis配置

1.jar包

导入mybatis-3.4.1.jar包

2.编写主配置文件

在src下创建 MyBatis 主配置文件 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>
  <environments default="development">
      <!--可创建多个environment连接,在使用到某个数据库连接时,把environments default属性
		修改为environment id的值-->
    <environment id="development">
      <transactionManager type="JDBC" />
      <dataSource type="POOLED">  //连接池
	  <property name="driver" value="oracle.jdbc.OracleDriver" />	
          <!--连接驱动名-->
	  <property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
          <!--数据库连接地址-->
	  <property name="username" value="scott" />
          <!--数据库连接用户名-->
	  <property name="password" value="tiger" />
          <!--数据库连接密码-->
      </dataSource>
    </environment>
  </environments>
  
    <mappers>
   		<mapper resource="dao/EmpDaoMapper.xml"></mapper>
 	</mappers>
	<!--映射文件写完后,将其添加到该处-->
</configuration>

3.创建工具类

编写实用工具类,根据 mybatis.xml 创建 SqlSessionFactory,通过SqlSessionFactory打开SqlSession

//编写工具类时注意SqlSessionFactoryBuilder只能创建一次,防止占用内存
//使用SqlSessionFactionBulider创建SqlSessionFactory
//SqlSessionFactoryBulider的生命周期再程序开始时创建SqlSessionFactory便消亡
//SqlSessionFactory的生命周期是在程序创建期间一直存在
//使用SqlSessionFactory,创建对数据库的连接SqlSession
//Sqlsession的生命周期是在一次与数据库的会话中存在
public class SqlSessionFactoryUtil {
    private static SqlSessionFactory factory;
    private SqlSessionFactoryUtil(){}
    static{
	Reader reader = null;
	try{
         reader = Resources.getResourceAsReader("mybatis.xml");	
        //使用IO字符流读取Mybatis配置文件
         factory = new SqlSessionFactoryBuilder().build(reader);
        //使用SqlSessionFactoryBuilder创建出SqlSessionFactory
	} catch (Exception e) {
		e.printStackTrace();
	}finally{ 
        if(reader!=null)
            reader.close();
        //如果读取为空则关闭字符流
    }
    }

    public static SqlSession getSqlSession(){
	 return  factory.openSession(true);
        //返回SqlSessionFactory创建的会话sqlsession
        //为factory创建的sql会话配置true,即自动提交事务
        //设置完成后,在执行完增删改操作后自动提交,不需要手动提交
    }
}

4.创建实体类

实体类的属性与数据库表的列一一对应

数据库的每一行对应实体类的每一个对象

5.编写接口

package dao;
public interface EmpDao{
	public List<Emp> searchAll();
} 
//编写接口,使得映射文件得到地址

6.编写mapper.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="dao.EmpDao">
<!--命名空间为接口的地址-->
  <select id="searchAll" resultType="domain.Emp">
     select empno as empNo,ename as empName,
     sal as salary,hiredate from emp
  </select>
</mapper>

7.测试 @Before @After

public class UserTest {
    UserDao dao = null;
    SqlSession  session = null;
    
    @Before
    public void open() {
        session = SqlSessionUtil.getSqlsession();
        dao = session.getMapper(UserDao.class);
    }
    //防止需要测试的代码中创建session重复冗余,使用@Before在测试之前进行初始化
    
    @Test
    public void SelectUserByTest(){
        User user = dao.SelectUserBy(3);
        System.out.println(user.getId()+"\t"+user.getUsername());
    }
    
    @After
    public void close(){
        session.close();
    }
    //在测试之后使用@After对session进行关闭
}

8.调试: log4j

1.添加jar包和properties资源文件
2.如果不需要调试,就将log4j.rootLogger = debug,stdout 中的debug改为error。控制台就不会打印详细运行信息。

9.总结

select标签必须有resultType或者resultMap,如果返回值时list ,resultType可以设定为list里面的类的类型

select 中 as是指定 属性和列的映射关系(ORM) as左边是属性,右边为列名。 如果属性和列拼写一致,那么可以不写as ,都一直,可以写为select * from

需要传参的时候使用#{参数对应的属性},如果只有一个参数,那么这个值可以随便写。

#{}相当于(preparedStatement) ${}相当于(Statement)

10.异常

如果传入参数不是实体,而是int、string等基本数据类型的单一参数时

import com.xyd.bean.User;

public interface UserDao {
    User SelectUserBy(Integer id);
}

这里就涉及到mybatis的内置对象_parameter,单个参数判断的时候,就不像1、 2那样直接用参数对象名判断了。还有就是数据类型最好加上

<mapper namespace="com.xyd.dao.UserDao">
    <!--命名空间为接口的地址-->
    <select id="SelectUserBy" resultType="com.xyd.bean.User" parameterType="java.lang.Integer">
        select * from t_user
        <where>
            <if test="_parameter!=null">
                <!--最好使用_parameter来获取单一参数的值-->
                id=#{_parameter}
            </if>
        </where>
    </select>
</mapper>

或者不使用_parameter,使用注解@Param

User SelectUserBy( @Param("userid")int userid);

mybatis使用

1.配置实体类包

在mybatis的配置文件mybatis—config.xml中配置实体类包的地址,可以减少代码重复,本质就是为每个实体类配置别名

<!--mybatis—config.xml-->
<typeAliases>
        <typeAlias type="com.xyd.entity.User" alias="user"/>
</typeAliases>
//使用此代码可以使resultType的值不再有很多的重复,相当于直接为实体类配置别名

<!--XXXmapper.xml-->
<select id="SelectUserBy" resultType="user" parameterType="int">
        select * from t_user
        <where>
            <if test="userid!=0">
                id=#{userid}
            </if>
        </where>
</select>

<!--也可以直接把实体类打包设置别名-->
<!--mybatis—config.xml-->
<typeAliases>
        <package name="com.xyd.entity"/>
</typeAliases>
<!--设置的别名为实体类去掉大写字母改为小写字母-->
<!--XXXmapper.xml-->
<select id="SelectUserBy" resultType="user" parameterType="int">
        select * from t_user
        <where>
            <if test="userid!=0">
                id=#{userid}
            </if>
        </where>
</select>

2.编写工具类高并发版

每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能被共享也是线程不安全的。因此最佳的范围是请求或方法范围。使用Web框架时,要考虑SqlSession放在一个和HTTP请求对象相似的范围内。基于收到的HTTP请求,打开了一个SqlSession,返回响应后关闭。关闭Session很重要,应该确保使用finally块来关闭它。基本模式:
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}

package com.util;

import com.dao.UserMapper;
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;

/**
 * 1、创建和初始化SqlSessionFactory
 * 2、创建一个open方法返回一定范围内(线程)可用的SqlSession
 * 3、创建一个close方法,来关闭一定范围内的SqlSession
 * 4、创建commit、rollback等事务管理方法
 * 5、创建一些其它的Mybatis相关方法
 * 6、每个不同的线程访问时都会创建一个自己的sqlsession储存在线程池中,使用时获取自己的
 *    sqlsession,这样sqlsession在线程内就是安全的
 */
public class MybatisUtils {

    static ThreadLocal<SqlSession> THREAD_LOCAL = new ThreadLocal<>();
    static final String CONF_FILE = "mybatis-config.xml";
    static SqlSessionFactory factory = null;
    static{
        initFactory(CONF_FILE);
    }
    public static void initFactory(String configFile){
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        try {
            InputStream resourceAsStream =
                    Resources.getResourceAsStream(configFile);
            factory = builder.build(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession open(){
        SqlSession session = THREAD_LOCAL.get();
        if(session == null){
            session = factory.openSession();
            THREAD_LOCAL.set(session);  //
        }
        return session;
    }

    public static void close(){
        SqlSession session = THREAD_LOCAL.get();
        if(session != null){
            session.close();
            THREAD_LOCAL.set(null);
        }
    }

    public static void commit(){
        SqlSession session = THREAD_LOCAL.get();
        if(session!=null)
            session.commit();
    }

    public static void rollback(){
        SqlSession session = THREAD_LOCAL.get();
        if(session!=null)
            session.rollback();
    }

    // 获取Dao层映射对象,
    public static <T> T getMapper(Class<T> tClass){
        return open().getMapper(tClass);
    }

    public static void main(String[] args) {
        SqlSession s1 = open();
        // 1s
        SqlSession s2 = open();
        // 10s
        SqlSession s3 = open();
        // 场景1,重定向
        // s1 -> A(伊滨)   线程1  request->response open()
        // s2 -> B(西工)   线程2  request->response open()
        // s3 -> C(涧西)   线程3  request->response open()
        // s4 -> A(伊滨)   线程4  request->response open()
        // 场景2,转发
        // s <-> A(伊滨) -电话-> B(西工) -(电话)-> C(涧西)
        //                线程1 request->response open()/open()/open()
        UserMapper dao = getMapper(UserMapper.class);
    }
}

在配置完成之后创建过滤器,过滤需要访问的请求

package com.filter;

import com.util.MybatisUtils;
import org.apache.log4j.Logger;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(urlPatterns = "/*",filterName = "SqlSessionFilter")   // web.xml
public class SqlSessionFilter implements Filter {
    // 日志工具
    static final Logger log = Logger.getLogger(SqlSessionFilter.class);
    // a(过滤器)->b(Servlet)->c(Dao)
    // a先开始,后结束,
    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //http://localhost:8080/login=>path:/login
        String path = request.getServletPath();
        log.debug("["+path+"] coming...");
        if(path != null && !(
                path.endsWith("jsp")  ||
                        path.endsWith("html") ||
                        path.endsWith("htm") ||
                        path.endsWith("jpg") ||
                        path.endsWith("jpeg") ||
                        path.endsWith("png") ||
                        path.endsWith("gif") ||
                        path.endsWith("bmp") ||
                        path.endsWith("ico") ||
                        path.endsWith("js") ||
                        path.endsWith("css") ||
                        path.endsWith("avi") ||
                        path.endsWith("mp4") ||
                        path.endsWith("mp3") ||
                        path.endsWith("mkv") ||
                        path.endsWith("rm") ||
                        path.endsWith("rmvb")
        )) {
            try {
                log.debug("["+path+"] opening SqlSession...");
                // 1、请求到来
                MybatisUtils.open();
                // 2、调用目标,b
                log.debug("["+path+"] executing sql...");
                filterChain.doFilter(servletRequest, servletResponse);

                log.debug("["+path+"] end sql...");
                MybatisUtils.commit();
                log.debug("["+path+"] commit sql...");
            } catch (Exception e) {
                MybatisUtils.rollback();        // 回滚
                log.debug("["+path+"] rollback sql...");

//                log.debug("["+path+"] closing SqlSession...");
//                MybatisUtils.close();
                throw new ServletException(e);  // 在抛出异常
            } finally {
//                 3、响应返回
                log.debug("["+path+"] closing SqlSession...");
                MybatisUtils.close();
            }
        }else{
            filterChain.doFilter(servletRequest, servletResponse);
        }
        log.debug("["+path+"] stop!!!");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

3.级联查询

Mybatis的双向一对多(多对一)的配置

  • 一的一方要创建多的一方的集合要注意初始化

    • private List list = new ArrayList();

    • mapper文件当中需要配置的是collection

  • 多的一方要创建一的一方的对象

    • mapper文件中需要的是association
①(多对一)association
<resultMap id="topicuser" type="org.zk.entity.Topic">
	<id property="topicId" column="topicid" javaType="int"/>
	<result property="title" column="title"/>
    <!--property对应的是属性 ,column对应的是列名-->
	<association property="user" column="userid" javaType="org.zk.entity.User">
        <!--
			property对应的是属性 
			column对应的是列名
			javaType对应的是属性的类型
		-->
		<id property="userId" column="userid"/>
		<result property="name" column="username"/>
	</association>
</resultMap>
<!--注意
	多对一查询时,类中的一为单一实体类
	如板块与新闻
	新闻中板块的对应为板块类Board
-->
<select id="getTopicAndUserByTopic" parameterType="org.zk.entity.Topic" resultMap="topicuser">
	select t.topicid,t.title,t.pic,t.content,t.writedate,u.userid,u.username 
    from     
    t_topic t inner join t_user u
	on t.userid = u.userid where topicid=#{topicId}
</select>

②(一对多)collection
<resultMap id="userAndTopic" type="org.zk.entity.User">  
	<id property="userId" column="userid" javaType="int"/>
	<result property="name" column="username"/>
	<result property="pwd" column="password"/>
    <!--property对应的是属性 ,column对应的是列名-->
	<collection property="topicList" ofType="org.zk.entity.Topic" column="userid">
        <!--
			property对应的是属性 
			column对应的是列名
			ofType对应的是集合中属性的类型
		-->
        
		<id property="topicId" column="topicid" javaType="int"/>
		<result property="title" column="title"/>
		<result property="content" column="content"/>
    </collection>
</resultMap>
<!--注意
	一对多查询时,类中的一为实体类集合
	如板块与新闻
	板块中新闻的对应为新闻类集合:List<News>
-->
<select id="getUserAndTopic" parameterType="int" resultMap="userAndTopic">
    select u.*,t.* from t_user u ,t_topic t where t.userid=u.userid and  u.userid= #{userId}
</select>

4.XML映射配置文件

MyBatis的XML配置文件包含了影响MyBatis行为甚深的设置和属性信息。XML文档的高层级结构如下:

  • configuration配置
    • properties属性
    • settings设置
    • typeAliases类型命名
    • typeHandlers类型处理器
    • objectFactory对象工厂
    • plugins插件
    • environments环境
      • environment环境变量
        • transactionManager事务管理器
        • dataSource数据源
    • mappers
properties配置

这些是外部化的,可替代的属性,这些属性也可以配置在典型的Java属性配置文件中,或者通过properties元素的子元素来传递。例如:mybatis-config.xml中的配置

<!--mybatis—config.xml-->
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>

其中的属性就可以在整个配置文件中使用,使用可替换的属性来实现动态配置。比如:

<!--mybatis—config.xml-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>

这个例子中的username和password将会由properties元素中设置的值来替换。driver和url属性将会从包含进来的config.properties文件中的值来替换。

#config.porperties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/company?characterEncoding=utf8&amp;useAffectedRows=true&amp;useUnicode=true&amp;serverTimezone=Asia/Shanghai
username=root
password=123456

属性也可以被传递到SqlSessionBuilder.build()方法中。例如://注意这种方法不常用

SqlSessionFactory factory =
sqlSessionFactoryBuilder.build(reader, props);
// ... or ...
SqlSessionFactory factory =
sqlSessionFactoryBuilder.build(reader, environment, props);

如果在这些地方,属性多于一个的话,MyBatis按照如下的顺序加载它们:
在properties元素体内指定的属性首先被读取。
从类路径下资源或properties元素的url属性中加载的属性第二被读取,它会覆盖已经存在的完全一样的属性。
作为方法参数传递的属性最后被读取,它也会覆盖任一已经存在的完全一样的属性,这些属性可能是从properties元素体内和资源/url属性中加载的。

Settings配置

用来修改MyBatis在运行时的行为方式。
一个设置信息元素的示例,完全的配置如下所示: //注意:这些属性配置不配置的话都是默认值,

<!--mybatis—config.xml-->
<!--现在的属性值即为默认值,如果需要修改再进行配置,一般不需要配置-->
<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="defaultExecutorType" value="SIMPLE"/> 默认执行器为SIMPLE
	<setting name="defaultStatementTimeout" value="25000"/> 超时时间为25000毫秒
</settings> 
typeAliases配置
<!--mybatis—config.xml-->
<typeAliases>
        <typeAlias type="com.xyd.entity.User" alias="user"/>
</typeAliases>
//使用此代码可以使resultType的值不再有很多的重复,相当于直接为实体类配置别名

对于普通的Java类型,有许多内建的类型别名。它们都是大小写不敏感的。

别名映射类型别名映射类型别名映射类型
_bytebytebyteBytedecimalBigDecimal
_longlonglongLongbigdecimalBigDecimal
_shortshortshortShortobjectObject
_intintintIntegermapMap
_integerintintegerIntegerhashmapHashMap
_doubledoubledoubleDoublelistList
_floatfloatfloatFloatarrayListArrayList
_booleanbooleanbooleanBooleancollectionCollection
stringStringdateDateiteratorIterator
environments配置

MyBatis可以配置多种环境。可以将SQL映射应用于多种数据库之中。每个SqlSessionFactory实例对应一个数据库环境。使用SqlSessionFactoryBuilder创建SqlSessionFactory时可以指定环境。如果没有指定环境将加载默认环境。
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment,properties);
环境配置:

<!--mybatis—config.xml-->
<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="" />
                <property name="url" value=""/>
                <property name="username" value="" />
                <property name="password" value="" />
            </dataSource>
        </environment>
    <!--MyBatis可以配置多种环境-->
    <!--可创建多个environment连接,在使用到某个数据库连接时,把environments default属性
		修改为environment id的值-->
        <environment id="development2">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="" />
                <property name="url" value=""/>
                <property name="username" value="" />
                <property name="password" value="" />
            </dataSource>
        </environment>
    </environments>
transactionManager配置

在MyBatis中有两种事务管理器类型(也就是type=“[JDBC|MANAGED]”):
JDBC – 这个配置直接简单使用了JDBC的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。
MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如Spring或JEE应用服务器的上下文)。默认情况下它会关闭连接。然而一些容器并不希望这样,因此如果你需要从连接中停止它,将closeConnection属性设置为false。例如:

<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
dataSource

dataSource元素使用基本的JDBC数据源接口来配置JDBC连接对象的资源。有三种内建的数据源类型:

  • UNPOOLED – 这个数据源的实现是每次被请求时简单打开和关闭连接。这是对简单应用程序的一个很好的选择,因为它不需要及时的可用连接。UNPOOLED类型的数据源仅仅用来配置以下4种属性:driver\url\username\password

  • POOLED – 这是JDBC连接对象的数据源连接池的实现,用来避免创建新的连接实例时必要的初始连接和认证时间。这是一种当前Web应用程序用来快速响应请求很流行的方法。除了上述(UNPOOLED)的属性之外,还有很多属性可以用来配置POOLED数据源,如:
    poolMaximumActiveConnections – 在任意时间存在的活动(也就是正在使用)连接的数量。默认值:10 poolMaximumIdleConnections – 任意时间存在的空闲连接数。poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检查的时间。默认值:20000毫秒(也就是20秒)

  • JNDI – 这个数据源的实现是为了使用如Spring或应用服务器这类的容器,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。这个数据源配置只需要两个属性:

    • initial_context – 这个属性用来从初始上下文中寻找环境(也就是initialContext.lookup(initial——context))。这是个可选属性,如果被忽略,那么data_source属性将会直接以initialContext为背景再次寻找。
    • data_source – 这是引用数据源实例位置的上下文的路径。它会以由initial_context查询返回的环境为背景来查找,如果initial_context没有返回结果时,直接以初始上下文为环境来查找。
      和其他数据源配置相似,它也可以通过名为“env.”的前缀直接向初始上下文发送属性。比如:
    • env.encoding=UTF8 - 在初始化之后,这就会以值“UTF8”向初始上下文的构造方法传递名为“encoding”的属性。
mappers配置

Sql映射语句一般定义在各持久类的Mapper.xml文件中,需要在配置中引用这些映射文件。可以使用相对于类路径的资源引用,或url引用的完全限定名(包括file:///URLs)。例如:

<!--使用类路径资源引用-->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!--使用完全限定名-->
<mappers>
<mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>
<mapper url="file:///var/sqlmaps/BlogMapper.xml"/>
<mapper url="file:///var/sqlmaps/PostMapper.xml"/>
</mappers>

5.SQL映射的XML文件 Mapper

SQL映射文件的几个顶级元素(按照它们应该被定义的顺序):

  • cache - 配置给定命名空间的缓存。 //不常用
  • cache-ref – 从其他命名空间引用缓存配置。 //不常用
  • resultMap –用来描述数据库结果集和对象的对应关系。
  • sql – 可以重用的SQL块,也可以被其他语句引用。
  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句
select
属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数类的完全限定名或别名。
resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用resultType或resultMap,但不能同时使用。
resultMap命名引用外部的resultMap
flushCache将其设置为true,不论语句什么时候被调用,都会导致缓存被清空。默认值:false。
useCache将其设置为true,将会导致本条语句的结果被缓存。默认值:true。
timeout这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)。
fetchSize这是暗示驱动程序每次批量返回的结果行数。
statementTypeSTATEMENT,PREPARED或CALLABLE的一种。让MyBatis选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED。
resultSetTypeFORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE中的一种。默认是不设置(驱动自行处理)

用来定义查询语句。一个简单的例子:

<resultMap type="domain.Person " id=" Person ">
	<result property=“personId" column=“person_id" />
	<result property=“personName" column=“person_name"  />
</resultMap>

<select id="selectPerson" parameterType="int"resultMap="Person">
	SELECT * FROM PERSON WHERE ID = #{id}
</select>

通过id来执行此语句
session.selectOne(" selectPerson ", “1”);
parameterType指明参数类型为int,resultType指明返回值类型为hashmap(这是java类型HashMap的别名)
用#{}来表示参数,括号中是参数的名字。当有多个参数时,可以将参数类型设为map,key是参数名,value是参数值。

insert、update、delete
属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数类的完全限定名或别名。
flushCache将其设置为true,不论语句什么时候被调用,都会导致缓存被清空。默认值:false。
timeout这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)。
statementTypeSTATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis使用选择使用Statement,PreparedStatement或CallableStatement。默认值:PREPARED。
useGeneratedKeys(仅对insert有用)这会告诉MyBatis使用JDBC的getGeneratedKeys方法来取出由数据(比如:像MySQL和SQL Server这样的数据库管理系统的自动递增字段)内部生成的主键。默认值:false。
keyProperty(仅对insert有用)标记一个属性,MyBatis会通过getGeneratedKeys或者通过insert语句的selectKey子元素设置它的值。默认:不设置。

语句示例:

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

<update id="updateAuthor" parameterType="domain.blog.Author">
	update Author set
	username = #{username},
	password = #{password},
	email = #{email}
 	where id = #{id}
</update>

<delete id="deleteAuthor" parameterType="int">
	delete from Author where id = #{id}
</delete>
  • 自动生成主键的insert(数据库自动生成,MySQL、SQL Server)

    <insert id="insertAuthor" parameterType="domain.blog.Author" useGeneratedKeys= "true" keyProperty= "id" >
    	insert into Author (username,password,email,bio)
    	values (#{username},#{password},#{email},#{bio})
    </insert>
    
  • 使用selectKey生成主键的insert(程序生成或数据库序列,Oracle)

    <insert id="insertAuthor" parameterType="domain.blog.Author">
        <selectKey resultType="_int" keyProperty="id" order="BEFORE" >
      		select SEQ_AUTHOR.Nextval from DUAL
         </selectKey>
    	insert into Author (id,username,password,email,bio)
    	values (#{id},#{username},#{password},#{email},#{bio})
    </insert>
    
  • selectKey元素将会首先运行,Author的id会被设置,然后插入语句

Foreach

注:foreach一般用于批量操作,如批量删除、批量添加等

<delete id="deleteBatch"> 
    delete from user where id in
  <foreach collection="array" item="id" index="index" open="(" close=")"separator=","> 
      #{id}
  </foreach>
</delete>
  • collection :collection属性的值有三个分别是list、array、map三种,

    ​ 分别对应的参数类型为:List、数组、map集合,

    ​ 我在上面传的参数为数组,所以值为array。

  • item : 表示在迭代过程中每一个元素的别名

  • index :表示在迭代过程中每次迭代到的位置(下标)

  • open :前缀

  • close :后缀

  • separator :分隔符,表示迭代时每个元素之间以什么分隔

-- 完整输出的sql语句应该是
delete from user where id in (id1,id2,id3)
Choose

if是与(and)的关系,而choose是或(or)的关系。

<select id="getStudentListChooseEntity" parameterType="StudentEntity" resultMap="studentResultMap">     
    SELECT * from STUDENT_TBL ST      
    <where>     
        <choose>     
            <when test="studentName!=null and studentName!='' ">     
                    ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName}),'%')      
            </when>     
            <when test="studentSex!= null and studentSex!= '' ">     
                    AND ST.STUDENT_SEX = #{studentSex}      
            </when><otherwise>     
                      
            </otherwise>     
        </choose>     
    </where>     
</select>     

choose是当一个条件满足后剩余的条件都不看了

if

if是当条件满足后添加语句,然后看下一个if判断是否满足

<update id="updateBoard" >
        update t_board
        <set>
            <if test="valname !=null and valname!=''">
                valname =#{valname}
            </if>
        </set>
        <where>
            valid = #{valid}
        </where>
    </update>

mybatis xml文件中用 if 标签判断字符串是否相等

一、方法一:

<if test="delFlag == '2'.toString()">
	a.del_flag = #{delFlag}
</if>
<!--注意:是"内扩'.toString()-->

二、方法二:

<if test=' delFlag == "2" '>
	a.del_flag = #{delFlag}
</if>
<!--注意:是'内扩",来判断字符串-->

注意以下方法不可使用

<if test=" delFlag == '2' ">
	a.del_flag = #{delFlag}
</if>
sql

这个元素可以被用来定义可重用的SQL代码段,可以包含在其他语句中。比如:

<sql id="userColumns"> id,username,password </sql>
<!--这个SQL片段可以被包含在其他语句中,例如:-->
<select id="selectUsers" parameterType="int" resultType="hashmap">
select <include refid="userColumns"/>
from some_table
where id = #{id}
</select>

6.多参数传值

Map

Key和#{…}对应即可

Map<String,Object> map=new HashMap<String,Object>();
map.put(“name", "lisi");
map.put(“pwd", “123");
int count=mapper.insertUser(map);
<insert id="insertUser2" parameterType="java.util.Map">
insert into t_user (t_username,t_password) values (#{name},#{pwd});
</insert>
对象

属性和#{…}对应即可

public boolean UpmsgBymsg(Msg msg)
<update id="UpmsgBymsg" parameterType="msg" >
    UPDATE t_msg set content =#{content},time = #{time} where id =#{id}
</update>

当属性也是类的话,需要属性的内容时

#{属性名.属性}

public class News implements Serializable {
    private int newsid;
    private String tittle;
    private String content;
    private String pic;
    private String creator;
    private String creatTime;
    private User user;
    private Board board;
}

public class Board implements Serializable {
    int valid;
    String valname;
}

即使用News中board属性的valname时:

#{board.valname}

注解

使用注解和#{…}对应即可

List<Board> getValList(@Param("tittle") String tittle,@Param("pageNum") int pageNum,@Param("pageSize") int pageSize);
<select id="getValList" resultType="board">
        select * from t_board
        <where>
            <if test="tittle !='' and tittle !=null">
                valname like concat("%",#{tittle},"%")
            </if>
        </where>
        order by valid  desc limit #{pageNum},#{pageSize}
</select>
单一参数传递

单一参数传递时,使用注解配置参数,或者使用_paramete来获取参数,

单一参数传递时,#{_paramete}里边可以写任意的名字都可以获取,但是有时机器会认为获取不到该值

所以获取参数时还是使用#{_paramete}

Msg selectmsgById(int id);
<select id="selectmsgById" resultType="msg" >
        select
        m.id,m.tittle,m.userid,m.content,m.pic,u.username,m.time
        from t_msg m,t_user u
        where m.userid=u.id AND m.id=#{_paramete}
</select>
顺序

任意多个参数,都会被MyBatis重新包装成一个Map传入。
Map的key是param1,param2,或者0,1,值就是参数的值

<!--int count=mapper.insertUser(“zhangsan",“123")-->

<insert id="insertUser3" parameterType="java.util.Map">
insert into t_user (t_username,t_password)
values (#{param1},#{param2})
</insert>
<!--或-->
<insert id="insertUser3" parameterType="java.util.Map">
	insert into t_user (t_username,t_password)values (#{0},#{1})
</insert>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值