一、什么是框架
框架是一个框子---指其约束性,也是一个架子---指其支撑性。
即已经对基础的的代码进行了封装并提供相应的API,开发者在使用框架时直接调用封装好的api可以省去很多代码的编写,从而提高工作效率和开发速度。
二、传统的jdbc代码问题
1、手动创建和连接
2、sql语句在代码中的硬编码
3、对结果的解析
三、mybatis框架概述
mybatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只关注sql本身,而不需要花费精力去处理例如注册驱动、创建connect、创建statement、手动设置参数、获取结果等jdbc繁杂的过程代码。
四、mybatis入门案例
1、pom.xml(添加依赖)
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
如果不添加此节点src/main/java目录下的所有配置文件都会被漏掉。
<build>
<!-- 如果不添加此节点src/main/java目录下的所有配置文件都会被漏掉。 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
添加实体类User
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
mapper包里面的Usermapper
public interface UserMapper {
public List<User> findAll();
}
UserMapper.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">
<!--namespace:隔离sql,一般是接口名称的全类名-->
<mapper namespace="com.by.dao.UserMapper">
<!--
id:和接口方法名保持一致
resultType:和接口返回类型保持一致
-->
<select id="findAll" resultType="com.by.pojo.User">
select * from user
</select>
</mapper>
注意:一般会把数据库配置信息定义在一个独立的配置文件里面,比如db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456
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>
<!--引入db.properties-->
<properties resource="db.properties"></properties>
<typeAliases>
<!--批量定义别名-->
<package name="com.by.pojo"></package>
</typeAliases>
<!-- 和spring整合后 environments配置将废除-->
<environments default="dev">
<!-- dev环境 -->
<environment id="dev">
<!-- 配置事务的类型:type="JDBC | MANAGED" 两种方式
JDBC:表示使用JDBC中原生的事务管理方式
MANAGED:被管理,例如Spring
-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源(连接池) -->
<dataSource type="POOLED">
<!-- mysql5 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
<package name="com.by.mapper"></package>
</mappers>
</configuration>
注意:mybatis5的driver和url
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=UTF-8"/>
测试:
public class MyBatisTest {
private InputStream inputStream;
private SqlSession sqlSession;
@Before
public void createSqlSession() throws IOException {
// 加载配置文件
inputStream = Resources.getResourceAsStream("mybatis- config.xml");
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
//获得数据库会话实例
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void testFindAll(){
UserDao userDao = sqlSession.getMapper(UserMapper.class);
List<User> userList = userDao.findAll();
for(User user : userList) {
System.out.println(user);
}
}
@After
public void closeSqlSession() throws IOException {
sqlSession.close();
inputStream.close();
}
}
五、mybatis的运行原理
mybatis-config.xml
mapper.xml mapper.xml mapper.xml
|
|
Resources
|
| --->inputStream
|
SqlSessionFactoryBuilder
|
|---->Configuration(conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>)
|
SqlSessionFactory
|
|---->Configuration(conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>)
|
SqlSession
|
|---->conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>
|
ProxyFactory
|
|---->MappedStatement(sql, resultType), conn
|
Executor
| |
| |
| |
输出映射
七、mybatis的CRUD
1、查询
①单个参数绑定
//单个参数传递
public User findUserById(Integer id);
<!--
parameterType:指定输入参数的类型
resultType:指定数据结果封装的数据类型
#{id}:它代表占位符,相当于原来 jdbc 部分所学的?,都是用于替换实际的数据。
-->
<select id="findUserById" parameterType="java.lang.Integer"
resultType="com.by.pojo.User" >
select * from user where id=#{id}<!--只有一个参数时,#{任意书写}-->
</select>
@Test
public void testFindUserById(){
UserDao userDao = sqlSession.getMapper(UserMapper.class);
User user = userDao.findUserById(41);
System.out.println(user);
}
②序号参数绑定
③注解参数绑定
④对象参数绑定
⑤Map参数绑定
⑥模糊查询
⑦聚合函数查询
2、删除
3、修改
4、添加
主键回填
①方法1
②方法2
八、mybatis的ORM映射
MyBatis只能自动维护库表”列名“与”属性名“相同时的对应关系,二者不同时无法自动ORM
①起别名
②结果映射 (ResultMap)
九、mybatis的关联查询
①一对一
一个账户信息只能供某个用户使用,所以从查询账户信息出发关联查询用户信息为一对一查询。
在实体类中加入user属性
AccountMapper
AccountMapper.xml
②一对多
查询所有用户信息及用户关联的账户信息。
实体类中添加account类
③多对多
查询角色及角色赋予的用户信息。