Java框架!聊聊MyBatis的历史
Posted 程序员超时空
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java框架!聊聊MyBatis的历史相关的知识,希望对你有一定的参考价值。
原生的mybatis(使用xml)
关于别名
关于namespace
原生的mybatis(使用注解)
Mybatis与spring
MapperFactoryBean
SqlSessionDaoSupport
Mybatis与springBoot
Mybatis与mybatis-plus
序言
==
最近项目中,需要在mysql里面新增一个表,然后套用mybatis做增删改查,然后再mapper.java的方法上写注解。写着写着就感觉很烦,为什么呢?看下面:
@Insert({
"INSERT INTO " + TABLE_NAME + INSERT_COLUMNS +
" VALUES" +
"(#{id},now(),now(),#{idxConfigId},#{userId},#{ownerId},#{status}," +
" #{ukIdempotent},#{startTime},#{endTime},#{extraInfo}," +
" #{awardResult},#{boxConfig},#{currentCount},#{treeId},#{target},#{scope} )"
})
int insertFinanceInfo(FarmFinanceInfoDO financeInfoDO);
@Update({ "update "+TABLE_NAME+" set " +
" idx_config_id = #{idxConfigId}, " +
" owner_id = #{ownerId},status = #{status}, " +
" uk_idempotent = #{ukIdempotent}, " +
" start_time = #{startTime,jdbcType=TIMESTAMP}, " +
" end_time = #{endTime,jdbcType=TIMESTAMP}, " +
" current_count = #{currentCount}, " +
" tree_id = #{treeId},target = #{target}, scope = #{scope}, " +
" box_config = #{boxConfig},award_result = #{awardResult}, " +
" extra_info = #{extraInfo} " +
" where id = #{id} and user_id= #{userId}" })
int updateFinanceInfo(FarmFinanceInfoDO financeInfoDO);
其实我是特别不喜欢在java文件里写这种很长的注解的,感觉特别乱,我甚至愿意把它放到xml里面。后来在网上搜了一下原来还有一个叫mybatis-plus的组件,看着还不错,然后在应用过程中也发生了一下问题,问题的根源就是自己还是急于求成,直接在网上搜一下现成的不成体系的代码就用,后面自然一堆问题。然后这两天就稍微挤出一点时间,把mybatis的使用,从最开始的原生xml,到注解,到spring,到spring-boot到mybatis-plus的使用都梳理了一遍。
原生的mybatis(使用xml)
=================
POM如下:
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
下面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>
<!-- 别名 -->
<typeAliases>
<package name="entity"/>
</typeAliases>
<!-- 数据库环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test_db?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 -->
<mappers>
<mapper resource="mapper/user.xml"/>
</mappers>
</configuration>
下面是某个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="xml">
<select id="listUser" resultType="user">
select * from user;
</select>
</mapper>
这个mapper里面有个namespace,我一直不知道它是什么意思。没关系这个namespace先随便写,一会就知道它是什么意思了。
增加entity
package entity;
/**
* @program: parent_pro
* @description:
* @author: 渭水
* @create: 2021/07/21
*/
public class User {
private int id;
private String username;
private String password;
private String nickname;
// 省略getset
}
最后的启动类
package xml;
import entity.User;
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;
import java.util.List;
/**
* @program: parent_pro
* @description:
* @author: 渭水
* @create: 2021/07/21
*/
public class MyBatisWithXML {
public static void main(String[] args) {
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
// 最后通过 session 的 selectList() 方法调用 sql 语句 listStudent
List<User> userList = session.selectList("listUser");
for (User student : userList) {
System.out.println("ID:" + student.getId() + ",NAME:" + student.getUsername());
}
}
}
我们看看整个项目个结构图:
数据库那边,我已经建立好了,大家看看:
运行项目就能看到:
OK,至此项目已经可以运行了。
然后我们分析一下代码:
关于别名
一段一段看
<select id="listUser" resultType="user">
select * from user limit 5;
</select>
这个里面的resultType,我们不用看框架,大概就懂它指的是把下面的sql语句执行的结果,包装成什么类型。
那么光写个user,mybatis知道这个user是个什么东西么?
<!-- 别名 -->
<typeAliases>
<package name="entity"/>
</typeAliases>
上面一段代码的语义就是,把entity下面的实体都加一个别名,而别名就是类名。所以mybatis就知道上面的user其实对应的就是entity.User这个类。
关于namespace
上面已经有了一个mapper,我现在再加一个mapper如下:
和之前那个的区别就是一个limit 5,一个limit 10
然后让mybatis的主配置文件感知到这个user2.xml
<!-- 映射文件 -->
<mappers>
<mapper resource="mapper/user.xml"/>
<mapper resource="mapper/user2.xml"/>
</mappers>
然后运行代码会发现:
说的很清楚listUser这个id重复了。
在线上工程里,要保证所有的sql的id都不重复有点困难,所以引入了namespace的概念。如果一旦有重复的id,那么session调用的时候得指定namespace。
List<User> userList = session.selectList("xml.listUser");
原生的mybatis(使用注解)
================
@Mapper
public interface PersonMapper {
@Select("select id,name ,age from person where id = #{id}")
Person getPersonById(int id);
@Select("<script>"
+"select * from person where 1=1"
+"<if test='name2 != null'> and name = #{name2}" +"</if>"
+"<if test='age != null'> and age = #{age}" +"</if>"
+"</script>")
List<Person> getList(@Param("name2") String name,@Param("age") String age);
@SelectProvider(type = UserDaoProvider.class, method = "getPersonByPara")
Person getPersonByPara(@Param("name") String name, @Param("age") String age);
}
如上面所示
调用的时候就直接写
PersonMapper personMapper = session.getMapper(PersonMapper.class);
Person result = personMapper.getPersonByPara("渭水","");
List<Person> list = personMapper.getList(null,"25");
其实,这就回到我在序言里说的了,在java代码里写脚本语言很丑,代码很难读。
我们可以用一个单独的java方法来产生sql语句,如下;
@Mapper
public interface PersonMapper {
@SelectProvider(type = UserDaoProvider.class, method = "getPersonByPara")
Person getPersonByPara(@Param("name") String name, @Param("age") String age);
}
public class UserDaoProvider {
public String getPersonByPara(Map<String, Object> para) {
String sql = new SQL() {
{
SELECT("id, name, age");
FROM("person");
if (StringUtils.isNotBlank("" + para.get("name"))) {
WHERE("name='" + para.get("name")+"'");
}
if (StringUtils.isNotBlank("" + para.get("age"))) {
WHERE("age=" + para.get("age"));
}
}
}.toString();
System.out.println("----" + sql);
return sql;
}
}
Mybatis与spring
==============
通过上面我们可以看到,不管是用xml配置,还是直接在java文件里写注解,最终都是通过SqlSession 来指向下一步的操作的。
所以,就算我们把mybatis与spring整合,其实核心原理还是依赖SqlSession 的。
第一步,我们先去掉之前的mybatis依赖,改成
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
然后在spring的xml里面加上
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
dataSource的相关代码我这边就赘述。
然后,具体来说,整合的思路有两种:
MapperFactoryBean
把我们的mapper放到MapperFactoryBean里面
学习分享,共勉
这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!
资料都是免费提供的,整理不易,有需要的朋友可以转发分享下,同时可以关注我,定期分享学习资源还会更新一些技术分享!
整理不易,有需要的朋友转发支持下,感谢感谢!
Java核心知识体系笔记.pdf
中高级Java开发面试高频考点题笔记300道.pdf
架构进阶面试专题及架构学习笔记脑图
Java架构进阶学习视频分享
来说,整合的思路有两种:
MapperFactoryBean
把我们的mapper放到MapperFactoryBean里面
学习分享,共勉
这里是小编拿到的学习资源,其中包括“中高级Java开发面试高频考点题笔记300道.pdf”和“Java核心知识体系笔记.pdf”文件分享,内容丰富,囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。同时还有Java进阶学习的知识笔记脑图(内含大量学习笔记)!
资料都是免费提供的,整理不易,有需要的朋友可以转发分享下,同时可以关注我,定期分享学习资源还会更新一些技术分享!
整理不易,有需要的朋友转发支持下,感谢感谢!
Java核心知识体系笔记.pdf
[外链图片转存中…(img-T816NIQy-1628135718754)]
中高级Java开发面试高频考点题笔记300道.pdf
[外链图片转存中…(img-d2Wg57yO-1628135718756)]
架构进阶面试专题及架构学习笔记脑图
[外链图片转存中…(img-SIlNOWdA-1628135718758)]
Java架构进阶学习视频分享
[外链图片转存中…(img-7WTUBrSd-1628135718760)]
以上是关于Java框架!聊聊MyBatis的历史的主要内容,如果未能解决你的问题,请参考以下文章