MyBatis_01_刘锋的博客
一、框架的概述
文章目录
- 一、框架的概述
- mvc架构模式
- 三层架构
- 三层架构请求处理的流程
- 三层架构模式和框架
- jdbc访问数据库的优缺点
- MyBatis
- 二、MyBatis框架的快速入门
- 搭建MyBatis开发环境
- jdbc.properties
- mybatis.xml
- 提交事务:
- 重要对象
- Resources
- SqlSessionFactoryBuilder
- SqlSessionFactory(重要对象)
- sqlSession对象
- 使用工具类和模板
- 工具类
- 模板
- java.sql.SQLException: Unknown initial character set index ‘255‘ received from server.
- 三、dao代理
- 使用条件:
- 实现方式:
- 参数类型
- 形参起别名
- resultMap结果映射
- 下划线到驼峰的映射
- 嵌套查询
- 四、动态sql
- if
- 语法:
- mapper
- dao接口
- 测试:
- where
- 语法
- mapper
- dao接口
- test
- foreach
- mappre
- dao接口
- test
- 循环student对象:
- sql标签 代码片段
- 模糊查询
- 五、主配置文件
- jdbc.properties
- 在主配置文件中加入
- 设置数据库连接对象
- 设置引入mapper文件
- 六、pageHelper
- pom.xml添加依赖
- 在主配置文件添加声明
- 在javaTest中
- 日志
- Log4j
- 单元测试
- 指定排序方案
mvc架构模式
在web开发的过程中,使用mvc架构模式。
m数据 (来自数据库,文件,网络)
v视图(jsp,html,显示请求的处理结果)
c控制器(接受请求,调用servlet对象显示处理的结果,servlet)
作用:
- 实现解耦合
- 让mvc各负其职
- 使得系统的扩展性更好,更容易的维护
在web应用中很通用
三层架构
- 界面层(视图层) 用来接受用户的请求,显示请求的处理结果,是包含了jsp、http、servlet的,是和用户直接打交道的,对应的包是controller ,
- 业务逻辑层 处理业务的逻辑,使用算法来处理数据的,把数据返回给界面层,对应的是service包,和其中很多的xxxService类,比如studentService,,等等,一般都是在service包中
- 持久层(数据访问层) 访问数据库,读取文件,访问网络,获取数据。对应的是dao包
- 结构清晰,耦合度低,分工明确
- 可维护性高,可扩展高
- 有利于标准化
- 开发人员只关注其中的一层的功能实现
- 有利于各个层逻辑的复用
三层架构请求处理的流程
用户发起请求—界面层—业务逻辑层—持久层—数据库
三层架构模式和框架
每一层对应一个框架
界面层–SpringMVC
业务逻辑层—Spring
持久层—MyBatis
jdbc访问数据库的优缺点
优点
- 直观,好理解
缺点:
- 创建很多对象
- 注册驱动
- 执行sql语句
- 转换结果集
- 关闭资源
- sql语句和业务逻辑代码混在一起
MyBatis
ssm中的m是半面向对象的,效率比hibernater高
ssh中的h是Hibernater,是面向对象的
jdbc是手动的,mybatis是半自动的,hibernater是全自动的
本是apache的一个[开源项目]iBatis, 2010年这个[项目]由apache software foundation 迁移到了[google code],并且改名为MyBatis 。2013年11月迁移到[Github]
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
当前,最新版本是MyBatis 3.5.6 ,其发布时间是2020年10月6日。
可以操作数据库,对数据库进行增删查改,可以看作是一个高级的jdbc,解决了jdbc的缺点
- 注册驱动
- 创建jdbc中使用的Connection、Statement、ResultSet
- 执行sql语句,得到结果集
- 处理结果集,把结果集的数据转换成java对象,把java对象放入到list集合
- 关闭资源
- 实现sql语句和Java代码的解耦合
MyBatis的官网:https://mybatis.org/mybatis-3/zh/index.html
二、MyBatis框架的快速入门
搭建MyBatis开发环境
- 创建一个maven标准的java项目
- pom.xml配置
添加依赖:MyBatic、mysql
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency><dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency>
在加入插件
<resources> <resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes> </resource> </resources>
创建一个实体类pojo,属性名字和表的列名保持一致
package com.itlf.domain;/*** Created with IntelliJ IDEA.** @author: LiuF* @date: 2021/5/16* @description:* @version: 1.0*/ public class Book {private int id;private String bName;private int price;private String author;public Book() {}public Book(int id, String bName, int price, String author) {this.id = id;this.bName = bName;this.price = price;this.author = author;}public int getId() {return id;}public Book setId(int id) {this.id = id;return this;}public String getbName() {return bName;}public Book setbName(String bName) {this.bName = bName;return this;}public int getPrice() {return price;}public Book setPrice(int price) {this.price = price;return this;}public String getAuthor() {return author;}public Book setAuthor(String author) {this.author = author;return this;}@Overridepublic String toString() {return "Book{" +"id=" + id +", bName='" + bName + '\'' +", price=" + price +", author='" + author + '\'' +'}';} }
创建一个dao接口,定义操作数据的方法
package com.itlf.dao;import com.itlf.domain.Book;/*** Created with IntelliJ IDEA.** @author: LiuF* @date: 2021/5/16* @description:* @version: 1.0*/ public interface IBookDao {/*** 根据id查询一条数据** @return*/Book findBookById(int id);}
创建一个xml文件(mapper),写sql语句的,写在dao接口在同一个目录,一般是一个表一个mapper文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.itlf.dao.IBookDao"><select id="findBookById" resultType="com.itlf.domain.Book">select bName,price,author from book where id = #{id} </select><insert id="insertBook">insert into book values (0,#{bName},#{price},#{author})</insert> </mapper>
创建MyBatis的主配置文件(只有一个),放在resources目录下
定义数据库的连接实例的数据源对象
指定其他mapper文件的位置
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&rewriteBatchedStatements=true
username=root
password=123456
initialSize=5
maxActive=10
maxWait=2000
mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--配置jdbc的连接信息--><properties resource="jdbc.properties"/><environments default="development"><environment id="development"><transactionManager type="JDBC"/><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><!--找到mapper文件,执行sql语句,一个mapper指定一个--><mappers><mapper resource="com/itlf/dao/IBookDao.xml"/></mappers>
</configuration>
- 创建测试内容
可以使用main方法
也可以使用unit4单元测试
提交事务:
默认的是手动改提交事务
// 修改为自动提交
SqlSession session = factory.openSession(true);
在添加、删除、修改后要手动提交事务
session.commit();
重要对象
Resources
读取主配置信息
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder
创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSessionFactory(重要对象)
是一个重量级的对象:就是创建对象要更多的资源和时间。在项目中有一个就可以
是一个接口:是SqlSession的工厂,用来创建SqlSession对象
public class DefaultSqlSessionFactory implements SqlSessionFactory {
方法:
openSession() 创建一个sqlSession对象,默认是需要手工提交事务的
可以给参数,true是自动提交事务
sqlSession对象
提供了大量的执行sql的方法
selectOne
selectList
selectMap
insert
update
delete
commit
rollback
sqlSession不是线程安全的,使用的步骤
- 在方法的内部,执行sql语句之前,先获取sqlSession对象
- 调用sqlSession,执行sql语句
- 关闭sqlSession
使用工具类和模板
工具类
/** * -----------------------静态模式------------------------------ */ private static SqlSessionFactory factory = null; static { String config = "mybatis.xml"; try { InputStream is = Resources.getResourceAsStream(config); factory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSqlSession() { SqlSession session = null; if (factory != null) { session = factory.openSession(); } return session; }
/** * -----------------------单例模式------------------------------- */private static SqlSessionFactory factory = null;private static MyBatisUtil myBatisUtil = new MyBatisUtil(); // 饿汉模式private MyBatisUtil() { String config = "mybatis.xml"; try { InputStream is = Resources.getResourceAsStream(config); factory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { e.printStackTrace(); }}/** * 单例模式对外提供给一个出口,返回自身的单例对象 * * @return */public static MyBatisUtil getInstance() { return myBatisUtil;}/** * 获取SQL Session对象 * * @return */public SqlSession getSqlSession() { SqlSession session = null; if (factory != null) { session = factory.openSession(); } return session;}
模板
创建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主配置文件模板
<?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> <!--配置jdbc的连接信息--> <properties resource="jdbc.properties"/> <!-- 日志输出 <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> --> <!--连接数据库对象--> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <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> <!--找到mapper文件,执行sql语句,一个mapper指定一个--> <mappers> <mapper resource="com/itlf/dao/xxxDao.xml"/> </mappers></configuration>
java.sql.SQLException: Unknown initial character set index ‘255‘ received from server.
更改jdbc的版本
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version></dependency>
三、dao代理
mybatis在内存中创建一个dao的实现类对象,完成sql语句的执行
使用条件:
- mapper文件中的namespace必须是dao接口的全限定名
- mapper文件中标签的id必须和dao接口中方法的名称一模一样
实现方式:
BookDao bookDao = session.getMapper(BookDao.class);
运用反射机制,方法getMappper,得到dao接口的class
然后在调用接口中相应的抽象方法
Book book = bookDao.SelectBookById(5);
参数类型
parameterType=""
值可以有两种
- java类型的全限定类型的名称
- mybatis定义的java类型的别名
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
形参起别名
在定义接口的时候,可以通过@Param给形参起别名
User findById(@Param("id") long id);
resultMap结果映射
<resultMap id="userResultMap" type="User"> <id property="id" column="user_id" /> <result property="username" column="user_name"/> <result property="password" column="hashed_password"/></resultMap>
<select id="selectUsers" resultMap="userResultMap"> select user_id, user_name, hashed_password from some_table where id = #{id}</select>
下划线到驼峰的映射
<settings> <!--<setting name="logImpl" value="STDOUT_LOGGING"/>--> <setting name="mapUnderscoreToCamelCase" value="true"/></settings>
嵌套查询
简单的
<resultMap id="rm" type="Major"> <association property="college" column="college" select="com.ychs.dao.CollegeMapper.selectById"/></resultMap>
复杂的
<!--autoMapping:自动映射属性和列--><resultMap id="rm" type="College" autoMapping="true"> <id property="id" column="id"/> <collection property="majors" javaType="java.util.List" ofType="Major"> <result property="id" column="mid"/> <result property="code" column="mcode"/> <result property="name" column="mname"/> </collection></resultMap><sql id="select"> SELECT c.id,c.`CODE`,c.`NAME`,m.id as mid,m.`CODE` as mcode,m.`NAME` as mname FROM college c LEFT JOIN major m on m.college = c.id</sql><select id="selectById" resultMap="rm"> <include refid="select"/> where c.id = #{id}</select>
四、动态sql
同一个dao方法,根据不同的条件可以表示不同的sql语句,主要是where部分有变化
使用mybatis提供的标签,实现动态sql的能力,主要讲的是if,where,foreach,sql
使用动态sql的时候,dao方法使用形参使用Java对象
if
多应用于多条件查询
语法:
在mapper文件中<select id="selectStudent" resultType="com.itlf.domainStudent"> select * from student(主sql) <if test="条件"> sql语句(部分sql) </if> <if test="条件"> sql语句(部分sql) </if> <if test="条件"> sql语句(部分sql) </if></select>
mapper
<!--iftest:使用对象的属性值作为条件--><select id="selectIf" resultType="com.itlf.domain.Book"> select * from book where 1=1 <if test="bName != null and bName != ''"> or bName=#{bName} </if> <if test="id > 0"> or id=#{id} </if></select>
dao接口
/** * book的if条件查询 * @param book * @return */List<Book> selectIf(Book book);
测试:
@Testpublic void test02() { SqlSession session = MyBatisUtil.getInstance().getSqlSession(); BookDao mapper = session.getMapper(BookDao.class); Book book = new Book(); book.setId(3); book.setbName("book"); List<Book> list = mapper.selectIf(book); for (Book book1 : list) { System.out.println(book1); } session.close();}
where
使用if标签的时候,容易造成sql语句的语法错误,使用where标签解决if产生的语法错误
使用where,里面 是一个或者多个if标签,当有一个if标签的时候,判断条件为true where标签会转换为WHERE关键字附加到sql语句的后面 ,如果if没有一个条件为true,忽略where和里面的if
语法
<where> <if test="条件一">sql语句</if> <if test="条件二">sql语句</if> ....</where>
mapper
<!-- where --><select id="selectWhere" resultType="com.itlf.domain.Book"> select * from book <where> <if test="id>0"> or id=#{id} </if> <if test="bName != null and bName != ''"> or bName=#{bName} </if> </where></select>
dao接口
/** * book的where条件查询 * * @param book * @return */List<Book> selectWhere(Book book);
test
@Test public void testWhere() { SqlSession session = MyBatisUtil.getInstance().getSqlSession(); BookDao mapper = session.getMapper(BookDao.class); Book book = new Book(); book.setId(12); book.setbName("三天光明"); List<Book> list = mapper.selectWhere(book); for (Book book1 : list) { System.out.println(book1); } session.close(); }
foreach
使用foreach可以循环数组,list集合,一般用在in语句中
<foreach collection="集合类型" open="开始的字符" close="结束的字符" item="集合中的成员" separator="集合成员之间的分隔符"> #{item 值}</foreach>
mappre
<select id="selectForeachOne" resultType="com.itlf.domain.Book"> select * from book <if test="list != null and list.size > 0"> where id in <foreach collection="list" open="(" close=")" separator="," item="myid"> #{myid} </foreach> </if> </select>
dao接口
/** * book的foreach条件查询 * * @param list * @return */List<Book> selectForeachOne(List list);
test
public void testSelectForeachOne() { SqlSession session = MyBatisUtil.getInstance().getSqlSession(); BookDao mapper = session.getMapper(BookDao.class); List<Integer> list = new ArrayList<>(); list.add(10); list.add(12); list.add(13); list.add(14); List<Book> list1 = mapper.selectForeachOne(list); for (Book book : list1) { System.out.println(book); } session.close();}
循环student对象:
sql标签 代码片段
sql标签可以是一段代码片段,表名,几个字段,where条件都可以,可以在其他的地方复用sql标签的内容
1)可以在mapper文件中定义sql代码片段,<sql id = "唯一的字符串"> 部分sql语句 </sql>2)在其他的位置使用include来引用
<!--定义代码片段--><sql id="selectBook"> select * from book</sql>
<select id="SelectBookById" resultType="com.itlf.domain.Book"> <include refid="selectBook"/> where id =#{id}</select>
模糊查询
select * from tbl_employee
<!-- 用trim:trim标签体中是整个字符串拼串后的结果 prefix:前缀:prefix给拼串后的整个字符加一个前缀 prefixOverrides:前缀覆盖:去掉整个字符串前面多余的字符 suffix:给拼串后的整个字符加一个后缀 suffixOverrides:后缀覆盖:去掉整个字符串后面多余的字符 --> <!--自定义字符串的截取规则--> <trim prefix="where" suffixOverrides="and"> <if test="id!=null"> id=#{id} and </if> <if test="lastName!=null and lastName!="""> last_name like #{lastName} and </if> <if test="email!=null and email.trim()!="""> email=#{email} and </if> <if test="gender==0 or gender==1"> gender=#{gender} </if> </trim></select>
五、主配置文件
jdbc.properties
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&rewriteBatchedStatements=trueusername=rootpassword=123456initialSize=5maxActive=10maxWait=2000
在主配置文件中加入
<!--配置jdbc的连接信息--><properties resource="jdbc.properties"/>
设置数据库连接对象
<!--连接数据库对象--><environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <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>
设置引入mapper文件
<!--找到mapper文件,执行sql语句,一个mapper指定一个--><mappers> <mapper resource="com/itlf/dao/BookDao.xml"/></mappers>
六、pageHelper
pom.xml添加依赖
<!--pageHelper--><dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version></dependency>
在主配置文件添加声明
<!--添加声明--><plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"/></plugins>
在javaTest中
public void test() { SqlSession session = MyBatisUtil.getInstance().getSqlSession(); BookDao bookDao = session.getMapper(BookDao.class); PageHelper.startPage(1, 3); // 在查询之前加入这个语句,第1页 一页3条 List<Book> bookList = bookDao.SelectAllBook(); for (Book book : bookList) { System.out.println(book); } }
日志
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/></settings>
Log4j
可以记录日志,可以用不同的日志级别去记录,可以开或者关闭
现有的框架产品,一些大公司都在使用,非常成熟。
Log4j1和Log4j2
Log4j1使用properties配置
Log4j2使用xml配置
单元测试
指定排序方案
按照字母排序
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
MyBatis_01_刘锋的博客相关推荐
- MySQL_DQL数据查询语言_刘锋的博客
文章目录 DQL数据查询语言 进阶一:基础查询 进阶二:条件查询 进阶三:排序查询 进阶四:常见函数 一.单行函数 二.分组函数(聚合函数) 进阶五.分组查询 进阶六:连接查询(多表查询) sql92 ...
- Spring_刘锋的博客
文章目录 一.Spring 简介 maven配置 优点 组成 拓展 二.IOC理论推导 helloSpring beans.xml Hello.class MyTest.class dao的sprin ...
- JSON_刘锋的博客
文章目录 JSON 一.什么是JSON 1.创建一个js对象 2.将js对象转换为json对象 3.将json对象转换成js对象 test.html 二.Controller返回JSON数据 Jack ...
- MySQL_TCL事务控制语言_刘锋的博客
文章目录 TCL事务控制语言 一.事务的属性(ACIB) 原子性 一致性 隔离性 持久性 二.事务的创建 隐式的事务 显式的事务 三.事务的隔离级别 脏读: 不可重复度: 幻读: 四.delete和t ...
- JDBC_刘锋的博客
文章目录 JDBC 1.JDBC概述 2.获取数据库连接 3.使用preparedstatement实现CRUD操作 增加(Create) 更新(Update) 通用的增删(delete)改 检索(R ...
- jsp中Ajax请求发送PUT、DELETE请求的方式_刘锋的博客
jsp中Ajax请求发送PUT.DELETE请求的方式 方式一 首先配置pom.xml ,添加过滤器 <filter><filter-name>hiddenHttpMethod ...
- Lombok_刘锋的博客
文章目录 概念: 使用: 常用注解: 优点: 缺点: 1. JDK版本问题 2. 胁迫使用 3. 可读性差 4. 代码耦合度增加 概念: Lombok项目是一个Java库,它会自动插入编辑器和构建工具 ...
- SpringMVC_刘锋的博客
文章目录 一. 回顾servlet 创建maven项目 设置pom.xml依赖 创建普通的子项目,添加web框架支持 HelloServlet from.jsp test.jsp 二.初始Spring ...
- Maven_刘锋的博客
文章目录 ANT 概述 功能 安装 种类和之间的关系 本地仓库 远程仓库 中央仓库 设置本地仓库路径 Maven的标准目录结构 Maven常用的命令 Maven生命周期 Maven概念模型图 IDEA ...
最新文章
- javascript创建对象
- Atitit.upnp SSDP 查找nas的原理与实现java php c#.net c++
- mysql windows集群_Mysql集群windows服务器版搭建过程
- oracle中primary,oracle中如何 Primary key自增
- BZOJ1911:[Apio2010]特别行动队——题解
- linux在指定目录多个文件中搜索关键字
- qt调用import sys库_Python模块之 sys 模块
- VB.NET2005通过泛型实现的KMP查找算法
- Unity3D基础4:空物体与预制体
- uos系统安装教程_统一操作系统UOS下载&安装图文教程:尝鲜记(一)
- 敏感词过滤的php代码,ThinkPHP敏感词汇过滤
- 金蝶KIS专业版本单据导入导出工具使用说明
- The Code is successfully generatd...使用stm32cude生成工程时报错
- 如何完全清除微信聊天记录
- JS - 计算直角三角形的边长及角度
- 揭秘:全球第一张云安全国际认证金牌得主
- vitamin_baidu
- iOS: pch 如何添加项目中
- html 中数字换行,CSS实现连续数字和英文的自动换行的方法
- 2023 CVTE寒暑假实习C++开发 笔试一面面经
热门文章
- 关于PDF的相关操作-----PyPDF2
- 安卓、iOS支持录音格式
- python封装成exe win7不能用_pyinstaller打包python的执行文件如何在32位和64位操作系统下也能运行...
- JCFXBL JSM文件(I/O)操作设计思想
- photon四种同步方式_【程序】必看干货:Photon多人游戏开发教程
- MySQLWorkbench导出数据库生成sql文件
- linux系统Hadoop启动错误,Hadoop启动错误解决总结
- Java正则表达式(一看就懂)
- 使用python3发送nbns协议包,并说明注意事项
- 信息学奥赛一本通答案dj均值1060