MyBatis使用(helloworld)
helloworld测试
1. 导包
在官网下载jar包,
https://github.com/mybatis/mybatis-3
或者使用maven自动导包:如下
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
2. 创建mybatis_config.xml文件
示例(该示例从mybatis官方文档中复制,更改数据库配置):
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!- 数据库配置 ->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="111111"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
3.在mysql数据库中创建测试库、表以及测试数据
库名为:mybatis
CREATE TABLE tbl_employee(
id INT PRIMARY KEY AUTO_INCREMENT,
last_name VARCHAR(255),
gender CHAR(1),
email VARCHAR(255)
);
INSERT INTO tbl_employee(`last_name`,`gender`,`email`)VALUES(`tom`,`男`,`tom@qd.com`);
创建对应的javaBean
public class Employee {
private Integer id;
private String lastName;
private String gender;
private String email;
//toString方法
//get、set方法
//构造器
}
4.创建测试类
public class MyBatisTest {
@Test
public void testMyBatis() throws IOException {
//1、根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2、获取一个SqlSession实例,能直接执行已经映射的Sql语句
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//sql的唯一标识:statement Unique identifier matching the statement to use.
//执行sql要用的参数:parameter A parameter object to pass to the statement.
//配置文件见EmployeeMapper.xml
Employee employee = sqlSession.selectOne("com.szm.mybatis.EmployeeMapper.selectEmp", 1);
System.out.println(employee);
} finally {
//关闭SqlSession
sqlSession.close();
}
}
}
5.书写sql映射文件EmployeeMapper.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">
<mapper namespace="com.szm.mybatis.EmployeeMapper">
<!--
namespace:名称空间
id:唯一标识
resultType:返回值类型
#{id}:从传过来的参数中取出id值
-->
<select id="selectEmp" resultType="com.szm.mybatis.bean.Employee">
select * from tbl_employee where id = #{id}
</select>
</mapper>
6.执行第一次测试
报错,
更改全局配置文件
因此步骤非常重要,所以希望能先自行测试之后报错后再更改全局配置文件
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!- 数据库配置 ->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="111111"/>
</dataSource>
</environment>
</environments>
<!--将我们写好的sql映射文件一定要注册到全局配置文件中-->
<mappers>
<mapper resource="EmployeeMapper.xml"/>
</mappers>
</configuration>
7.执行第二次测试
控制台输出如下:
DEBUG 01-10 18:50:11,161 ==> Preparing: select * from tbl_employee where id = ? (BaseJdbcLogger.java:159)
DEBUG 01-10 18:50:11,202 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 01-10 18:50:11,226 <== Total: 1 (BaseJdbcLogger.java:159)
Employee{id=1, lastName='null', gender='男', email='tom@qd.com'}
发现lastName值为null,
原因是
mysql表中字段名为last_name
Javabean中的属性名为lastName
二者无法对应
解决方法为给字段取别名
更改sql映射文件中sql语句
<?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">
<mapper namespace="com.szm.mybatis.EmployeeMapper">
<!--
namespace:名称空间
id:唯一标识
resultType:返回值类型
#{id}:从传过来的参数中取出id值
-->
<select id="selectEmp" resultType="com.szm.mybatis.bean.Employee">
select `id`,`last_name` lastName,`gender`,`email` from tbl_employee where id = #{id}
</select>
</mapper>
8.执行第三次测试
控制台输出如下:
DEBUG 01-10 19:22:39,938 ==> Preparing: select `id`,`last_name` lastName,`gender`,`email` from tbl_employee where id = ? (BaseJdbcLogger.java:159)
DEBUG 01-10 19:22:39,985 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:159)
DEBUG 01-10 19:22:40,015 <== Total: 1 (BaseJdbcLogger.java:159)
Employee{id=1, lastName='tom', gender='男', email='tom@qd.com'}
测试成功
9.使用步骤总结
- 根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象
xml配置文件中包含了数据源等信息 - sql映射文件;配置了每一个sql,以及sql的封装规则
- 将sql映射文件注册在全局配置文件中
- 写代码:
- 根据全局配置文件得到SqlSessionFactory;
- 使用sqlSession工厂获取到sqlSession对象,使用它来执行增删改查
一个sqlSession就是代表和数据库的一次会话,用完关闭
- 使用sql的唯一标识来告诉MyBatis执行哪个sql。sql都是保存在sql映射文件中的。
优化helloworld(接口式编程)
1.优化的原因
在测试时发现
......
Employee employee = sqlSession.selectOne("com.szm.mybatis.EmployeeMapper.selectEmp", 1);
......
在传参数时,因为没有限定参数类型,那么就有可能查询错误,如下
......
Employee employee = sqlSession.selectOne("com.szm.mybatis.EmployeeMapper.selectEmp", "abc");
......
在数据库中,id字段为int类型,所以我们要让参数最好只能传入integer类型,
在mybatis中提供了对应的实现方式
2.编写EmployeeMapper接口(DAO)
示例:
public interface EmployeeMapper {
Employee getEmpById(Integer id);
}
3.改写EmployeeMapper.xml文件
namespace:名称空间;指定为接口的全类名,建立对应关系
id:唯一标识;指定为接口中对应的方法名,同样是为了建立对应关系
<?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">
<mapper namespace="com.szm.mybatis.dao.EmployeeMapper">
<!--
namespace:名称空间;指定为接口的全类名,建立对应关系
id:唯一标识;指定为接口中对应的方法名,同样是为了建立对应关系
resultType:返回值类型
#{id}:从传过来的参数中取出id值
-->
<select id="getEmpById" resultType="com.szm.mybatis.bean.Employee">
select `id`,`last_name` lastName,`gender`,`email` from tbl_employee where id = #{id}
</select>
</mapper>
4.编写测试类,进行测试
//将获取SqlSessionFactory的方法提取出来了
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testMyBatis1() throws IOException {
//1、获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
//2、获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//3、获取接口的实现类
//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
//4、调用接口中的方法
Employee employee = mapper.getEmpById(1);
//打印
System.out.println(employee);
} finally {
//关闭sqlSession
sqlSession.close();
}
}
控制台输出如下:
Employee{id=1, lastName='tom', gender='男', email='tom@qd.com'}
测试成功
总结
- 接口式编程
原生 DAO ===> DaoImpl mybatis Mapper ===> xxxMapper.xml - SqlSession代表和数据库的一次会话;用完必须关闭
- SqlSession和Connection一样都是非线程安全的。每次使用都应该去获取新的对象。
- mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。
(将接口和xml进行绑定)
EmployeeMapper empMapper = sqlSession.getMapper(EmployeeMapper.class);
- 两个重要的配置文件
- mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等。。。系统运行环境信息
- sql映射文件:保存了每一个sql语句的映射信息:将sql抽取出来。