想了解myBatis3笔记的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于mybatis3文档的相关问题,此外,我们还将为您介绍关于javaday56【Mybatis延迟加载策略、Mybat
想了解myBatis3 笔记的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于mybatis3文档的相关问题,此外,我们还将为您介绍关于java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】、Java SSM框架之MyBatis3(六)MyBatis之参数传递、java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】、Java-MyBatis-MyBatis3-XML映射文件:select的新知识。
本文目录一览:- myBatis3 笔记(mybatis3文档)
- java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】
- Java SSM框架之MyBatis3(六)MyBatis之参数传递
- java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】
- Java-MyBatis-MyBatis3-XML映射文件:select
myBatis3 笔记(mybatis3文档)
mybatis 3
官网手册 : https://mybatis.org/mybatis-3/zh/getting-started.html**
一.创建一个Mybatis 应用
1.创建mybatis工具类 mybatisUtls
mybatisUtls.java
//sqlSessionFactory --> sqlSession
public class MybatisUtils {
private static sqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsstream(resource);
sqlSessionFactory = new sqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printstacktrace();
}
}
public static sqlSession getsqlSession(){
return sqlSessionFactory.openSession();
}
}
2.mybatis被动需要核心配置 mybatis-config.xml
mybatis-config.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 id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.MysqL.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:MysqL:///mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper. XML都需要在Mybatis核心配置文件中注册! -->
<mappers>
<mapper resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
</configuration>
3.实体类 pojo.User
user.java
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
4.接口 UserDao,后写Mapper.xml
接口userDao
public interface UserDao {
List<User> getUserList();
}
Usermapper.xml
<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--绑定一个对应的dao or mapper 接口-->
<mapper namespace="com.kuang.dao.UserDao">
<!-- select 查询语句-->
<select id="getUserList" resultType="com.kuang.pojo.User">
select * from mybatis.user
</select>
</mapper>
5.写测试类UseraoTest
public class UserDaoTest {
@Test
public void test(){
// 第一步 获得sqlSession对象
sqlSession sqlSession = MybatisUtils.getsqlSession();
try {
// 方式一: getMapper 极其推荐
UserDao userDao= sqlSession.getMapper(UserDao.class);
List<User> userList=userDao.getUserList();
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printstacktrace();
} finally {
sqlSession.close();
}
// 方式二 : 不推荐 老了
// List<User> userList = sqlSession.selectList("com.kuang.dao.UserDao.getUserList");
}
}
mybatis 核心配置
路径:src/main/resources/mybatis-config.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 id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.MysqL.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:MysqL:///mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper. XML都需要在Mybatis核心配置文件中注册! -->
<mappers>
<mapper resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
</configuration>
注意点
找不到Mapper.xml 报错;在父 子 pom.xml文件中加如下code
资源扫描器插件
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
dao接口
public interface UserDao {
List<User> getUserList();
}
●接口实现类由原来的UserDaolmpl转变为-个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">
<!--绑定一个对应的dao or mapper 接口-->
<mapper namespace="com.kuang.dao.UserDao">
<!-- select 查询语句-->
<select id="getUserList" resultType="com.kuang.pojo.User">
select * from mybatis.user
</select>
</mapper>
CROD
1.namespace
中的包名 要与 dao/mapper 接口的包名 一致
2.select
- id : 就是对应的namespace中的方法名;
- resultType:sql语句执行的返回值!
- parameterType :参数类型!
-
编写接口
// 查询所有用户 List<User> getUserList(); // select byId User getUserById(int id);
-
编写对应的mapper中的sql语句
<!--绑定一个对应的dao or mapper 接口--> <mapper namespace="com.kuang.dao.UserMapper"> <!-- select 查询语句--> <select id="getUserList" resultType="com.kuang.pojo.User"> select * from mybatis.user </select> <select id="getUserById" parameterType="int" resultType="com.kuang.pojo.User"> select * from mybatis.user where id =#{id} </select>
-
测试
@Test //Test 必须写这个注解 public void list(){ // 第一步 获得sqlSession对象 sqlSession sqlSession = MybatisUtils.getsqlSession(); try { // 方式一: getMapper 极其推荐 UserMapper userDao= sqlSession.getMapper(UserMapper.class); List<User> userList=userDao.getUserList(); for (User user : userList) { System.out.println(user); } } catch (Exception e) { e.printstacktrace(); } finally { sqlSession.close(); } // 方式二 : 不推荐 老了 // List<User> userList = sqlSession.selectList("com.kuang.dao.UserDao.getUserList"); } @Test public void getUserById(){ sqlSession sqlSession = MybatisUtils.getsqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(12); System.out.println(user); sqlSession.close(); }
3.insert(mapper.xml)
<!--insert -->
<insert id="addUser" parameterType="com.kuang.pojo.User" >
insert into mybatis.user(id, name, pwd) value (#{id},#{name},#{pwd})
</insert>
4.update
<!-- update -->
<update id="updateUser" parameterType="com.kuang.pojo.User" >
update mybatis.user set name =#{name},pwd=#{pwd} where id = #{id};
</update>
5.delete
<!-- delete -->
<delete id="deleteUser" parameterType="com.kuang.pojo.User" >
delete from mybatis.user where id =#{id}
</delete>
注意点:
-
增 删 改 需要提交事务
-
resource绑定mapper, 需要使用路径 / /
<!--每一个Mapper. XML都需要在Mybatis核心配置文件中注册! --> <mappers> <mapper resource="com/kuang/dao/UserMapper.xml"/> </mappers>
- 程序配置文件必须符合规范!
- NullPointerException,没有注册到资源!
- 输出的xm|文件中存在中文乱码问题!
- maven资源没有导出问题!
万能Mapper
假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!
// 万能的Map
int addUser2(Map<String,Object> map);
<!--insert 万能Map-->
<insert id="addUser2" parameterType="map" >
insert into mybatis.user(id, name, pwd) value (#{userid},#{username},#{password})
</insert>
@Test
public void addUser2(){
// 万能Map 增删改 需要提交事务
sqlSession sqlSession = MybatisUtils.getsqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<>();
map.put("userid", 5);
map.put("username","hello");
map.put("password","helio0");
mapper.addUser2(map);
sqlSession.commit(); // 增删改 需要提交事务
sqlSession.close();
}
- Map传递参数,直接在sq|中取出key即可! [parameterType="map"]
- 对象传递参数,直接在sq|中取对象的属性即可! [parameterType="Objet"]
- 只有一个基本类型参数的情况下,可以直接在sq|中取到!
- 多个参数用Map,或者注解!
模糊查询 怎么写
- 在sql拼接中使用通配符
<select id="getUserLike" resultType="com.kuang.pojo.User">
select * from mybatis.user where name like "#" #{ value} "#"
</select>
容易存在sql注入,
- java执行时使用通配符
@Test
public void getUserLike(){
// 第一步 获得sqlSession对象
sqlSession sqlSession = MybatisUtils.getsqlSession();
UserMapper mapper= sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserLike("%李%");
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
让用户只能传稳定的值
配置解析
1.MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
2、环境配置(environments)
MyBatis可以配置成适应多种环境
不过要记住:尽管可以配置多个环境,但每个SqISessionFactory实例只能选择1种环境。
学会使用配置多套运行环境!
Mybatis默认的事务管理器就是JDBC,连接池: POOLED
resultMap
结果集映射
1 name id pwd
2 name id password
UserMapper.xml
<!-- 结果集映射 sql中 列 --> User类中的属性 -->
<resultMap id="UserMap" type="User">
<result column="id" property="id"/>
<result column="name" property="name"/>
<!--suppress MybatisXMapperXmlinspection -->
<result column="pwd" property="password" />
</resultMap>
<select id="getUserById" parameterType="int" resultMap="UserMap">
select * from mybatis.user where id =#{id}
</select>
6.日志
如果一一个数据库操作,出现了异常,我们需要排错。日志就是最好的助手!
曾经: sout、 debug
现在:日志工厂!
LOG4J(mybatis 3.5.9 起废弃) LOG4J2
- STDOUT_LOGGING
-
LOG4J
导包
@H_301_305@<!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
log4j.properties
### set log levels ###
log4j.rootLogger = DEBUG,console,file
### 输出到控制台 ###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [%c]-%m%n
### 输出到日志文件 ###
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/hou.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
# 日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
mybatis-config.xml
<settings>
<setting name="logImpl" value="LOG4J"/>
<!-- 标准的日志 <setting name="logImpl" value="STDOUT_LOGGING"/> -->
</settings>
log4j 简单使用
-
在要使用Log4j的类中,导入包 import org.apache.log4j.Logger;
-
日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserDaoTest.class);
-
日志级别
logger.info("info 进入testLog4j"); logger.debug("info 进入testLog4j"); logger.error("info 进入testLog4j");
分页
select * from mybatis.user limit stratIndex,endindex
select * from mybatis.user limit 3; [0,n]
-
limit 分页
-
RowBounds实现
-
分页插件
了解即可,万一以后公司的架构师,说要使用,你需要知道它是什么东西!|
使用注解开发
-
面向接口编程
-大家之前都学过面向对象编程,也学习过接口,但在真正的开发中,很多时候我们会选择面向接口编程
- **根本原因:
解耦 ,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好,在一一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部
是如何实现自己的,对系统设计人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。
关于接口的理解
-接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
. 接口的本身反映了系统设计人员对系统的抽象理解。
-接口应有两类:
-第一类是对一个个体的抽象,它可对应为- -个抽象体(abstract class);
-第二类是对一一个个体某一 方面的抽象,即形成一个抽象面(interface) ;
-一个体有可能有多个抽象面。抽象体与抽象面是有区别的。
三个面向区别
面向对象是指,我们考虑问题时,以对象为单位,考虑它的属性及方法.
面向过程是指,我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现.
-接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题更多的体现就是对系统整体的架构
-
适用注解开发
本质:反射机制实现
底层:动态代理!
- 注解 CROD
[注意:我们必须要将 接口注册绑定到我们的核心配置文件中! ]
关于@Param("uid")
●基本类型的参数或者String类型,需要加上
●引用类型不需要加
●如果只有一个基本类型的话,可以忽略,但是建议大家都加上!
●我们在sql中引用的就是我们这里的@param()中设定的属性名!
#{} (推荐 ,可以防止sql注入, 跟Statement和Prestatement) ${} 区别
Lombok
1 进入设置安装lombok 插件,
2 导包
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
3 实体类上加注解即可
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String password;
}
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @requiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@StandardException
@val
@var
experimental @var
@UtilityClass
Lombok config system
@Data: 生成 无参构造,get、 set、 tostring. hashcode, equals
优点:
1.能通过注解的形式自动生成构造器、getter/setter. equals. hashcode、 toString等方法, 提高了-定的开发效率
2.让代码变得简洁,不用过多的去关注相应的方法
3.属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等
缺点:
1.不支持多种参数构造器的重载如
2.虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度
总结
Lombok虽然有很多优点,但Lombok更类似于一种IDE插件, 项目也需要依赖相应的jar包。Lombok依赖jar包是因为编译时要用它
的注解,为什么说它又类似插件?因为在使用时,eclipse或IntelliJ IDEA都需要安装相应的插件,在编译器编译时通过操作AST (抽象
语法树)改变字节码生成,变向的就是说它在改变java语法。它不像spring的依赖注入或者mybatis的ORM-样是运行时的特性,而是编译时的特性。这里我个人最感觉不爽的地方就是对插件的依赖!因为Lombok只是省去了一些人工生成代码的麻烦, 但IDE都有快捷键来协助生成getter/setter等方法, 也非常方便。
知乎上有位大神发表过对Lombok的一些看法:
这是一种低级趣味的插件,不建议使用。JAVA发展到今天,各种插件层出不穷,如何甄别各种插件的优劣?能从架构上优化你的设计的,能提高应用程序性能的,实现高度封装可扩展的...,像lombok这种, 像这种插件,已经不仅仅是插件了,改变了你如何编写源码,事实上,少去了的代码,你写.上去又如何?如果JAVA家族到处充斥这样的东西, 那只不过是一坨披着金属颜色的屎, 迟早会被其它的语言取代。
多对一
●多个学生,对应-一个老师
●对于学生这边而言,关联 ..多个学生,关联一个老师 [多对一 ]
●对于老师而言,集合,- -个老师,有很多学生 [一对多]
测试环境搭建
1.导入lombok
2.新建实体类Teacher, Student
3.建立Mapper接口
4.建立Mapper .XML文件
5.在核心配置文件中绑定注册我们的Mapper接口或者文件! [方式很多, 随心选]
6.测试查询是否能够成功!
- 子查询
<!-- =======================================-->
<!-- 思路:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师! 子查询
-->
<select id="getStudent" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性(teacher属性),我们需要单独处理 对象: association 集合: collection -->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id}
</select>
- 嵌套查询(推荐)
<!-- 按照结果嵌套处理 推荐 -->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname ,t.name tname
from student s, teacher t
where s.tid = t.id;
</select>
<resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="teacher">
<result property="name" column="tname"/>
</association>
</resultMap>
一对多
实体类
@Data
public class Teacher {
private int id;
private String name;
private List<Student> students;
}
@Data
public class Student {
private int id;
private String name;
//学生需要关联一个老师!
private int tid;
}
按照结果嵌套查询(推荐 ,不易出错)
<!-- 按照结果嵌套查询-->
<select id="getTeacher" resultMap="TeacherStudent">
SELECT s.id sid, s.name sname, t.name tname,t.id tid
FROM student s, teacher t
WHERE s.tid = t.id AND t.id = #{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
子查询处理
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id =#{tid};
</select>
<resultMap id="TeacherStudent2" type="teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from mybatis.student where tid =#{tid};
</select>
小结
1.关联- association [多对一 ]
2.集合- collection [- -对多]
javaType & ofType
-
JavaType用来指定实体类中属性的类型
-
ofType用来指定映射到List或者集合中的pojo类型,泛型中的约束类型!
注意点:
●保证sql的可读性,尽量保证通俗易懂
●注意一对多和多对- -中,属性名和字段的问题!
●如果问题不好排查错误,可以使用日志,建议使用Log4j
面试高频
●Mysq引擎
●InnoDB底 层原
●索引
●索引优化!
动态sql
创建一一个基础工程
1.导包
2.编写配置文件
3.编写实体类
@Data
public class Blog {
private int id;
private String title;
private String auther;
private Data createDate;
private int views;
}
4.编写实体类对应Mapper接口和Mapper.XML文件
java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】
第 1 章 Mybatis 延迟加载策略
1.1 何为延迟加载?
1.2 实现需求
1.3 使用 assocation 实现延迟加载
1.3.1 账户的持久层 DAO 接口
1.3.2 账户的持久层映射文件
1.3.3 用户的持久层接口和映射文件
1.3.4 开启 Mybatis 的延迟加载策略
1.3.5 编写测试只查账户信息不查用户信息。
1.4 使用 Collection 实现延迟加载
1.4.1 在 User 实体类中加入 List 属性
1.4.2 编写用户和账户持久层接口的方法
1.4.3 编写用户持久层映射配置
1.4.4 编写账户持久层映射配置
1.4.5 测试只加载用户信息
第 2 章 Mybatis 缓存
2.1 Mybatis 一级缓存
2.1.1 证明一级缓存的存在
2.1.1.1 编写用户持久层 Dao 接口
2.1.1.2 编写用户持久层映射文件
2.1.1.3 编写测试方法
2.1.2 一级缓存的分析
2.1.3 测试一级缓存的清空
2.2 Mybatis 二级缓存
2.2.1 二级缓存结构图
2.2.2 二级缓存的开启与关闭
2.2.2.1 第一步:在 SqlMapConfig.xml 文件开启二级缓存
2.2.2.2 第二步:配置相关的 Mapper 映射文件
2.2.2.3 第三步:配置 statement 上面的 useCache 属性
2.2.3 二级缓存测试
2.2.4 二级缓存注意事项
第 3 章 Mybatis 注解开发
3.1 mybatis 的常用注解说明
3.2 使用 Mybatis 注解实现基本 CRUD
3.2.1 编写实体类
3.2.2 使用注解方式开发持久层接口
3.2.3 编写 SqlMapConfig 配置文件
3.2.4 编写测试方法
3.3 使用注解实现复杂关系映射开发
3.3.1 复杂关系映射的注解说明
3.3.2 使用注解实现一对一复杂关系映射及延迟加载
3.3.2.1 添加 User 实体类及 Account 实体类
3.3.2.2 添加账户的持久层接口并使用注解配置
3.3.2.3 添加用户的持久层接口并使用注解配置
3.3.2.4 测试一对一关联及延迟加载
3.3.3 使用注解实现一对多复杂关系映射
3.3.3.2 编写用户的持久层接口并使用注解配置
3.3.3.3 编写账户的持久层接口并使用注解配置
3.3.3.4 添加测试方法
3.4 mybatis 基于注解的二级缓存
3.4.1 在 SqlMapConfig 中开启二级缓存支持
3.4.2 在持久层接口中使用注解配置二级缓存
Java SSM框架之MyBatis3(六)MyBatis之参数传递
一、单个参数
StudentParamsMapper


package cn.cnki.ref.mapper;
import cn.cnki.ref.pojo.Student;
public interface StudentParamsMapper {
/**
* 根据name查询
* @param name
* @return
*/
public Student getByName(String name);
}
StudentParamsMapper.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="cn.cnki.ref.mapper.StudentParamsMapper">
<!-- 根据用户名和id同时查询 -->
<select id="getStudentByIdAndName" resultType="cn.cnki.ref.pojo.Student">
select * from student where id=#{param1} and name=#{param2}
</select>
</mapper>
StudentParamsController


package cn.cnki.ref.controller;
import cn.cnki.ref.mapper.StudentParamsMapper;
import cn.cnki.ref.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
public interface StudentParamsController {
@RestController
public class StudentParamsMapper {
@Autowired
private cn.cnki.ref.mapper.StudentParamsMapper StudentParamsMapper;
@GetMapping("/studentparams/{name}")
public Student selectCourseById(@PathVariable("name") String name) {
Student student = StudentParamsMapper.getByName(name);
return student;
}
}
}
测试
http://localhost:8080/studentparams/王五

二、多个参数
1.根据参数key值获取,获取规则为param1,param2,param3.........:
StudentParamsMapper


package cn.cnki.ref.mapper;
import cn.cnki.ref.pojo.Student;
public interface StudentParamsMapper {
/**
* 根据用户名和id同时查询
* @param id
* @param name
* @return
*/
public Student getStudentByIdAndName(Integer id,String name);
}
StudentParamsMapper.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="cn.cnki.ref.mapper.StudentParamsMapper">
<!-- 根据用户名和id同时查询 -->
<select id="getStudentByIdAndName" resultType="cn.cnki.ref.pojo.Student">
select * from student where id=#{0} and name=#{1}
</select>
</mapper>
StudentParamsController


package cn.cnki.ref.controller;
import cn.cnki.ref.mapper.StudentParamsMapper;
import cn.cnki.ref.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
public interface StudentParamsController {
@RestController
public class StudentParamsMapper {
@RequestMapping("/getStudentByIdAndName")
public Student getStudentByIdAndName(@RequestParam("id") Integer id, @RequestParam("name") String name) {
Student student = StudentParamsMapper.getStudentByIdAndName(id,name);
return student;
}
}
}
测试
http://localhost:8080/getStudentByIdAndName?id=1&name=张三
2.绑定参数名
StudentParamsMapper


<?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="cn.cnki.ref.mapper.StudentParamsMapper">
<!-- 根据用户名和id同时查询 -->
<select id="getStudentByIdAndNameParam" resultType="cn.cnki.ref.pojo.Student">
select * from student where name=#{name} and id=#{id}
</select>
</mapper>
StudentParamsMapper.xml


package cn.cnki.ref.mapper;
import cn.cnki.ref.pojo.Student;
import org.apache.ibatis.annotations.Param;
public interface StudentParamsMapper {
/**
* 根据用户名和id同时查询
* @param id
* @param name
* @return
*/
public Student getStudentByIdAndNameParam(@Param("id")Integer id, @Param("name")String name);
}
StudentParamsController


package cn.cnki.ref.controller;
import cn.cnki.ref.mapper.StudentParamsMapper;
import cn.cnki.ref.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
public interface StudentParamsController {
@RestController
public class StudentParamsMapper {
@Autowired
private cn.cnki.ref.mapper.StudentParamsMapper StudentParamsMapper;
@RequestMapping("/getStudentByIdAndNameParam")
public Student getStudentByIdAndNameParam(@RequestParam("id") Integer id, @RequestParam("name") String name) {
Student student = StudentParamsMapper.getStudentByIdAndName(id,name);
return student;
}
}
}
测试
http://localhost:8080/getStudentByIdAndNameParam?id=1&name=张三
3.封装实体参数
StudentParamsMapper


package cn.cnki.ref.mapper;
import cn.cnki.ref.pojo.Student;
import org.apache.ibatis.annotations.Param;
public interface StudentParamsMapper {
/**
* 根据用户名和id同时查询
* @param id
* @param name
* @return
*/
public Student getStudentByIdAndNameByObjectParam(Student student);
}
StudentParamsMapper.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="cn.cnki.ref.mapper.StudentParamsMapper">
<!-- 根据用户名和id同时查询 -->
<select id="getStudentByIdAndNameByObjectParam" resultType="cn.cnki.ref.pojo.Student">
select * from student where name=#{name} and id=#{id}
</select>
</mapper>
StudentParamsController


package cn.cnki.ref.controller;
import cn.cnki.ref.mapper.StudentParamsMapper;
import cn.cnki.ref.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
public interface StudentParamsController {
@RestController
public class StudentParamsMapper {
@Autowired
private cn.cnki.ref.mapper.StudentParamsMapper StudentParamsMapper;
@RequestMapping("/getStudentByIdAndNameByObjectParam")
public Student getStudentByIdAndNameByObjectParam(@RequestParam("id") Integer id, @RequestParam("name") String name) {
Student student = new Student();
student.setName(name);
student.setId(id);
Student studentQuery = StudentParamsMapper.getStudentByIdAndNameByObjectParam(student);
return student;
}
}
}
测试
http://localhost:8080/getStudentByIdAndNameByObjectParam?id=1&name=张三
java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】
一、概述
三款框架的功能对比
|
Mybatis-generator |
通用Mapper |
Mybatis-Plus |
代码生成器 |
支持自动生成Model,Mapper,Mapper XML文件 生成方式不够灵活; 生成代码功能较为简单 |
支持自动生成Entity,Mapper,Mapper XML文件; 提供通用的Mapper模板,生成方式较灵活; 生成的Model文件包含注释能够很好地与数据库表完成映射 |
支持自动生成Entity,Mapper,Mapper XML,Service,Controller文件; 提供BaseMapper接口 |
CRUD操作 |
代码生成后每个Mapper有固定的CRUD方法; 在每个Mapper上分别扩展 |
提供通用Mapper接口;方便构造统一service 可以扩展通用接口 |
提供BaseMapper接口; 可以扩展通用接口 |
条件构造器 |
每个实体类自己的Example构造条件【对象方式】 |
提供通用Example【构建sql】 |
提供Wrapper进行复杂条件构造 |
乐观锁 |
|
支持 |
支持 |
主键策略 |
|
支持 |
支持 |
分页 |
|
|
支持 |
逻辑删除 |
|
|
支持 |
通用枚举 |
|
|
支持 |
攻击Sql阻断 |
|
|
支持 |
性能分析 |
|
|
支持 |
通用Mapper是对Mybatis-generator的升级改造,解决了使用Mybatis-generator可能需要大量重构的问题,并且在这个基础上加入了一些新的功能。
Mybatis-Plus可以看作是在另一个方向上对Mybatis的升级改造,不仅能够根据数据库表快速生成pojo实体类,还封装了大量CRUD方法,使用Wrapper解决了复杂条件构造等问题,更是根据开发中常见的问题给出了一系列解决方案。
在拥有Maven和Spring boot的开发框架下,MBG、通用Mapper和MP都可以快速地完成安装,相比于MBG和通用Mapper仅需要执行插件就可以完成基本的开发工作,MP可能需要更多的开发工作量。
最佳实践参看代码:https://github.com/bjlhx15/java_base_architecture.git
二、Mybatis-generator
MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成器。它为所有版本的MyBatis以及版本2.2.0之后的iBATIS版本生成代码。它将根据数据库表生成可用于访问表的文件。
Mybatis-generator主要完成的工作是依据数据库表创建对应的model、dao、mapping文件,可以通过Maven插件或者mybatis-generator的jar包生成。
这里介绍Maven插件使用方法:
1、在pom.xml文件中加入mybatis-generator系列插件;
2、创建generatorConfig.xml文件,在配置文件中指定数据库连接地址、生成类的存放地址、生成对应表的类名等信息;
3、执行mybatis-generator插件,即可生成相应文件;
4、此外,mybatis-generator自动生成了example类用于构造复杂的筛选条件
Mybatis-generator使用较为简单,生成的DAO类及映射文件中包含基本的CRUD操作。
需要注意的是,在一次项目中多次执行mybatis-generator,xml文件会追加,会覆盖原本的Model、DAO;可以使用如下方式
1、每次清理要生成的xml
2、自动生成的写入auto,
3、个人扩展的使用上图方式
可以参看上述github代码
三、通用Mapper【tk.mybatis】
官网:https://github.com/abel533/Mapper/wiki
当数据库字段变化频繁时,使用MBG(mybatis-generator)会带来大量的重构工作,对此,通用Mapper给出的解决办法是:给予开发者一个具备丰富的单表方法并且容易扩展的通用的Mapper。
通用Mapper是对单表的CRUD操作进行了较为详细的实现,使得开发人员可以随意的按照自己的需求选择通用的方法,同时允许开发人员便捷地对通用Mapper进行扩展。
1. 在pom.xml中添加插件配置


<!-- 命令:mvn mybatis-generator:generate -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<!-- 配置实际调用地址-->
<configurationFile>src/main/resources/mybatis_generatorConfig/generatorConfig-base.xml
</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</plugin>
可以看到,通用Mapper的代码生成实际上是使用了MGB,因此通用Mapper的代码生成器只是调用了MGB,然后在这个基础上加入了一些元素来方便开发。
2. 配置文件generatorConfig.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
<!--导入属性配置,前面我们写的一个配置文件,你也可以直接使用mybatis的jdbc的配置文件 -->
<properties resource="jdbc.properties"></properties>
<!-- 数据库驱动,注意,这里必须要修改成你的数据库的驱动地址 -->
<!-- 如果 pom配置这里可以不写-->
<!-- <classPathEntry location=".m2/repository/mysql/mysql-connector-java/5.1.8/mysql-connector-java-5.1.8.jar"/>-->
<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
<property name="caseSensitive" value="true"/>
</plugin>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="${jdbc.driver}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}" password="${jdbc.password}">
</jdbcConnection>
<!-- <javaTypeResolver>-->
<!-- <property name="forceBigDecimals" value="false"/>-->
<!-- </javaTypeResolver>-->
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.github.bjlhx15.mybatis.springboot.base.model.auto"
targetProject="../tk-mybatis-springboot-base1/src/main/java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- targetProject:mapper xml 映射文件生成的位置 -->
<sqlMapGenerator targetPackage="autoxml"
targetProject="../tk-mybatis-springboot-base1/src/main/resources/mapper/">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!--targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.github.bjlhx15.mybatis.springboot.base.repository.auto"
targetProject="../tk-mybatis-springboot-base1/src/main/java">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false"/>
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="accountbalance" domainObjectName="AccountBalance">
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>
与MGB原有的配置文件相比,这里只是多了一个插件的配置,这个插件的作用是:配置生成的Mapper接口都会自动继承这个接口,也就是说,使用通用Mapper生成的mapper接口即使看上去空空如也,但已经具备了大量的对数据库的操作方法。此外,通用 Mapper 专用代码生成器生成的 Model 会在原有基础上增加 @Table,@Id,@Column 等注解,方便自动与数据库字段进行映射。
3. 在 pom.xml 这一级目录的命令行窗口执行 mvn mybatis-generator:generate或者直接在执行mvn插件即可。
4. 通用Mapper同样有Example的设计,与MGB不同的是,MDB会对每一个表生成对应的Example类,而通用Mapper提供了一个统一的Example类,这个类和 MBG 生成的相比,需要自己设置属性名,这个类还额外提供了更多的方法。
通用Mapper可以看作是MGB的改进和扩展,一定程度上解决了使用MGB重构的问题。
可以参看上述github代码
四、Mybatis-Plus
官网地址:https://mp.baomidou.com/guide/generator.html
(以下简称MP)是Mybatis的增强工具(MBG和通用Mapper可看成插件),在Mybatis的基础上增加了很多功能,简化开发,提高效率。
在Spring Boot中的引入:
1. 在maven中添加MP启动器
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
2. 要使用代码生成器还需要添加模板引擎依赖
参看地址:AutoGenerator的使用参考 https://mybatis.plus/guide/generator.html 。
添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。
Velocity(默认):
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.1</version>
</dependency>
Freemarker:
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
Beetl:
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。


AutoGenerator generator = new AutoGenerator();
// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());
// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());
// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());
// other config
...
3、代码的自动生成。AutoGenerator是MP的代码生成器,通过调用AutoGenerator,进行相应的模板、策略配置可以快速生成Entity、Mapper、Mapper XML、Service、Controller各个模块的代码。
4. MP将通用的CRUD操作封装进BaseMapper接口,而自动生成的Mapper接口便自动继承了BaseMapper接口。复杂的Sql操作,则可以使用QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper)进行动态Sql拼接。
5、此外,MP还支持分页、逻辑删除、通用枚举、Sql注入等功能,在:https://mp.baomidou.com/guide/generator.html
还有性能分析插件:https://mp.baomidou.com/guide/performance-analysis-plugin.html
与MBG不同,使用Mybatis-Plus自动生成代码需要编写代码,通过调用AutoAutoGenerator类实现代码生成,从这方面来说不如使用插件方便。但是它丰富的功能以及只是相对复杂的配置还是使它领先于MBG以及通用Mapper。
双方都
Java-MyBatis-MyBatis3-XML映射文件:select
ylbtech-Java-MyBatis-MyBatis3-XML映射文件:select |
select
查询语句是 MyBatis 中最常用的元素之一,光能把数据存到数据库中价值并不大,只有还能重新取出来才有用,多数应用也都是查询比修改要频繁。对每个插入、更新或删除操作,通常间隔多个查询操作。这是 MyBatis 的基本原则之一,也是将焦点和努力放在查询和结果映射的原因。简单查询的 select 元素是非常简单的。比如:
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
这个语句被称作 selectPerson,接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值。
注意参数符号:
#{id}
这就告诉 MyBatis 创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中,就像这样:
// 近似的 JDBC 代码,非 MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
当然,使用 JDBC 意味着需要更多的代码来提取结果并将它们映射到对象实例中,而这就是 MyBatis 节省你时间的地方。参数和结果映射还有更深入的细节。这些细节会分别在后面单独的小节中呈现。
select 元素允许你配置很多属性来配置每条语句的作用细节。
<select
id="selectPerson"
parameterType="int"
parameterMap="deprecated"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句。 |
parameterType | 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler) 推断出具体传入语句的参数,默认值为未设置(unset)。 |
resultType | 从这条语句中返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。可以使用 resultType 或 resultMap,但不能同时使用。 |
resultMap | 外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂映射的情形都能迎刃而解。可以使用 resultMap 或 resultType,但不能同时使用。 |
flushCache | 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。 |
useCache | 将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。 |
fetchSize | 这是一个给驱动的提示,尝试让驱动程序每次批量返回的结果行数和这个设置值相等。 默认值为未设置(unset)(依赖驱动)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖驱动)。 |
databaseId | 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。 |
resultOrdered | 这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。 这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。 |
resultSets | 这个设置仅对多结果集的情况适用。它将列出语句执行后返回的结果集并给每个结果集一个名称,名称是逗号分隔的。 |

出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
今天关于myBatis3 笔记和mybatis3文档的分享就到这里,希望大家有所收获,若想了解更多关于java day56【 Mybatis 延迟加载策略 、 Mybatis 缓存、Mybatis 注解开发 】、Java SSM框架之MyBatis3(六)MyBatis之参数传递、java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】、Java-MyBatis-MyBatis3-XML映射文件:select等相关知识,可以在本站进行查询。
本文标签: