mybatis3.2.7 原理和入门程序
使用jdbc操作数据库有以下缺点
|--数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁开启和关闭,造成数据源资源浪费,影响数据库性能。
设想:使用数据库连接池管理数据库连接。
|--将sql语句硬编码到Java代码中,如果sql语句修改,需要重新编译Java源码,不利于系统维护。
设想:将sql语句配置在xml文件中,即使sql变化,不需要对Java代码进行重新编译
|--向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码,不利于系统维护。
设想:将sql语句和占位符号和参数 全部配置在xml文件中
|--从resultSet中遍历结果集resultSet时,存在硬编码,将获取表的字段进行硬编码,不利于系统维护。
设想:将查询的结果集,自动映射成Java对象。
1.mybaits是什么?
1.1 mybatis是一个持久层框架,是Apache下的顶级框架。后来托管到googlecode下面,再后来托管到github下。
1.2 mybatis让程序员主要把精力放在sql上,通过mybaits提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql) 满足需求的sql语句。
1.3 mybatis可以将向preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象(输出映射)。
2.mybaits原理
2.1 SqlMapConfig.xml(是mybatis的全局配置文件,名称是不固定的)
配置了数据源、事务等mybaits环境
配置映射文件(配置sql语句) mapper.xml mapper.xml ....
2.2 SqlSessionFactory(会话工厂),根据配置文件创建工厂
作用:创建SqlSession
2.3 SqlSession(会话):是一个接口,面向用户(程序员)的接口
作用:操作数据库(发出sql 增、删、改、查)
2.4 Executor(执行器):是一个接口(基本执行器、缓存执行器)
作用:SqlSession通过执行器操作数据库
2.5 mapper statement(底层封装对象)
作用:对操作数据库进行存储封装,包括sql语句、输入参数、输出结果类型。
--输入参数类型: Java简单类型、hashmap、pojo自定义
--输出结果类型: java简单类型、hashmap、pojo自定义
2.6 数据库
3. mybaits的jar包 3.2.7版本
https://github.com/mybatis/mybatis-3/releases
lib下: 依赖包 log4j日志包 cglib.jar(动态代理的jar包)
mybaits-3.2.7.jar : 核心包
数据库驱动包
示例代码
1. sql-map-config.xml
<configuration>
<!--和Spring整合以后,environments配置将废除-->
<environments default="development">
<environment id="development">
<!--使用jdbc事物管理,事务由mybatis控制-->
<transactionManager type="JDBC">
<!--数据库连接池,由mybatis控制-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environments>
<!--加载配置文件mapper.xml-->
<mappers>
<mapper resource="sqlmap/user.xml"/>
<mapper resource="sqlmap/user-mapping.xml"/>
</mappers>
</configuration>
2. user-mapping.xml
namespace命名空间,作用就是对sql进行分类管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有着特殊重要的作用
<mapper namespace="test">
<!-- 在映射文件中配置很多的sql语句
需求:通过id查询用户表的记录 通过select语句执行数据库查询
id:标识映射文件中的sql 将sql语句封装到mapperStatement中去,所以将id称为statement的id
parameterType;指定输入参数的类型,这里指定int类型
#{}表示一个占位符号
#{id}:其中的id表示接收输入的参数,参数名称就是id,如果输入参数是简单数据类型,参数名称可以任意命名,比如value或者其他名称。
resultType:指定sql输出结果的所映射的Java对象类型,select指定resultMap表示将单条记录映射成java对象。 -->
<select id="findUserById" parameterType="int" resultType="cn.itcast.po.User">
select * from user where id = #{id}
</select>
<!-- 需求:根据用户名称迷糊查询用户信息,可能返回多条
resultType:指定就是单条记录所映射的java对象类型
${}: 表示拼接sql串,将接收到参数的内容不添加任何修饰,拼接在sql中 ==>${}拼接sql,就会引起一个问题,sql注入
${value}:接收输入参数的类型,如果传入类型是简单类型,${}中只能使用value. -->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.po.User">
select * from user where name like '%${value}%'
</select>
<!-- 添加用户,返回插入数据的主键值(MySQL/Oracle)
parameterType:指定输入参数pojo数据类型(包括用户信息)
#{}: 指定pojo的属性名,接收到pojo的对象的属性值。mybatis通过OGNL获取对象的属性值 -->
<insert id="insertUser" parameterType="cn.itcast.po.User">
<!--1. MySQL 自增主键返回 -->
<!--将插入数据的主键返回,返回到User对象中
Select LAST_INSERT_ID():得到刚刚insert进去记录的值,只适用于mysql自增主键
keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order: Select LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType:指定Select LAST_INSERT_ID()的结果类型 -->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
Select LAST_INSERT_ID();
</selectKey>
insert into user(name, age, sex, birthday)
values(#{name}, #{age}, #{sex}, #{birthday})
<!--2. MySQL 非自增主键返回:使用mysql的uuid()生成主键
执行过程:首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行之前,从user对象中取出id的属性值 -->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
Select UUID();
</selectKey>
insert into user(id, name, age, sex, birthday)
values(#{id}, #{name}, #{age}, #{sex}, #{birthday}) -->
<!--3. ORACLE 主键返回:通过oracle的序列生成主键
执行过程:首先通过 序列名.nextVal 得到主键,将主键设置到user对象的id属性中
其次在insert执行之前,从user对象中取出id的属性值 -->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
Select 序列名.nextval;
</selectKey>
insert into user(id, name, age, sex, birthday)
values(#{id}, #{name}, #{age}, #{sex}, #{birthday}) -->
</insert>
<!-- 根据id删除用户 -->
<delete id="deleteUserById" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
<!-- 根据id更新用户 分析:需要传入用户的id
需要传入用户的更新信息
parameterType: 指定user对象,包括id和更新信息,注意:id 必须存在
#{id} : 从输入user对象中获取id属性值 -->
<update id="updateUserById" parameterType="cn.itcast.po.User">
update user
set name = #{name}, age = #{age}, sex = #{sex}, birthday = #{birthday}
where id = #{id}
</update>
</mapper>
3. 测试代码
1 public void findUserByIdTest(){
2 //mybatis配置文件
3 String resource = "sqlMapConfig.xml";
4
5 //得到配置文件流
6 InputStream inputStream = Resources.getResourceAsStream(resource);
7
8 //创建会话工厂,传入mybatis的配置文件信息
9 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
10
11 //通过工厂得到sqlSession
12 SqlSession sqlSession = sqlSessionFactory.openSession();
13
14 //通过sqlSession操作数据库
15 //第一个参数:映射文件中statement的id,命名规则: namespace + "." + statement的id
16 //第二个参数:指定和映射文件中所匹配的parameterType类型的参数
17 //sqlSession.selectOne结果是与映射文件中匹配的resultType类型的对象
18 User user = sqlSession.selectOne("test.findUserById", 1);
19
20 System.out.println(user);
21
22 //释放资源
23 sqlSession.close();
24 }
25
26
27 public void findUserByNameTest(){
28 //mybatis配置文件
29 String resource = "sqlMapConfig.xml";
30
31 //得到配置文件流
32 InputStream inputStream = Resources.getResourceAsStream(resource);
33
34 //创建会话工厂,传入mybatis的配置文件信息
35 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
36
37 //通过工厂得到sqlSession
38 SqlSession sqlSession = sqlSessionFactory.openSession();
39
40 //通过sqlSession操作数据库
41 //list中的User和映射文件中resulType所指定的类型一致
42 List<User> users = sqlSession.selectList("test.findUserByName", "小明");
43
44 System.out.println(users);
45
46 //释放资源
47 sqlSession.close();
48 }
49
50
51 public void insertUserTest(){
52 //mybatis配置文件
53 String resource = "sqlMapConfig.xml";
54
55 //得到配置文件流
56 InputStream inputStream = Resources.getResourceAsStream(resource);
57
58 //创建会话工厂,传入mybatis的配置文件信息
59 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
60
61 //通过工厂得到sqlSession
62 SqlSession sqlSession = sqlSessionFactory.openSession();
63
64 //插入用户对象
65 User user = new User();
66 user.setName("小明");
67 user.setAge(24);
68 user.setSex("女");
69 user.setBirthday(new Date());
70
71 sqlSession.insert("test.insertUser", user);
72
73 //提交事务
74 sqlSession.commit();
75
76 //获取用户信息主键
77 System.out.println(user.getID());
78
79 //释放资源
80 sqlSession.close();
81 }
82
83 public void deleteUserTest(){
84 //mybatis配置文件
85 String resource = "sqlMapConfig.xml";
86
87 //得到配置文件流
88 InputStream inputStream = Resources.getResourceAsStream(resource);
89
90 //创建会话工厂,传入mybatis的配置文件信息
91 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder.build(inputStream);
92
93 //通过工厂得到sqlSession
94 SqlSession sqlSession = sqlSessionFactory.openSession();
95
96 //根据用户id删除用户
97 sqlSession.delete("test.deleteUserById", 4);
98
99 //提交事务
100 sqlSession.commit();
101
102 //释放资源
103 sqlSession.close();
104 }
105
106
107 public void updateUserTest(){
108 //mybatis配置文件
109 String resource = "sqlMapConfig.xml";
110
111 //得到配置文件流
112 InputStream inputStream = Resources.getResourceAsStream(resource);
113
114 //创建会话工厂,传入mybatis的配置文件信息