百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

二、mybatis基本使用

wxin55 2024-11-24 22:35 13 浏览 0 评论

声明:内容来源于互联网,笔者主要进行了相关整理。

一.mybatis基本概念介绍

1、对象/关系数据库映射(ORM)

ORM全称Object/Relation Mapping:表示对象-关系映射的缩写。

2、mybatis简介

基于ORM的半自动轻量级持久层框架。其特点:基于ORM、半自动、轻量级持久层框架。

官网地址:http://www.mybatis.org/mybatis-3/

3、mybatis优势

核心是sql开发,需要自己优化,sql和java编码分开、功能边界清晰,一个专注业务,一个专注数据。

javaBean-->ybatis框架-->db

mybatis经过:编写sql、预编译、设置参数、执行sql、封装结果。

二、mybatis基本使用

1、快速入门

1)添加mybatis的坐标

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<maven.compiler.encoding>UTF-8</maven.compiler.encoding>

<java.version>1.8</java.version>

<maven.compiler.source>1.8</maven.compiler.source>

<maven.compiler.target>1.8</maven.compiler.target>

</properties>

<dependency>

<groupId>org.mybatis</groupId>

<artifactId>mybatis</artifactId>

<version>3.5.3</version>

</dependency>

<dependency>

<groupId>mysql</groupId>

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

<version>5.1.45</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.10</version>

</dependency>

2)创建user数据库表

create database mybatis character set = utf8;

create table user(

id int(10),username varchar(20),primary key(id)

);

insert into user values (1,'zhangsan');

insert into user values (2,'lisi');

insert into user values (3,null);

3)编写user实体

public class User {

private Integer id;

private String username;

//get、set方法忽略

}

4)编写映射文件UserMapper.xml

<mapper namespace="user">

<!--

namespace:名称空间,与id组成sql的唯一标识

resultType:表明返回值类型

-->

<select id="findAll" resultType="org.example.mybatis.pojo.User">

select * from user

</select>

</mapper>

5)编写sqlMapConfig.xml

<configuration>

<!--environments运行环境-->

<environments default="development">

<environment id="development">

<!--当前事务交由JDBC进行管理-->

<transactionManager type="JDBC"/>

<!--当前使用myBatis提供的连接池-->

<dataSource type="POOLED">

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

<!-- ///表示本地的数据 -->

<property name="url" value="jdbc:mysql:///mybatis"></property>

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

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

</dataSource>

</environment>

</environments>

<mappers>

<mapper resource="UserMapper.xml"/>

</mappers>

</configuration>

6)编写测试类

@Test

public void test1() throws Exception{

InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession sqlSession = sqlSessionFactory.openSession();

List<User> userList = sqlSession.selectList("user.findAll");

for(User user:userList){

System.out.println(user);

}

sqlSession.close();

}

2.增删改操作

1.除了查询操作外,增删改都会默认提交开启一个事务,需要在sql执行完毕进行提交。

2.或者在获取sqlSession时候直接设置为自动提交。sqlSessionFactory.openSession(true);

<!--添加-->

<insert id="saveUser" parameterType="org.example.mybatis.pojo.User">

insert into user values (#{id},#{username})

</insert>

User user = new User();

user.setId(4);

user.setUsername("tom");

sqlSession.insert("user.saveUser",user);

sqlSession.commit();

<!--修改-->

<update id="updateUser" parameterType="org.example.mybatis.pojo.User">

update user set username = #{username} where id = #{id}

</update>

User user = new User();

user.setId(4);

user.setUsername("tom2");

sqlSession.update("user.updateUser",user);

sqlSession.commit();

<!--删除-->

<update id="deleteUser" parameterType="java.lang.Integer">

delete from user where id = #{id}

</update>

sqlSession.delete("user.deleteUser",4);

sqlSession.commit();

3.dao层模式开发

1-传统方式

public interface IUserDao {

List<User> findAll() throws IOException;

}

public class UserDaoImpl implements IUserDao {

@Override

public List<User> findAll() throws IOException {

//1.Resources工具类,配置文件的加载,把配置文件加载成字节流

InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");

//2.解析了配置文件,并创建了sqlSessionFactory工厂

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//3.生产sqlSession,默认开启了一个事务,但是不会对该事务进行自动提交。(增删改的操作时候需要手动提交)

// 也可以在获取sqlSession的传递参数true的方式开启自动提交

SqlSession sqlSession = sqlSessionFactory.openSession();

//4.sqlSession调用方法:查询所有selectList 查询单个selectOne 添加insert 修改update 删除delete

List<User> userList = sqlSession.selectList("user.findAll");

// 释放资源

sqlSession.close();

return userList;

}

}

2-代理方式

代理方式开发,只需要编写Mapper接口即可,由Mybatis框架根据接口文档创建接口的动态代理对象,动态代理对象来实现接口类方法。

编写的规范为:

Mapper.xml文件中的namespace与mapper接口的全限定名相同

Mapper接口方法名和mapper.xml中定义的每个statement的id相同

Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同

Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

<!--代理方式需要和dao全限定名一致-->

<mapper namespace="org.example.mybatis.dao.IUserDao">

<!--普通访问方式没有限制

<mapper namespace="user">-->

<!--

namespace:名称空间,与id组成sql的唯一标识

resultType:表明返回值类型

-->

<!--查询-->

<select id="findAll" resultType="org.example.mybatis.pojo.User">

select * from user

</select>

</mapper>

测试方法:

@Test

public void test6() throws Exception{

InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession sqlSession = sqlSessionFactory.openSession();


IUserDao userDao = sqlSession.getMapper(IUserDao.class);

List<User> userList = userDao.findAll();

for(User user:userList){

System.out.println(user);

}

}

4.mybatis配置文件深入

1-sqlMapperConfig.xml常用配置解析

1)environments标签

作用:数据库环境的配置,支持多环境配置

<!--environments运行环境,default用于指定默认的环境名称-->

<environments default="development">

<!--id用于指定当前环境的名称-->

<environment id="development">

<!--指定事务管理类型,当前事务交由JDBC进行管理-->

<transactionManager type="JDBC"/>

<!--指定当前数据库类型,当前使用myBatis提供的连接池-->

<dataSource type="POOLED">

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

<!-- ///表示本地的数据 -->

<property name="url" value="jdbc:mysql:///mybatis"></property>

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

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

</dataSource>

</environment>

</environments>

其中,事务管理器transactionManager类型有两种:

JDBC:直接使用JDBC的提交和回滚设置,依赖于从数据源得到的连接来管理事务的作用。

MANAGED:几乎不做什么,不提交或回滚连接,依赖于容器来管理事务的整个生命周期。

其中,数据源dataSource类型有是那种:

UNPOOLED:不使用数据库连接池,每次请求时打开和关闭连接。

POOLED:使用数据库连接池,直接与池交互。

JNDI:上下文配置,为实现EJB或应用服务器中容器可以集中或外部配置数据源。

<mappers>

<mapper resource="UserMapper.xml"/>

</mappers>

2)mapper标签

作用:加载映射。加载方式有四种:

相对路径,例如:<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

全限定资源定位符,例如:<mapper url="file:///d:/project/mybatis/org/mybatis/builder/AuthorMapper.xml"/>

映射器接口全限定类名,例如:<mapper class="org.mybatis.builder.AuthorMapper"/>

包内映射器接口实现全部注册为映射器,例如:<package name="org.mybatis.builder"/>

3)properties标签

通常习惯将数据源配置信息单的抽取成一个properties文件,该标签可以加载额外配置的properties文件

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql:///mybatis

jdbc.username=root

jdbc.password=111111

sqlMapperConfig.xml

<!--properties,加载配置文件-->

<properties resource="jdbc.properties"/>

<!--environments运行环境,default用于指定默认的环境名称-->

<environments default="development">

<!--具体信息忽略,详见上文-->

</environments>

4)typeAliases标签

作用:类型别名,是为Java类型设置一个短的名字。

在UserMapper.xml中我们经常使用到User对象的时候,需要使用全限定名称,org.example.mybatis.pojo.User。

比较长,我们可以通过设置别的方式来简化字符。

如,原来的写法为

<!--查询-->

<select id="findAll" resultType="org.example.mybatis.pojo.User">

select * from user

</select>

调整后

sqlMapConfig中设置别名

<!--给实体类的全限定名设置别名-->

<typeAliases>

<!--给单独的实体设置别名

<typeAlias type="org.example.mybatis.pojo.User" alias="user"/>-->

<!--批量设置别名,该表下,所有类的别名为其本身的类名,且不区分大小-->

<package name="org.example.mybatis.pojo"/>

</typeAliases>

UserMapper中使用别名

<select id="findAll" resultType="user">

select * from user

</select>

常用的基本类型,mybatis已经帮助我们设置了别名

比如:string是String的别名,long是Long的,int是Integer的,double是Double的,boolean是Boolean。

2-mapper.xml中常用标签

1)动态sql之<if/>

List<User> findByCondition(User user);

<!--多条件查询-->

<select id="findByCondition" parameterType="user" resultType="user">

select * from user

<!--where标签自动会将sql中第一个and给去除掉-->

<where>

<if test="id!=null">

and id = #{id}

</if>

<if test="username!=null">

and username = #{username}

</if>

</where>

</select>

public void test7() throws Exception{

InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession sqlSession = sqlSessionFactory.openSession();


User user1 = new User();

user1.setUsername("zhangsan");


IUserDao userDao = sqlSession.getMapper(IUserDao.class);

List<User> userList = userDao.findByCondition(user1);

for(User user:userList){

System.out.println(user);

}

}

2)动态sql之<foreach/>

<foreach>标签用于遍历集合,它的属性:

collection:遍历集合的元素,注意编写时不使用#{}

open:语句的开始部分

close:语句的结束部分

item:遍历集合的每个元素,生成变量名

separator:分隔符

List<User> findByIds(int[] ids);

<!--循环查询-->

<select id="findByIds" parameterType="list" resultType="user">

select * from user

<where>

<foreach collection="array" open="id in (" close=")" item="id" separator=",">

#{id}

</foreach>

</where>

</select>

public void test8() throws Exception{

InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession sqlSession = sqlSessionFactory.openSession();


int[] ids = new int[]{1,2};

IUserDao userDao = sqlSession.getMapper(IUserDao.class);

List<User> userList = userDao.findByIds(ids);

for(User user:userList){

System.out.println(user);

}

}

3)公用sql的抽取之<sql>

sql中可以将重复的sql抽取出来,使用的时候通过include的方式引用即可,最终达到sql重用的目的。

<!--公共sql片段的抽取-->

<sql id="selectUser">

select * from user

</sql>

<!--循环查询-->

<select id="findByIds" parameterType="list" resultType="user">

<include refid="selectUser"/>

<where>

<foreach collection="array" open="id in (" close=")" item="id" separator=",">

#{id}

</foreach>

</where>

</select>

相关推荐

ES6中 Promise的使用场景?(es6promise用法例子)

一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...

JavaScript 对 Promise 并发的处理方法

Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...

Promise的九大方法(promise的实例方法)

1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...

360前端一面~面试题解析(360前端开发面试题)

1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...

前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?

Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...

最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式

看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...

前端分享-Promise可以中途取消啦(promise可以取消吗)

传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...

手写 Promise(手写输入法 中文)

前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...

什么是 Promise.allSettled()!新手老手都要会?

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...

前端面试-关于Promise解析与高频面试题示范

Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...

宇宙厂:为什么前端离不开 Promise.withResolvers() ?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...

Promise 新增了一个超实用的 API!

在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...

一次搞懂 Promise 异步处理(promise 异步顺序执行)

PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...

Promise 核心机制详解(promise机制的实现原理)

一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...

javascript——Promise(js实现promise)

1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...

取消回复欢迎 发表评论: