案例需求:
通过mybatis查询数据库user表的所有记录,封装到User对象中,打印到控制台上
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` datetime default NULL COMMENT '生日',
`sex` char(1) default NULL COMMENT '性别',
`address` varchar(256) default NULL COMMENT '地址',
PRIMARY KEY (`id`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into
`user`(`id`,`username`,`birthday`,`sex`,`address`)
values
(1,'张三','2020-11-11 00:00:00','男','北京海淀'),
(2,'李四','2020-12-12 00:00:00','男','北京海淀');
17
17
UTF-8
UTF-8
org.mybatis
mybatis
3.5.4
mysql
mysql-connector-java
5.1.6
runtime
junit
junit
4.12
//编写实体类 对应映射User表
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
public User() {
}
public User(int id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
ORM(Object Relational Mapping)对象关系映射
O(对象模型):
实体对象,即我们在程序中根据数据库表结构建立的一个个实体javaBean
R(关系型数据库的数据结构):
关系数据库领域的Relational(建立的数据库表)
M(映射):
从R(数据库)到O(对象模型)的映射,可通过XML文件映射
实现:
(1)让实体类和数据库表进行一一对应
先让实体类和数据库表对应
再让实体类属性和表里面字段对应
(2)不需要直接操作数据库表,直接操作表对应的实体类对象
mybatis采用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作
insert into user (username, sex , birthday , address)
values(#{username} , #{sex}, #{birthday}, #{address})
update user set username = #{username} , birthday = #{birthday} , sex = #{sex} , address = #{address} where id = #{id}
delete from user where id = #{id}
映射文件根标签mapper: (1)namespace:命名空间 一个项目中会有很多映射文件 (2)namespace.id ==》 可以准确定位到项目中唯一的一条sql语句
select:表示查询 命名空间中 可以写多个标签 id:用于区分同一个命名空间的不同标签 resultType:用于指定sql语句的查询结果所对应的实体类对象 标签中间:定义具体的sql
insert:新增 #{}:表示占位符 parameterType : 指定参数 对应的实体类对象
update:修改 delete:删除
新增、修改、删除用parameterType,查询用resultType
‘
SqlMapConfig.xml
加载外部的配置文件:
别名处理器 可以将原来的java类型 起个别名 不区分大小写:
type : 指定要起别名的全路径类名 alios : 指定新的别名
环境配置:
default:指定默认的环境名称
id 表示当前环境的名称
使用JDBC类型事务管理器 type="JDBC":指定事物的类型 JDBC JDBC:使用了JDBC的提交和回滚 依赖于数据源的链接管理事务 MANAGED:基本上啥也不干 将事务交给容器来管理,比如Spring容器
使用连接池 type="POOLED": 指定当前数据库的链接 直接从连接池中获取 type="UNPOLLED" ,不使用连接池 , 每次都是获取新的连接 type=”JNDI“,支持将数据源 集中配置到 外部 ,使用JNDI类型的变量去引用
加载映射配置文件
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1
jdbc.username=root
jdbc.password=18270139613
实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件
package com.qiku.test;
import com.qiku.pojo.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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MyTest {
// 测试查询所有user
@Test
public void testFindAllUser() throws IOException {
// 1.加载核心配置文件
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2.获取sqlSessionFactory 工厂对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);
// 3.获取session 会话对象
SqlSession sqlSession = factory.openSession();
// 4.执行sql
List list = sqlSession.selectList("UserMapper.findAll");
for (User user : list){
System.out.println(user);
}
// 5.释放资源
sqlSession.close();
}
// 测试新增用户
@Test
public void testAddUser() throws IOException {
// 1.加载核心配置文件 存入 输入流resource
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
// 根据输入流 resource 创建工厂 factory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);
// 2.根据factory工厂 获取会话(表示一个数据库) sqlSesion
// true : 表示自动提交事务
SqlSession sqlSession = factory.openSession(true);
// 准备插入一个数据
User user = new User();
user.setUsername("hhh");
user.setBirthday(new Date());
user.setAddress("zz");
user.setSex("女");
// 3.通过sqlSesion执行sql(通过namespace,id定位SQL语句)
int i = sqlSession.insert("UserMapper.addUser", user);
// 4.提交事务(上面写true这里就不用写了)
// sqlSession.commit();
// 5.释放资源
sqlSession.close();
}
// 测试修改用户
@Test
public void testUpdateUser() throws IOException {
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);
SqlSession sqlSession = factory.openSession();
// 准备数据
User user = new User();
user.setUsername("哈哈哈");
user.setBirthday(new Date());
user.setAddress("黑呵呵");
user.setSex("女");
// 修改id=5的数据
user.setId(5);
int update = sqlSession.update("UserMapper.updateUser", user);
System.out.println(update);
// 增删改操作需要提交事务
sqlSession.commit();
sqlSession.close();
}
// 删除用户
@Test
public void testDeleteUser() throws IOException {
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
SqlSession sqlSession = sqlSessionFactory.openSession();
int delete = sqlSession.delete("UserMapper.deleteUser", 5);
System.out.println(delete);
sqlSession.commit();
sqlSession.close();
}
// 根据ID查询用户
@Test
public void testFindUserById() throws IOException {
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);
SqlSession sqlSession = factory.openSession();
User user = sqlSession.selectOne("UserMapper.findUserById", 1);
System.out.println(user);
}
}
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resource);
SqlSession sqlSession = factory.openSession();
actory.openSession():手动提交
actory.openSession(true):自动提交
上面三步一定一定一定要记住
List list = sqlSession.selectList("UserMapper.findAll");
如果是添加、修改功能则需要在 4.执行sql 之前定义你要的功能,视情况而定
反正需要添加功能就写在3、4步之间
sqlSession.close();
注:增删改操作需要提交事务(写在sqlSession.close();前面):
sqlSession.commit();
要是前面设置为自动提交就不用写
MyBatis核心配置文件层级关系
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
配置文档的顶层结构如下
MyBatis常用配置解析
数据库环境的配置,支持多环境配置
事务管理器(transactionManager)类型有两种:
JDBC: 这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
MANAGED: 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。 例如:mybatis与spring整合后,事务交给spring容器管理。
数据源(dataSource)常用类型有三种:
UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
POOLED: 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
JNDI : 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据 源,然后放置一个 JNDI 上下文的数据源引用
实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的
类型别名是为 Java 类型设置一个短的名字。
为了简化映射文件 Java 类型设置,mybatis框架为我们设置好的一些常用的类型的别名:
该标签的作用是加载映射的,加载方式有如下几种:
1. 使用相对于类路径的资源引用,例如:
2. 使用完全限定资源定位符(URL),例如:
《下面两种mapper代理开发中使用:暂时了解》
3. 使用映射器接口实现类的完全限定类名,例如:
4. 将包内的映射器接口实现全部注册为映射器,例如: