MyBatis入门到实践 概述
MyBatis是一款优秀的 持久层 (Dao) 框架,用于简化JDBC的开发。
MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了googlecode,并且改名为MyBatis。2013年11月迁移到Github。
官网:The MyBatis Blog
MyBatis入门 快速入门 使用Mybatis查询所有用户数据
准备工作(创建springboot工程、数据库表user、实体类User)
MyBatis Framework
、MySQL Driver
1 2 3 4 5 6 7 8 9 10 11 public class User { private Integer id; private String name; private short age; private short gender; private String phone; }
引入Mybatis的相关依赖,配置Mybatis(数据库连接信息)
Data Source
、Drivers
1 2 3 4 5 6 spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver spring.datasource.url = jdbc:mysql://localhost:3306/数据库名 spring.datasource.username = root spring.datasource.password = 1234
编写SQL语句(注解/XML)
1 2 3 4 5 6 7 @Mapper public interface UserMapper { @Select("select * from user") public List<User> list () ; }
测试
Show Context Actions
->inject language or reference
->MySQL(SQL)
——配置SQL语句联想报错提示
Data Source
->MySQL
->DataBase
——配置数据库连接后表名、列名…联想提示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @SpringBootTest class SpringbootMybatisQuickstartApplictionTests { @Autowired private UserMapper userMapper; @Test public void testListUser () { List<User> userList = userMapper.list(); userList.stream().forEach(user -> { System.out.println(user); }) } }
JDBC介绍 什么是JDBC JDBC :(J ava D ata B ase C onnectivity),就是使用Java语言操作关系型数据库的一套APl。
Sun公司官方定义的一套操作所有关系型数据库的规范,即接口。
各个数据库厂商去实现这套接口,提供数据库 驱动jar包
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
JDBC示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Class.forName("com/mysql.cj.jdbc.Driver" );String url = "jdbc:mysql://localhost:3306/mybatis" ;String username = "root" ;String password = "1234" ; Connection conn= DriverManager.getConnection(url,username,password); String sql= "select * from user" ; Statementstatement= conn.createstatement(); ResultSet resultSet= statement.executeQuery(sql); List<User> userList= new ArrayList <>();while (resultSet.next()){ int id = resultSet.getInt("id" ); String name = resultSet.getString("name ); short age = resuItSet.getShort(" age"); short gender= resultSet.getShort(" gender"); String phone = resultSet.getString(" phone"); Useruser= new user(id,name,age,gender,phone); userList.add(user); } //4.释放资源 statement.close(); connection.close();
数据库连接池 什么是数据库连接池?
数据库连接池是个容器,负责分配、管理数据库连接(Connection)
它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
当某用户从数据库连接池获取连接后,一段时间内该连接一直处于闲置状态,该连接会重回连接池。
连接池的优势
标准接口:DataSource
官方(sun)提供的数据库连接池接口,由第三方组织实现此接口。
功能:获取连接 Connection getConnection() throws SQLException
常见产品
C3P0
DBCP
Druid (德鲁伊)
Druid连接池是阿里巴巴开源的数据库连接池项目
功能强大,性能优秀,是Java语言最好的数据库连接池之一
Hikari (Springboot默认)
切换Druid数据库连接池 官方网址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
1 2 3 4 5 6 7 <dependency > <groupld > com.alibaba</groupld > <artifactld > druid-spring-boot-starter</artifactld > <version > 1.2.23</version > </dependency >
1 2 3 4 5 6 spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver spring.datasource.url = jdbc:mysql://localhost:3306/mybatis spring.datasource.username = root spring.datasource.password = 1234
Lombok 什么是Lombok?
Lombok是一个实用的Java类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。
@Getter/@Setter
——为所有的属性提供get/set
方法
@ToString
——会给类自动生成易阅读的toString
方法
@EqualsAndHashCode
——根据类所拥有的非静态字段自动重写equals
方法和hashCode
方法
@Data
——提供了更综合的生成代码
(@Getter
+@Setter
+@ToString
+@EqualsAndHashCode
)
@NoArgsConstructor
——为实体类生成 无参的构造器 方法
@AllArgsConstructor
——为实体类生成除了static修饰的字段之外 全参的构造器 方法
@Slf4j
——自动生成日志记录
在 Java 类上使用这个注解,Lombok 库会在编译时自动为该类添加一个 SLF4J(Simple Logging Facade for Java)日志变量,通常这个变量的名字是 log
。
1 2 3 4 5 6 7 8 9 import lombok.extern.slf4j.Slf4j;@Slf4j public class MyClass { public void doSomething () { log.info("Doing something..." ); } }
Lombok依赖文件 Lombok插件(较新版IDEA自带): Settings
->Plugins
1 2 3 4 5 6 <dependency > <groupId > org.projectlombok</groupId > <artifactId > lombok</artifactId > </dependency >
MyBatis增删改查 需求案例:员工管理的需求开发 环境准备
1 2 3 4 5 6 7 8 9 10 11 12 13 create table emp ( id int unsigned primary key auto_increment comment 'ID' , username varchar (20 ) not null unique comment '用户名' , password varchar (32 ) default '123456' comment '密码' , name varchar (10 ) not null comment '姓名' , gender tinyint unsigned not null comment '性别,说明:1 男,2 女' ) image varchar (300 ) comment '图像' , job tinyint unsigned comment '职位,说明:1 班主任,2 讲师,3 学工主管,4 教研主管 5 咨询师' , entrydate date comment '入职时间' , dept_id int unsigned comment '部门ID' , create_time datetime not null comment '创建时间' , update_time datetime not null comment '修改时间' , )comment '员工表' ;
创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok)
Lombok
、MySQL Driver
、MyBatis Framework
application.properties中引入数据库连接信息
1 2 3 4 5 6 spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver spring.datasource.url = jdbc:mysql://localhost:3306/mybatis spring.datasource.username = root spring.datasource.password = 1234
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Data @NoArgsConstuctor @AllArgsConstuctor public class Emp { private Integer id; private String username; private String password; private String name; private Short gender; private String image; private Short job; private LocalDate entrydate; private Integer deptId; private LocalDateTime createTime; private LocalDateTime updateTime; }
1 2 3 4 5 @Mapper public interface EmpMapper { }
增删改查 删除
根据主键ID删除
根据主键ID批量删除(动态SQL)
1 2 3 4 mybatis.configuration.log-impl = org.apache.ibatis.logging.stdout.StdOutImpl
1 2 3 4 5 6 7 8 9 @Mapper public interface EmpMapper { @Delete("delete from emp where id = #{id}") public int delete (Integer id) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @SpringBootTest class SpringbootMybatisCrudApplicationTests { @Autowired private EmpMapper empMapper; @Test public void testDelete () { int delete = empMapper.delete(17 ); System.out.println("根据ID删除数据的记录数:" +delete) } }
新增 1 2 3 4 5 6 7 8 9 10 11 @Mapper public interface EmpMapper { @Insert("insert into"+ "emp(username,name,gender,image,job,entrydate,dept_id,create_time,update_time)" +"values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})") public int insert (Emp emp) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @SpringBootTest class SpringbootMybatisCrudApplicationTests { @Autowired private EmpMapper empMapper; @Test public void testInsert () { Emp emp = new Emp (); emp.setUsername("Tom" ); ...... emp.setGender((short )1 ); emp.setEntrydate(LocalDate.of(2000 ,1 ,1 )); emp.setCreateTime(LocalDateTime.now()); emp.setUpdateTime(LocalDateTime.now()); empMapper.insert(emp); } }
新增 (主键返回)主键返回:在数据添加成功后,需要获取插入数据库数据的主键。
如:
先保存套餐信息,并获取套餐ID
再保存套餐菜品关联信息(需要记录套餐ID 、菜品ID)
1 2 3 4 5 6 7 8 9 10 11 12 @Mapper public interface EmpMapper { @Options(useGeneratedKeys = true,keyProperty = "id") @Insert("insert into"+ "emp(username,name,gender,image,job,entrydate,dept_id,create_time,update_time)" +"values(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})") public int insert (Emp emp) ; }
更新
1 2 3 4 5 6 7 8 9 @Mapper public interface EmpMapper { @Update("update emp set username = #{username},name = #{name},gender = #{gender},image = #{image},job = #{job},entrydate = #{entrydate},dept_id = #{deptId},update_time = #{updateTime} where id = #{id}") public int update (Emp emp) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @SpringBootTest class SpringbootMybatisCrudApplicationTests { @Autowired private EmpMapper empMapper; @Test public void testInsert () { Emp emp = new Emp (); emp.setId(18 ); emp.setUsername("Tom" ); ...... emp.setGender((short )1 ); emp.setEntrydate(LocalDate.of(2000 ,1 ,1 )); emp.setUpdateTime(LocalDateTime.now()); empMapper.update(emp); } }
查询 (根据主键ID查询)1 2 3 4 5 6 7 8 9 @Mapper public interface EmpMapper { @Select("select * from emp where id = #{id}") public Emp getById (Integer id) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @SpringBootTest class SpringbootMybatisCrudApplicationTests { @Autowired private EmpMapper empMapper; @Test public void testSelect () { Emp emp = empMapper.getById(20 ); System.out.println(Emp emp); } }
数据封装
1 @Select("select id,...,dept_id as deptId,create_time as createTime...")
1 2 3 4 5 6 7 @Results({ @Result(column = "dept_id",property = "deptId"), @Result(column = "create_time",property = "createTime"), @Result(column = "update_time",property = "updateTime") }) @Select("select * from emp where id = #{id}") public Emp getById (Integer id) ;
1 2 3 mybatis.configuration.map-underscore-to-camel-case = true
查询(根据条件查询)
根据输入的员工姓名、员工性别、入职时间搜素满足条件的员工信息。
其中员工姓名,支持模糊匹配;性别进行精确查询;入职时间进行范田查询。
支持分页查询。
并对查询的结果,根据最后修改时间进行倒序排序。
1 2 3 4 5 6 7 8 9 @Mapper public interface EmpMapper { @Select("select * from emp where name like concat('%',#{name},'%')) and gender = #{gender} and entrydate between #{begin} and #{end} order by update_time DESC") public List<Emp> list(String name,Short gender,LocalDate begin,LocalDate end); }
1 2 3 4 5 6 7 8 9 10 11 12 13 @SpringBootTest class SpringbootMybatisCrudApplicationTests { @Autowired private EmpMapper empMapper; @Test public void testList () { empMapper.list("张" ,(short )1 ,LocalDate.of(2010 ,1 ,1 ),LocalDate.of(2020 ,1 ,1 )); } }
XML映射文件 规范
XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。
创建包结构new directory
->com/dhu/mapper
src.main.java.com.mapper.EmpMapper
(Mapper接口)
src.main.resources.com.mapper.EmpMapper.xml
(XML映射文件)
XML映射文件的namespace属性为Mapper接口全限定名一致。
XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。
copy reference
1 2 3 4 5 6 @Mapper public interface EmpMapper { public List<Emp> list (String name,Short gender,LocalDate begin,LocalDate end) ; }
1 2 3 4 5 6 7 <mapper namespace ="com.dhu.mapper.EmpMapper" > <select id ="list" resultType ="com.itheima.pojo.Emp" > select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} and #{end} order by update_time desc </select > </mapper >
MybatisX
MybatisX是一款基于IDEA的快速开发Mybatis的插件,为效率而生。
Settings -> Plugins
跳转到对应的接口/方法
MyBatis动态SQL