mybatis
1.传统的jdbc
加载驱动
获取链接connection
获取预处理对象statement
设置sql (采用占位符,防止sql注入)
给占位符设置值
执行获取结果集
对结果集进行封装
释放资源
问题:
- 频繁的创建链接、释放资源 造成了系统资源的浪费。 --> 数据库连接池
- sql语句在java代码中,造成后期维护不易。
- 占位符设置值 存在硬编码。where语句里条件不固定,造成维护不易
SELECT * FROM user WHERE 1=1 AND id =’’ AND name LIKE ’%x%’ AND age =11
If(id != null){
Sql += “ and id=’’ ”
}
If(name != null){
Sql += “ and name like ‘’ ”
}
4. 对结果集的解析封装 存在硬编码
不用框架的话,我们完全可以自己实现这种封装。反射思想。(数据表的元信息)
表User —>name
实体类:User.java name setName getName ||
name(规则:列名首字母大写Name,再加上set或get前缀“setName”。通过反射获取实体类中的setName()方法)
name 列值:张三
获取表中name的值:操作User实体类,getName方法,通过表的元信息的映射获取user的name的值。
(实体类和Map是可以相互转化的,非常简单方便。)
List --> List
4.mybatis环境搭建
1.新建java项目,项目名:mybatis01,导入jar包 mybatis-3.2.7.jar junit
2.配置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
3.配置mybatis全局配置文件(mybatis.xml)
public class MybatisConnectionTest {
public static void main(String[] args) throws IOException {
//1.加载mybatis运行环境,io流的方式去读取配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");// 项目的(编译之后的)根路径
//2.获取工厂类,作用:完成数据库操作会话。长连接
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.操作数据库
SqlSession session = sqlSessionFactory.openSession();
System.out.println(session);// 相当于connection
//4.释放数据库
session.close();
}
}
5.入门案例
0、在数据库中创建测试表user。
CREATE TABLE user
(
id
int(11) NOT NULL AUTO_INCREMENT,
username
varchar(32) NOT NULL COMMENT ‘用户名称’,
birthday
date DEFAULT NULL COMMENT ‘生日’,
sex
char(1) DEFAULT NULL COMMENT ‘性别’,
address
varchar(256) DEFAULT NULL COMMENT ‘地址’,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
INSERT INTO user
(username,birthday,sex,address) VALUES (‘jack1’, ‘2019-03-20’, ‘男’, ‘上海’);
INSERT INTO user
(username,birthday,sex,address) VALUES (‘jack2’, ‘2019-03-20’, ‘男’, ‘上海’);
INSERT INTO user
(username,birthday,sex,address) VALUES (‘jack3’, ‘2019-03-20’, ‘男’, ‘上海’);
1、 pojo对象 User.java
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
.......
- 映射文件UserMapper.xml<?xml version="1.0" encoding="UTF-8"?>
- 配置映射mybatis.xml文件
<!-- 加载映射文件 -->
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
3、简单测试
4、单元测试
定义单例工厂类:
单元测试UserMTest.java:
6.会话工厂与会话
SqlSessionFactory: 会话工厂。通过全局配置文件创建的,由SqlSessionFactoryBuild对象创建。
作用:创建会话。
特点:会话工厂一旦创建,就会在应用程序的执行期间一直存在。我们就不需要重复的来创建这个 会话工厂了。所以我们应该 把它的实现方式设计为 单例模式的。
SqlSession: 会话。 作用:操作数据库。
特点:线程不安全的。应该把会话声明为局部的。
7.全局配置文件的其他配置
起别名mybatis.xml配置文件中:
<typeAliases>
<!-- type: 指的是要被定义别名的类 的全限定名
alias: 自定义的别名-->
<!-- <typeAlias type="com.cbb.pojo.User" alias="user"/> -->
<!-- 批量起别名 name:包。
会扫描配置的包下的所有的类然后 批量的起别名。 别名为 类名(首字母大写或者小写都可以)-->
<package name="com.cbb.pojo"/>
</typeAliases>
使用,可把resultType="com.cbb.pojo.User"替换为resultType=“user”:
select * from user where id = #{id}
-----》
select * from user where id = #{id}
通常使用,直接使用类名作为别名。
作业
我爱登录的t_user表 新增、修改、删除、 查询(根据名字模糊查询、查询出生日在2010年~2019年中间的用户,并且2010和2019是通过占位符设置)
8.传统的dao开发方法
新建项目,项目名:mybatis02
dao接口 daoImpl实现 映射文件
优化数据库配置mybatis.xml
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
9.动态代理实现方式
新建项目,项目名:mybatis03
Mapper 接口开发方法只需要程序员编写 Mapper 接口(相当于 Dao 接口),
由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边 Dao 接口实现类方法。
规范要求: 1.mapper.xml映射文件 和 mapper接口的名字 必须一致。 2.mapper.xml映射文件的 namespace 与 接口 的类全路径相同 3.mapper.xml映射文件的 statement的id 与 接口的方法名相同 4.mapper.xml映射文件 的参数类型parameterType 与 接口方法的 参数类型相同 5.mapper.xml映射文件 的输出结果类型 与 接口方法的 返回类型相同
9.1 parameterType(输入类型)
• java简单类型 int、String #{占位符的方式,任意字符}
• pojo自定义对象 #{pojo的属性名}
• hashmap类型 #{map的key}
9.4 复杂映射问题
resultMap: 除了能够解决上述的 名字不一致的问题外,还可以解决映射复杂的pojo 问题,比如一对多的关系。
参考:(扩展知识,不做掌握)
9.5 动态sql
通过mybatis提供的各种标签方法实现动态拼接sql。
9.6 示例
0、mybatis环境搭建,参考4。
省略。
1、数据表关系,增加car表。
CREATE TABLE car
(
carId
int(11) NOT NULL AUTO_INCREMENT,
name
varchar(255) DEFAULT NULL,
userId
varchar(255) DEFAULT NULL,
PRIMARY KEY (carId
)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
2、增加car表对应的实体类Car。
public class Car {
private int carId;
private String carName;//汽车的名字,属性名 与表字段名不一致
private int userId;
.....
拷贝User类
3、创建dao接口
dao接口:CarMapper.java UserMapper.java
CarMapper.java
4、在com.cbb.mapper包下,创建映射文件
CarMapper.xml
UserMapper.xml
CarMapper.xml
resultMap对应的VO类:UserVo.java
public class UserVo extends User{
private List<Car> cars;//一对多 一个人可能会有 多个汽车
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
}