Mybatis框架入门

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: mybatis采用ORM 思想解决了实体和数据库映射的问题。

mybatis采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

ORM:对象关系映射(Object Relational Mapping),以面向对象的思想来操作数据库

  1. 对象就是javabean对象
  2. 关系就是数据表
  3. javabean属性与表字段一一对应

mybatis的两种开发方式

  1. 使用原生接口
  2. Mapper代理实现自定义接口

Mybatis入门程序

1. pom.xml

<dependencies>

       <dependency>

           <groupId>org.mybatis</groupId>

           <artifactId>mybatis</artifactId>

           <version>3.4.5</version>

       </dependency>

       <dependency>

           <groupId>mysql</groupId>

           <artifactId>mysql-connector-java</artifactId>

           <version>8.0.21</version>

       </dependency>

       <dependency>

           <groupId>log4j</groupId>

           <artifactId>log4j</artifactId>

           <version>1.2.17</version>

       </dependency>

       <dependency>

           <groupId>junit</groupId>

           <artifactId>junit</artifactId>

           <version>4.13</version>

           <scope>test</scope>

       </dependency>

       <!--lombok简化实体类编写-->

       <dependency>

           <groupId>org.projectlombok</groupId>

           <artifactId>lombok</artifactId>

           <version>1.18.20</version>

       </dependency>

   </dependencies>

   <build>

       <resources>

           <!-- 表示编译java源码时,包含src/main/java和src/main/resources目录下的xml、properties一起 -->

           <!--如果mapper.xml在src/main/java目录下,就必须做这个配置,不然编译后会丢弃mapper.xml文件-->

           <resource>

               <directory>src/main/java</directory>

               <includes>

                   <include>**/*.xml</include>

                   <include>**/*.properties</include>

               </includes>

           </resource>

           <resource>

               <directory>src/main/resources</directory>

               <includes>

                   <include>**/*.xml</include>

                   <include>**/*.properties</include>

               </includes>

           </resource>

       </resources>

   </build>

2. 创建Account表

createtable t_account(

 id intprimarykeyauto_increment,

 username varchar(11),

 passwordvarchar(11),

 age int

);

3. 创建实体类Account

@Data

@AllArgsConstructor

@NoArgsConstructor

publicclassAccount {

   privatelongid;

   privateStringusername;

   privateStringpassword;

   privateintage;

}

4. 创建IAccountDao接口

接口中每一个方法都代表一个SQL语句,SQL语句写在mapper文件中

publicinterfaceIAccountDao {

   //查询一个用户

   AccountselectAccountById(Integerid);

}

5. 创建SQL映射文件

建议不同表的操作放在不同的mapper文件中

在接口同一目录下,创建与接口同名的文件IAccountDao.xml,来编写SQL语句

<?xmlversion="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace命名空间:推荐使用dao接口的全限定名称-->

<mappernamespace="dao.IAccountDao">

   <!--id是要执行SQL语句的唯一标识,推荐使用dao接口中的方法名称

       resultType:告诉mybatis,将查询到的数据赋值给哪个类的对象,使用实体类的全限定名称

       #{accountId}:占位符,表示从java程序中传来的数据

   -->

   <selectid="selectAccountById"resultType="domain.Account">

       select * from t_account where id=#{accountId}

   </select>

</mapper>

6. 创建主配置文件

这里连接数据库的url的参数的大小写敏感&amp;characterEncoding=utf-8

mybatis.xml包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)

<?xmlversion="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration

       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

       "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

   <!--设置日志-->

   <settings>

       <settingname="logImpl"value="STDOUT_LOGGING"/>

   </settings>

   

   <!--配置mybatis的运行环境。可以配置多个环境,选择其中一个环境-->

   <environmentsdefault="development">

       <environmentid="development">

           <!--事务管理-->

           <transactionManagertype="JDBC"/>

           <!--配置数据源:创建Connection对象-->

           <dataSourcetype="POOLED">

               <propertyname="driver"value="com.mysql.cj.jdbc.Driver"/>

               <propertyname="url"value="jdbc:mysql://localhost:3306/eesy?useUnicode=true&amp;characterEncoding=utf-8"/>

               <propertyname="username"value="ggbond"/>

               <propertyname="password"value="xxxx"/>

           </dataSource>

       </environment>

   </environments>

   <!--指定mapper文件的位置,进而找到SQL语句-->

   <mappers>

       <!--resource属性从类路径target/classes开始-->

       <mapperresource="dao/IAccountDao.xml"></mapper>

   </mappers>

   

</configuration>

7. 测试执行

publicclassMyTest {

   @Test

   publicvoidtestSelectAccountById() throwsIOException {

       //1.定义mybatis主配置文件的位置,从类路径开始的相对路径

       Stringconfig="mybatis.xml";

       //2.使用mybatis框架的工具类Resources来读取主配置文件为流对象

       InputStreamis=Resources.getResourceAsStream(config);

       //3.使用SqlSessionFactoryBuilder创建SqlSessionFactory对象

       SqlSessionFactoryfactory=newSqlSessionFactoryBuilder().build(is);

       //4.获取sqlSession对象

       SqlSessionsqlSession=factory.openSession();

       //5.指定要执行的SQL语句 = namespace + "." + id

       StringsqlId="dao.IAccountDao"+"."+"selectAccountById";

       //6.通过sqlSession的方法,执行SQL语句

       Accountaccount=sqlSession.selectOne(sqlId,2);

       System.out.println(account);

       //7.关闭sqlSession对象

       sqlSession.close();

   }

}

注意

1. 占位符 #{}

如果传给mybatis的是一个对象,那么使用#{属性名}占位符赋值,mybatis通过get方法来获取值

2. 事务

mybatis执行SQL语句默认是手动提交事务模式:在做insert、update、delete后需要手动提交事务

       sqlSession.commit();

mybatis相关对象

1. Resources

作用:读取类路径中的主配置文件为流对象

       //1.定义mybatis主配置文件的位置,从类路径开始的相对路径

       String config="mybatis.xml";

       //2.使用mybatis框架的工具类Resources来读取主配置文件为流对象

       InputStream is = Resources.getResourceAsStream(config);

2. SqlSessionFactoryBuilder

作用:创建SqlSessionFactory对象

       //3.使用SqlSessionFactoryBuilder创建SqlSessionFactory对象

       SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);

3. SqlSessionFactory

SqlSessionFactory是重量级对象:创建此对象需要使用更多的资源和时间。在项目中有一个即可(在工具类中放在静态代码块内)

作用:是SqlSession的工厂,就是创建SqlSession对象。

方法:

  1. openSession():获取一个默认的SqlSession对象, 默认是需要手工提交事务的。
  2. openSession(boolean): boolean参数表示是否自动提交事务。

                  true: 创建一个自动提交事务的SqlSession

                 false:   等同于没有参数的openSession

4. SqlSession

SqlSession中提供所有执行SQL的方法

selectOne:执行sql语句,最多得到一行记录,多余1行是错误。

selectList:执行sql语句,返回多行数据

selectMap:执行sql语句的,得到一个Map结果

insert:执行insert语句

update:执行update语句

delete:执行delete语句

commit:提交事务

rollback:回顾事务

注意SqlSession对象不是线程安全的(每次使用都要先去获取新的对象), 使用的步骤:

①:在方法的内部,执行sql语句之前,先获取SqlSession对象

②:调用SqlSession的方法,执行sql语句

③:关闭SqlSession对象,执行SqlSession.close()

<?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>

   <!--设置日志-->

   <settings>

       <setting name="logImpl" value="STDOUT_LOGGING"/>

   </settings>

   

   <!--配置mybatis的运行环境。可以配置多个环境,选择其中一个环境-->

   <environments default="development">

       <environment id="development">

           <!--事务管理-->

           <transactionManager type="JDBC"/>

           <!--配置数据源:创建Connection对象-->

           <dataSource type="POOLED">

               <property name="driver" value="com.mysql.cj.jdbc.Driver"/>

               <property name="url" value="jdbc:mysql://localhost:3306/eesy?useUnicode=true&amp;characterEncoding=utf-8"/>

               <property name="username" value="ggbond"/>

               <property name="password" value="xxxx"/>

           </dataSource>

       </environment>

   </environments>

   <!--指定mapper文件的位置,进而找到SQL语句-->

   <mappers>

       <!--resource属性从类路径target/classes开始-->

       <mapper resource="dao/IAccountDao.xml"></mapper>

   </mappers>


   

</configuration>

使用模板和工具类简化开发

模板

mybatis-mapper

<?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接口的全限定名称">

   <!--使用insert、update、delete、select标签写SQL -->

   

</mapper>

mybatis-config

<?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>

   <!--设置日志-->

   <settings>

       <setting name="logImpl" value="STDOUT_LOGGING"/>

   </settings>

   

   <!--配置mybatis的运行环境。可以配置多个环境,选择其中一个环境-->

   <environments default="development">

       <environment id="development">

           <!--事务管理-->

           <transactionManager type="JDBC"/>

           <!--配置数据源:创建Connection对象-->

           <dataSource type="POOLED">

               <property name="driver" value="com.mysql.cj.jdbc.Driver"/>

               <property name="url" value="jdbc:mysql://localhost:3306/eesy?useUnicode=true&amp;characterEncoding=utf-8"/>

               <property name="username" value="ggbond"/>

               <property name="password" value="xxxx"/>

           </dataSource>

       </environment>

   </environments>

   <!--指定mapper文件的位置,进而找到SQL语句-->

   <mappers>

       <!--resource属性从类路径target/classes开始-->

       <mapper resource="dao/IAccountDao.xml"></mapper>

   </mappers>


   

</configuration>

工具类

/**

* 工具类,创建SqlSession对象

*/

public class MyBatisUtil {

   private static SqlSessionFactory factory =null;

   static{

       //1.定义mybatis主配置文件的位置,文件的类路径

       String config="mybatis.xml";

       try {

           //2.使用mybatis框架的工具类Resources来读取主配置文件为流对象

           InputStream is = Resources.getResourceAsStream(config);

           //3.使用SqlSessionFactoryBuilder创建SqlSessionFactory对象

           factory = new SqlSessionFactoryBuilder().build(is);

       } catch (IOException e) {

           e.printStackTrace();

       }

   }

   /**

    * 获取SqlSession对象的方法

    * @return

    */

   public static SqlSession getSqlSession(){

       SqlSession sqlSession=null;

       if (factory!=null){

           sqlSession=factory.openSession();

       }

       return sqlSession;

   }

}

使用:

   @Test

   public void testUtil() throws IOException {

       //1.获取SqlSession对象

       SqlSession sqlSession = MyBatisUtil.getSqlSession();

       //2.指定要执行的SQL语句

       String sqlId="dao.IAccountDao"+"."+"insertAccount";

       //3.通过sqlSession的方法,执行SQL语句

       Account account = new Account(7,"琪琪","qiqi",20);

       int i = sqlSession.insert(sqlId,account);

       System.out.println(i);

       //4.提交事务

       sqlSession.commit();

       //5.关闭sqlSession对象

       sqlSession.close();

   }

Mybatis的mapper代理

使用传统开发方式

需要创建接口实现类,实现接口方法

public class AccountDaoImpl implements IAccountDao {

   @Override

   public Account selectAccountById(Integer id) {

       //1.获取SqlSession对象

       SqlSession sqlSession = MyBatisUtil.getSqlSession();

       //2.指定要执行的SQL语句

       String sqlId="dao.IAccountDao"+"."+"selectAccountById";

       //3.通过sqlSession的方法,执行SQL语句

       Account account = sqlSession.selectOne(sqlId, id);

       //4.关闭sqlSession对象

       sqlSession.close();


       return account;

   }


   @Override

   public int insertAccount(Account account) {

       //1.获取SqlSession对象

       SqlSession sqlSession = MyBatisUtil.getSqlSession();

       //2.指定要执行的SQL语句

       String sqlId="dao.IAccountDao"+"."+"insertAccount";

       //3.通过sqlSession的方法,执行SQL语句

       int i = sqlSession.insert(sqlId,account);

       System.out.println(i);

       //4.提交事务

       sqlSession.commit();

       //5.关闭sqlSession对象

       sqlSession.close();

       return i;

   }


   @Override

   public List<Account> selectAccounts() {

       //1.获取SqlSession对象

       SqlSession sqlSession = MyBatisUtil.getSqlSession();

       //2.指定要执行的SQL语句

       String sqlId="dao.IAccountDao"+"."+"selectAccounts";

       //3.通过sqlSession的方法,执行SQL语句

       List<Account> accounts = sqlSession.selectList(sqlId);

       //4.关闭sqlSession对象

       sqlSession.close();

       return accounts;

   }

}

传统开发方式的分析

在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件mapper 中的相应 SQL 语句,对 DB 进行操作。这种对 Dao 的实现方式称为Mapper 的动态代理方式

Mapper 代理实现数据库操作(重点)

Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的

  1. 需要dao接口和对应的mapper文件,不需要接口的实现类mapper文件的要求:
  1. mapper文件中的namespace是dao接口的全限定名称
  2. mapper文件中 标签的id是dao接口方法名称
  1. 以上操作绑定了mapper文件是接口的实现类
  2. 只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao 接口类的 class 值。

       //1.获取SqlSession对象

       SqlSession sqlSession = MyBatisUtil.getSqlSession();

       //2.获取接口的代理对象(将接口和配置文件绑定)

       IAccountDao dao = sqlSession.getMapper(IAccountDao.class);

       

       Account account = dao.selectAccountById(1);

       System.out.println(account);

       sqlSession.close();

映射文件

mapper.xml

1. SQL语句中参数的传递

通过java代码将参数传入到mapper文件中的sql语句。 参数主要是指dao接口方法的形参

parameterType(可选)

  1. parameterType是标签属性,表示接口中方法参数的类型, 属性值是类型的全限定名或别名
  2. 这个属性是可选的,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置(unset)。
  3. 接口中方法的参数从 java 代码传入到 mapper 文件的 sql 语句。

第一个用法: java类型的全限定类型名称   parameterType="java.lang.Integer"

第二个用法: mybatis定义的java类型的别名  parameterType="int"


parameterType:mybatis通过反射机制可以获取 dao接口方法参数的类型, 可以不写


<select id="selectById"  parameterType="integer"

                resultType="com.bjpowernode.domain.Student">

  select id,name,email,age from student where id=#{studentId}

</select>

dao接口方法有一个参数

//dao接口的方法形参是一个简单类型的

//简单类型: java基本数据类型和String

Student selectByEmail(String email);

<!--

  dao接口的方法形参是一个简单类型的

  mapper文件,获取这个参数值,使用#{任意字符}

-->

<select id="selectByEmail" resultType="com.bjpowernode.domain.Student">

   select id,name,email,age from student where email=#{studentEmail}

</select>

dao接口方法有多个参数

@Param: 命名参数,在方法的形参前面使用的,定义参数名。这个名称可以用在mapper文件中。

在dao接口,方法的定义:

/*

 多个简单类型的参数

 使用@Param命名参数, 注解是mybatis提供的

 位置:在形参定义的前面

 属性:value 自定义的参数名称

*/

List<Student> selectByNameOrAge(@Param("myname") String name,

                               @Param("myage") Integer age);

mapper文件:

<!--

  多个简单类型的参数.

  当使用了@Param命名后,例如@Param("myname").

  在mapper中,使用#{命名的参数}, 例如 #{myname}

-->

<select id="selectByNameOrAge" resultType="com.bjpowernode.domain.Student">

   select id,name,email,age from student where name=#{myname} or age=#{myage}

</select>

dao接口方法参数是一个对象

方法的形参是一个java对象。这个java对象表示多个参数。使用对象的属性作为参数使用

java对象

public class Student {

   private Integer id;

   private String name;

   private String email;

   private Integer age;

   //set|get方法

}


public class QueryParam {

   private Object p1;

   private Object p2;

   //set|get方法

}

dao接口中的方法定义

/*

* 一个java对象作为参数( 对象由属性, 每个属性有set,get方法)

*/

List<Student> selectByObject(Student student);


List<Student> selectByQueryParam(QueryParam param);

mapper文件

<!--

  一个java对象作为方法的参数,使用对象的属性作为参数值使用

  简单的语法: #{属性名} , mybatis调用此属性的getXXX()方法获取属性值

-->

<select id="selectByObject" resultType="com.bjpowernode.domain.Student">

   select id,name,email,age from student where name=#{name} or age=#{age}

</select>


<select id="selectByQueryParam" resultType="com.bjpowernode.domain.Student">

    select id,name,email,age from student where name=#{p1} or age=#{p2}

</select>


<!--负责的语法格式: #{属性名,javaType=java类型的全限定名称,jdbcType=mybatis中定义列的数据类型}

javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。常用格式 #{ property }-->

<select id="selectByObject" resultType="com.bjpowernode.domain.Student">

       select id,name,email,age from student where

       name=#{name,javaType=java.lang.String,jdbcType=VARCHAR}

       or

       age=#{age,javaType=java.lang.Integer,jdbcType=INTEGER}

</select>

2. #和$的区别

# 占位符

语法: #{字符}

mybatis处理#{} 使用jdbc对象是 PrepareStatment对象

<select id="selectById"  parameterType="integer"

            resultType="com.bjpowernode.domain.Student">

   select id,name,email,age from student where id=#{studentId}

</select>


mybatis会创建PrepareStatement对象,执行sql语句

String sql=" select id,name,email,age from student where id=?";

PrepareStatement pst = conn.prepareStatement(sql);

pst.setInt(1,1001);  //传递参数

ResultSet rs  = pst.executeQuery(); //执行sql语句

#{}特点:

1)使用的PrepareStatement对象,执行sql语句,效率高。

2)使用的PrepareStatement对象,能避免sql注入, sql语句执行更安全。

3) #{} 常常作为 列值使用的, 位于等号的右侧,  #{}位置的值和数据类型有关的。

$ 占位符

语法 :  ${字符}

mybatis执行${}占位符的sql语句,使用Statement对象

<select id="selectById"  parameterType="integer"

            resultType="com.bjpowernode.domain.Student">

   select id,name,email,age from student where id=${studentId}

</select>


${} 表示字符串连接, 把sql语句的其他内容和 ${}内容使用 字符串(+) 连接的方式连在一起

String sql="select id,name,email,age from student where id=" + "1001";


mybatis创建Statement对象, 执行sql语句。

Statement stmt  = conn.createStatement(sql);

ResultSet rs  = stmt.executeQuery();

${} 的特点

1)使用Statement对象,执行sql语句,效率低

2)${}占位符的值,使用的字符串连接方式, 有sql注入的风险。 有代码安全的问题

  1. ${} 数据是原样使用的(传什么就用什么), 不会区分数据类型。

4)${} 常用作 表名或者列名, 在能保证数据安全的情况下使用 ${}

3. 输出结果的封装

输出结果的封装:mybatis执行SQL语句,将结果集转为java对象

1. resultType

  1. 在执行select时使用, 作为<select>标签的属性出现的。
  2. 表示查询结果的类型,mysql执行sql语句,得到java对象的类型。值有两种写法:
  1. java类的全限定名称
  2. 使用类的别名

对象类型

resultType属性现在使用java类型的全限定名称,表示mybatis执行sql,把ResultSet中的数据转为Student类型的对象

# dao接口方法

Student selectById(Integer id);

# mapper文件

<select id="selectById" resultType="com.bjpowernode.domain.Student">

   select id,name,email,age from student where id=#{studentId}

</select>

mybatis会执行以下操作:

  1. 调用com.bjpowernode.domain.Student的无参数构造方法,创建对象

Student student = new Student(); //使用反射创建对象

  1. 同名的列赋值给同名的属性

student.setId( rs.getInt("id"));

student.setName(rs.getString("name"));

  1. 得到java对象, 如果dao接口返回值是List集合, mybatis把student对象放入到List集合

简单类型

基本类型和String

# dao接口方法

long countStudent();

# mapper文件,执行sql语句,得到是一个值(一行一列)

<select id="countStudent" resultType="java.lang.Long">

   select count(*) from student

</select>

Map

mybatis执行sql,把ResultSet转为map:列名为key,列值为value

注意:如果sql执行得到一行,是可以转为map的;但多于一行会报错,无法转换为map

//查询结果返回是一个Map

Map<Object,Object> selectMap(@Param("stuid") Integer id);

<select id="selectMap" resultType="java.util.HashMap">

   select id,name,email from student where id != #{stuid}

</select>

2. resultMap(推荐)

resultMap:结果映射。可以自定义 列名 和 java对象属性 的对应关系。常用在列名和属性名不同的情况

用法:

1.先定义resultMap标签,指定列名和属性名称对应关系

2.在select标签使用resultMap属性,指定上面定义的resultMap的id值

<!--使用resultMap定义列和属性的关系-->

<!--定义resultMap

   id:给resultMap的映射关系起个名称,唯一值

   type:java类型的全限定名称

-->

<resultMap id="customMap" type="com.bjpowernode.vo.CustomObject">


   <!--定义列名和属性名的对应-->

   <!--主键类型使用id标签-->

   <id column="id" property="cid" />

   <!--非主键类型使用result标签-->

   <result column="name" property="cname" />

   <!--列名和属性名相同不用定义-->

   <result column="email" property="email" />

   <result column="age" property="age" />

</resultMap>


<!--使用resultMap属性,指定映射关系的id

   resultMap和resultType 不能同时使用, 二选一。

-->

<select id="selectById2" resultMap="customMap">

 select id,name,email,age from student where id=#{stuid}

</select>

3. 列名和java对象属性名称不一样的解决方式

  1. 使用resultMap: 自定义列名和属性名称对应关系
  2. 使用resultType:  使用列别名(as),让别名和java对象属性名称一样

4. 模糊查询 like

类似于一个基本参数吧

dao接口方法

List<Student> selectLikeOne(@Param("name") String name);

mapper

<select id="selectLikeOne" resultType="com.bjpowernode.domain.Student">

   select * from student where name like #{name}

</select>

执行like

@Test

public void testLikeOne(){

   SqlSession sqlSession = MyBatisUtil.getSqlSession();

   StudentDao dao  = sqlSession.getMapper(StudentDao.class);


   String name="%李%";

   List<Student> students = dao.selectLikeOne(name);


   sqlSession.close();


   students.forEach( stu-> System.out.println(stu));

}

5. 自定义类的别名

mybatis提供的对java类的全限定名称进行自定义别名

自定义别名的步骤:

1)在mybatis主配置文件,使用 typeAliases标签声明别名

<typeAliases>

   <!--第一种语法格式

       type:java类型的全限定名称(自定义类型)

       alias:自定义别名

   -->

   <typeAlias type="com.bjpowernode.domain.Student" alias="stu" />


</typeAliases>

2)在mapper文件中, resultType="别名"

resultType="别名"

<select id="selectById"  parameterType="integer" resultType="stu">

   select id,name,email,age from student where id=#{studentId}

</select>

全局配置文件

config.xml

mybatis配置文件两大类:

  1. mybatis主配置文件,提供mybatis全局设置的。包含的内容 日志, 数据源,mapper文件位置
  2. mapper文件: 写sql语句的。 一个表一个mapper文件

1. settings 设置标签

settings是mybatis的全局设置,影响整个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="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>

2. typeAliases 别名标签

设置别名

<typeAliases>

       <!--第一种语法格式

           type:java类型的全限定名称(自定义类型)

           alias:自定义别名


           优点: 别名可以自定义

           缺点: 每个类型必须单独定义

       -->

       <typeAlias type="com.bjpowernode.domain.Student" alias="stu" />

       <typeAlias type="com.bjpowernode.vo.QueryParam" alias="qp" />


       <!--第二种方式

           name:包名, mybatis会把这个包中所有类名作为别名(不用区分大小写)

           优点:使用方便,一次给多个类定义别名

           缺点: 别名不能自定义,必须是类名。

       -->

       <package name="com.bjpowernode.domain" />

       <package name="com.bjpowernode.vo" />


   </typeAliases>

3. environments 环境标签

environments: 环境标签, 在他里面可以配置多个environment

      属性: default ,必须是某个environment的id属性值。 表示mybatis默认连接的数据库

environment: 表示一个数据库的连接信息。

      属性: id 自定义的环境的标识。 唯一值。

transactionManager:事务管理器

      属性:  type 表示事务管理器的类型。

      属性值:1)JDBC: 使用Connection对象, 由mybatis自己完成事务的处理。

            2) MANAGED: 管理,表示把事务的处理交给容器实现(由其他软件完成事务的提交,回滚)

dataSource: 数据源,创建的Connection对象,连接数据库。

      属性:  type 数据源的类型

      属性值:1) POOLED, mybatis会在内存中创建PooledDataSource类,管理多个Connection连接对象,使                           用的连接池

            2) UNPOOLED ,不使用连接池, mybatis创建一个UnPooledDataSource这个类, 每次执行sql                           语句先创建Connection对象,再执行sql语句,最后关闭Connection

            3) JNDI : java的命名和目录服务。


<environments default="online">

   

       <environment id="development">

           <transactionManager type="JDBC"/>

           <!--配置数据源: 创建Connection对象。-->

           <dataSource type="POOLED">

               <!--driver:驱动的内容-->

               <property name="driver" value="com.mysql.jdbc.Driver"/>

               <!--连接数据库的url-->

               <property name="url"

                         value="jdbc:mysql://localhost:3306/springdb"/>

               <!--用户名-->

               <property name="username" value="root"/>

               <!--密码-->

               <property name="password" value="123"/>

           </dataSource>

       </environment>

   

       <!-- 项目上线后使用的数据库 -->

       <environment id="online">

           <transactionManager type="JDBC"/>

           <!--配置数据源: 创建Connection对象。-->

           <dataSource type="POOLED">

               <!--driver:驱动的内容-->

               <property name="driver" value="com.mysql.jdbc.Driver"/>

               <!--连接数据库的url-->

               <property name="url"

                         value="jdbc:mysql://localhost:3306/springdb"/>

               <!--用户名-->

               <property name="username" value="admin"/>

               <!--密码-->

               <property name="password" value="123456"/>

           </dataSource>

       </environment>

   

   </environments>

4. 使用数据库属性配置文件(*)

需要把数据库的配置信息放到一个单独文件中, 独立管理。 这个文件扩展名是 properties. 在这个文件中,使用自定义的key=value的格式表示数据

使用步骤:

1.在resources目录中,创建xxxx.properties

2.在文件中,使用 key=value的格式定义数据。

  例如 jdbc.url=jdbc:mysq://localhost:3306/springdb

3.在mybatis主配置文件, 使用properties标签引用外部的属性配置文件

4.在使用值的位置, 使用${key}获取key对应的value(等号右侧的值)

例子:

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&amp;characterEncoding=utf-8

jdbc.username=root

jdbc.password=123

mybatis主配置文件

<!--使用外部属性配置文件

   resource:指定类路径下的某个属性配置文件

-->

<properties resource="jdbc.properties" />


<environments default="development">

       <environment id="development">

           <transactionManager type="JDBC"/>

           <!--配置数据源: 创建Connection对象。-->

           <dataSource type="POOLED">

               <!--driver:驱动的内容-->

               <property name="driver" value="${jdbc.driver}"/>

               <!--连接数据库的url-->

               <property name="url" value="${jdbc.url}"/>

               <!--用户名-->

               <property name="username" value="${jdbc.username}"/>

               <!--密码-->

               <property name="password" value="${jdbc.password}"/>

           </dataSource>

        </environment>

</environments>

5. mapper 标签(*)

使用mapper指定其他mapper文件的位置, 有两个常用的方式:

<mappers>

   <!--第一种方式, resources="mapper文件的路径"

       优点:文件清晰。 加载的文件是明确的。

             文件的位置比较灵活。

       缺点:文件比较多, 代码量会比较大, 管理难度大

   -->

   <mapper resource="com/bjpowernode/dao/StudentDao.xml"/>

   <mapper resource="com/bjpowernode/dao/OrderDao.xml"/>

   <!--

      第二种方式,使用<package>

      name:包名, mapper文件所在的包名。

      特点: 把这个包中的所有mapper文件,一次加载。


      使用要求:

       1. mapper文件和dao接口在同一目录

       2. mapper文件和dao接口名称完全一样。

   -->

   <package name="com.bjpowernode.dao" />

   <package name="com.bjpowernode.dao1" />

</mappers>

动态SQL

动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接SQL 语句。这里的条件判断使用的表达式为 OGNL 表达式。常用的动态 SQL标签有<if><where><choose/><foreach>等。MyBatis 的动态 SQL 语句,与 JSTL 中的语句非常相似。

动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的SQL 语句。此时,可使用动态 SQL 来解决这样的问题。动态SQL的dao接口方法参数是对象

比较符号转换为实体符

在 mapper 的动态 SQL 中若出现大于号(>)、小于号(<)、大于等于号(>=),小于等于号(<=)等符号,最好将其转换为实体符号。否则,XML 可能会出现解析出错问题。

&:&amp;

1. if 标签

语法:

  1. <if test="条件">sql语句</if>
  2. test使用对象的属性值作为条件

<!--在mapper文件中-->

<select id="selectStudent" resultType="com.bjpwoernode.domain.Student">

     select *from student

     <if test="条件">

         sql语句

     </if>

     <if test="条件">

         sql语句

     </if>

</select>

示例:

List<Student> selectIf(Student student);

<select id="selectIf" resultType="com.bjpowernode.domain.Student">

   select * from student

   where id=-1

   <if test="name !=null and name!=''">

      or  name = #{name}

   </if>

   

   <if test="age >0">

       or age &lt; #{age}

   </if>

</select>

2. where 标签

<if/>标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1的子句。因为,若 where 后的所有<if/>条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。所以,在where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。

使用<where/>标签,在有查询条件为true时,可以自动添加上 where 子句;没有查询条件为true时,不会添加 where 子句。需要注意的是,第一个<if/>标签中的SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and去掉。但其它<if/>中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错

语法:

<where>

   <if test="条件1">sql语句1</if>

   <if test="条件2">sql语句2</if>

</where>

示例:

//where

List<Student> selectWhere(Student student);

<!--where-->

<select id="selectWhere" resultType="com.bjpowernode.domain.Student">

   select * from student

   <where>

       <if test="name !=null and name!=''">

           or  name = #{name}

       </if>


       <if test="age >0">

           or age &lt; #{age}

       </if>

   </where>


</select>

3. foreach 循环标签

使用foreach可以循环数组,list集合, 一般使用在in语句

标签属性:

  1. collection:表示循环的对象是数组,还是list集合。
    如果dao接口方法的形参是数组,collection="array"
    如果dao接口形参是List,collection="list"
  2. open:循环开始时的字符。  sql.append("(");
  3. close:循环结束时字符。  sql.append(")");
  4. item:集合成员, 自定义的变量。  Integer item  = idlist.get(i);
  5. separator:集合成员之间的分隔符。  sql.append(",");
  6. #{item 的值}:获取集合成员的值。

语法:

< foreach collection="集合类型" open="开始字符" close="结束字符" item="集合成员" separator="集合成员之间的分隔符">

             #{item 的值}

</ foreach>

循环简单类型的List

List<Student> selectForeachOne(List<Integer> idlist);


<!--foreach第一种方式, 循环简单类型的List-->

<select id="selectForeachOne" resultType="com.bjpowernode.domain.Student">

     select * from student

       <if test="list !=null and list.size>0">

           where id in

           <foreach collection="list" open="(" close=")" separator="," item="myid">

                 #{myid}

           </foreach>

       </if>

</select>

@Test

public void testSelectForeachOne(){

       //1.获取SqlSession

       SqlSession session = MyBatisUtil.getSqlSession();

       //2.获取dao的代理

       StudentDao dao = session.getMapper(StudentDao.class);


       List<Integer> idlist = new ArrayList<>();

       idlist.add(1001);

       idlist.add(1002);

       idlist.add(1003);


       List<Student> students  = dao.selectForeachOne(idlist);


       students.forEach( stu-> System.out.println("stu=="+stu));

       //3.关闭SqlSession对象

       session.close();

   }

循环对象类型的list

//foreach-2

List<Student> selectForeachTwo(List<Student> studentList);


<!--foreach第二种方式, 循环的List<Student>-->

<select id="selectForeachTwo" resultType="com.bjpowernode.domain.Student">

       select * from student

       <if test="list != null and list.size>0">

           where id in

           <foreach collection="list" open="(" close=")" separator="," item="stu">

                 #{stu.id}

           </foreach>

       </if>

</select>

           

@Test

public void testSelectForeachTwo(){

       //1.获取SqlSession

       SqlSession session = MyBatisUtil.getSqlSession();

       //2.获取dao的代理

       StudentDao dao = session.getMapper(StudentDao.class);



       List<Student> list  = new ArrayList<>();

       Student s1 = new Student();

       s1.setId(1001);


       Student s2 = new Student();

       s2.setId(1002);


       list.add(s1);

       list.add(s2);



       List<Student> students  = dao.selectForeachTwo(list);


       students.forEach( stu-> System.out.println("stu=="+stu));

       //3.关闭SqlSession对象

       session.close();

   }

4. 代码片段

<sql/>标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断,需要使用<include/>子标签。该<sql/>标签可以定义 SQL 语句中的任何部分,所以<include/>子标签可以放在动态 SQL 的任何位置。

<!--定义代码片段-->

<sql id="selectStudent">

   select * from student

</sql>


<sql id="studentFieldList">

   id,name,email

</sql>


<select id="selectIf" resultType="com.bjpowernode.domain.Student">


       <include refid="selectStudent" />


       where id=-1

       <if test="name !=null and name!=''">

          or  name = #{name}

       </if>


       <if test="age >0">

           or age &lt; #{age}

       </if>

   </select>


   <select id="selectWhere" resultType="com.bjpowernode.domain.Student">

       select <include refid="studentFieldList"/> from student

       <where>

           <if test="name !=null and name!=''">

               or  name = #{name}

           </if>


           <if test="age >0">

               or age &lt; #{age}

           </if>

       </where>


   </select>

分页助手PageHelper

PageHelper做数据分页。 在你的select语句后面加入分页的 sql 内容, 如果你使用的mysql数据库, 它就是在select * from student 后面加入 limit 语句。

使用步骤:

1.加入依赖pagehelper依赖

<dependency>

<groupId>com.github.pagehelper</groupId>

<artifactId>pagehelper</artifactId>

<version>5.1.10</version>

</dependency>

2.在mybatis主配置文件, 加入plugin声明

在<environments> 之前加入

<plugins>

  <plugin interceptor ="com.github.pagehelper.PageInterceptor" />

</plugins>    

3.在select语句之前,调用PageHelper.startPage(页码,每页大小)。紧跟在这个方法后的第一个 MyBatis 查询方法会被进行分页

@Test

public void testSelect() throws IOException {

//获取第 1 页,3 条内容(页码从1开始)

PageHelper.startPage(1,3);

List<Student> studentList = studentDao.selectStudents();

studentList.forEach( stu -> System.out.println(stu));

}

对比:

  1. 没有使用PageHelper

select * from student order by id

  1. 使用PageHelper

SELECT count(0) FROM student


select * from student order by id LIMIT ?

Mybatis缓存机制


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2天前
|
Java 数据库连接 测试技术
MyBatis-Plus入门
MyBatis-Plus入门
|
4天前
|
SQL 缓存 Java
持久层框架MyBatis
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的操作。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
28 1
|
3天前
|
SQL 缓存 Java
【框架】MyBatis 框架重点解析
【框架】MyBatis 框架重点解析
7 0
|
3天前
|
SQL Java 数据库连接
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL(下)
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态
5 0
|
3天前
|
SQL Java 数据库连接
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL(上)
【JavaEE】懒人的福音-MyBatis框架—复杂的操作-动态SQL
4 0
|
3天前
|
SQL Java 数据库连接
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作(下)
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作
7 0
|
3天前
|
SQL 前端开发 Java
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作(上)
【JavaEE】懒人的福音-MyBatis框架—[单表]增删改查等常规操作
8 0
|
3天前
|
Java 数据库连接 数据库
【JavaEE】懒人的福音-MyBatis框架—介绍、搭建环境以及初步感受
【JavaEE】懒人的福音-MyBatis框架—介绍、搭建环境以及初步感受
7 0
|
4天前
|
XML Java 数据库连接
Java一分钟之MyBatis:持久层框架基础
【5月更文挑战第15天】MyBatis是Java的轻量级持久层框架,它分离SQL和Java代码,提供灵活的数据库操作。常见问题包括:XML配置文件未加载、忘记关闭SqlSession、接口方法与XML映射不一致、占位符使用错误、未配置ResultMap和事务管理不当。解决这些问题的关键在于正确配置映射文件、管理SqlSession、避免SQL注入、定义ResultMap以及确保事务边界。遵循最佳实践可优化MyBatis使用体验。
12 2
Java一分钟之MyBatis:持久层框架基础
|
4天前
|
SQL 缓存 Java