本文是学习JavaEE开发的记录笔记
大纲
MyBatis
ORM(Object Relational Mapping,对象关系映射):是一种使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中,为了解决面向对象与关系数据库存在互不匹配现象的技术
JDBC(Java DataBase Connectivity,Java数据库连接):是一组使用Java语言编写的类和接口用于执行SQL语句为多种数据库提供统一访问
MyBatis:是由apache的开源项目iBatis迁移到google code改名形成,是一个实现ORM规则、对JDBC进行封装、基于Java的持久层框架
MyBatis入门示例
- 使用Maven构建项目
- 在pom.xml中添加MyBatis依赖:
- 创建数据库表:我这里使用以前项目的数据库,数据库名为mt,数据表为mt_product
- 数据表结构如下
- 数据表结构如下
- 创建入门示例包:在src/main/java下创建dao包
- 在src/main/java/dao/下创建pojo包存储实体类:
- POJO(Plain Ordinary Java Object,简单Java对象):是一种实体类,类中的属性与数据库表中的字段对应,类中的方法为每个属性的getter/setter方法,在MyBatis框架中通过关联的XML文件使实体类对象与数据库中的表对应,对象属性与表中字段相对应
- 在dao/pojo/下创建对应数据表mt_product的实体类Product.java
- 在src/main/resources创建MyBatis配置文件[mybatis-config.xml]:
- 配置文件格式可在MyBatis中文官网查看
- 配置文件及相关标签解释如下
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
28
29
30
31
32
33
34
35<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义pojo包路径 映射文件resultType中可直接指定实体类名-->
<typeAliases>
<package name="dao.pojo"/>
</typeAliases>
<!--定义数据源 development表示生产环境 可通过多个<environment>标签配置多个环境下的数据源-->
<environments default="development">
<environment id="development">
<!--事务管理 JDBC自身事务管理-->
<transactionManager type="JDBC"/>
<!--连接池参数配置-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mt?useUnicode=true&characterEncoding=utf-8&useSSL=true"/>
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<!--映射文件-->
<mappers>
<!--配置路径-->
<mapper resource="mapper/ProductMapper.xml"/>
</mappers>
</configuration>
- 在src/main/resources下创建mapper包存储映射文件
- 创建实体类Product与数据表mt_product的映射文件ProductMapper.xml
- 映射文件格式同样可在MyBatis中文官网查看
- 映射文件及相关解释如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<?xml version="1.0" encoding="UTF-8" ?>
<!--namespace对应实现映射的接口类名-->
<mapper namespace="dao.mapper.ProductMapper">
<!--SQL映射语句-->
<!--参数id为实现这个SQL语句的接口的方法名-->
<!--参数parameterType为传入参数#{}类型-->
<!--参数resultType为返回类型一般为对应的pojo实体类 resultType一般为全名引用 若想直接使用需要在mybatis-config.xml下定义包-->
<select id="selectProduct" parameterType="int" resultType="Product">
select * from mt_product where id = #{id}
</select>
<!--其他SQL映射语句-->
<!--<insert id=""></insert>-->
<!--<delete id=""></delete>-->
<!--<update id=""></update>-->
</mapper>
- 在src/main/java/dao/下创建mapper包存储映射接口
- 在dao/mapper/下创建调用映射的接口ProductMapper
- 调用映射的接口包含对应SQL映射语句的方法,如上的映射语句对应如下的接口
- 在src/main/java/dao下创建util包存储工具类
- 在dao/util/下创建工具类GetSqlSessionFactory.java用于得到SQLSession对象
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
28
29
30
31
32
33
34
35
36
37
38
39package dao.util;
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 java.io.IOException;
import java.io.Reader;
public class GetSqlSessionFactory {
//SQL会话工厂对象
private static SqlSessionFactory sqlSessionFactory=null;
//静态代码块 用于读取配置文件创建SQL会话工厂对象
static{
try
{
//rs存储MyBatis配置文件路径
String rs="mybatis-config.xml";
Reader reader=null;
//读取配置文件存储在reader中
reader = Resources.getResourceAsReader(rs);
//根据reader创建SQL会话工厂对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e)
{
e.printStackTrace();
}
}
//通过SQL会话工厂对象打开一个SQL会话用于调用接口实现SQL语句
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
//私有构造方法 禁止外界创建SQL会话工厂对象
private GetSqlSessionFactory(){}
}
- 在dao/util/下创建工具类GetSqlSessionFactory.java用于得到SQLSession对象
- 在src/test/java下创建dao.mapper包用于测试接口
- 添加junit依赖
- 在dao.mapper下创建测试类ProductMapperTest测试ProductMapper接口
- 在测试类ProductMapperTest下创建testSelectProduct测试方法并添加@Test注解测试ProductMapper接口中的selectProduct方法
- 执行结果如下
dao.mapper.ProductMapper
不使用接口执行SQL映射语句
在入门示例中我们使用接口ProductMapper绑定了映射文件ProductMapper.xml,在测试用例中我们通过工具类获取SQL会话,通过SQL会话的反射机制获得ProductMapper接口的对象,从而调用接口对象的方法执行SQL映射语句
然而还有一种不使用接口执行SQL映射语句,不需要编写接口直接使用映射文件ProductMapper.xml,通过其mapper标签的namespace属性指定xml映射文件,之后通过SQL会话的方法通过传入namespace.SQL映射语句id的方式执行SQL映射语句
- 指定ProductMapper.xml的mapper标签的namespace属性:如test
- 测试用例中使用namespace.SQL映射语句id形式执行SQL映射语句:
- 执行结果如下
- 执行结果如下
数据库列名和pojo属性名不一致
若数据库列名和pojo属性名不一致,会造成查询的数据存储不到pojo实体类对象中,造成某些属性值为null
解决方案有两种:
- 别名:
- 将pojo中的sid属性名改为test属性名
- 直接查询会出现pojo实体中test属性为null
- 在SQL映射语句中的使用as语法将数据库列名转换为pojo属性名
- 此时执行查询会将数据库列名sid的值存储在pojo属性名test中
- 将pojo中的sid属性名改为test属性名
- ResultMap:
- 在ProductMapper.xml定义ResultMap标签:
- 在SQL映射语句中的resultMap属性指定ResultMap使用的标签:
- 测试用例中使用新的SQL映射语句
- 执行结果如下
- 在ProductMapper.xml定义ResultMap标签:
模糊查询(SQL映射语句#/$传参)
- 使用#{}占位符传参形式,则使用?为占位符替换#{},无法在SQL语句中添加%
- 使用${}字符串拼接传参形式,则可以在SQL语句中直接添加%,用$传参需要注意
- 若参数为字符串类型,需要在SQL语句中添加单引号’’包围${}
- 参数为一个且为简单类型必须使用value
- 参数为表名或者列名必须使用$传参
多参数传递
- 接口中使用注解@Param(value=””)
- SQL映射语句中的#{}值与接口中@Param的value值相对应
- XML
- 接口
- 测试类中使用Map传递参数
- SQL映射语句中的#{}值与Map中的KEY相对应
- XML
- 接口
- 测试类
SQL插入语句
- SQL映射语句XML
- 接口:返回值为影响行数
- 测试类:注意需要提交事务才能插入生效
- 获取自增ID
- 在SQL映射语句中配置useGeneratedKeys和keyProperty属性,MyBatis会在插入操作后将自增id放入被插入的实体类中
- 在SQL映射语句中配置useGeneratedKeys和keyProperty属性,MyBatis会在插入操作后将自增id放入被插入的实体类中