MyBatis-02
一、Mybatis实现CURD(重点)
1. 准备Mybatis环境
- 创建Maven的Java项目,坐标为:
<groupId>com.viking</groupId>
<artifactId>mybatis02_curd</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
- 在pom.xml中添加依赖:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
- 创建JavaBean
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//get/set方法...
//toString方法...
}
- 创建映射器接口IUserDao
public interface IUserDao {
}
- 创建映射配置文件IUserDao.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.viking.dao.IUserDao">
</mapper>
- 创建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="mysql_mybatis">
<environment id="mysql_mybatis">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/viking/dao/IUserDao.xml"/>
</mappers>
</configuration>
- 编写单元测试类
public class MybatisCURDTest {
private InputStream is;
private SqlSession session;
private IUserDao dao;
@Before
public void init() throws IOException {
is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
session = factory.openSession();
dao = session.getMapper(IUserDao.class);
}
@After
public void destory() throws IOException {
session.commit();
//7. 释放资源
session.close();
is.close();
}
}
2. 查询所有用户:略
3. 保存/新增用户
3.1 在映射器IUserDao中增加方法
void save(User user);
3.2 在映射配置文件中添加配置信息
<!--parameterType:是方法的参数类型,写全限定类名-->
<insert id="save" parameterType="com.viking.bean.User">
<!--
selectKey标签:用于向数据库添加数据之后,获取最新的主键值
resultType属性:得到的最新主键值的类型
keyProperty属性:得到的最新主键值,保存到JavaBean的哪个属性上
order属性:值BEFORE|AFTER,在insert语句执行之前还是之后,查询最新主键值。MySql是AFTER
-->
<selectKey resultType="int" keyProperty="id" order="AFTER">
select last_insert_id()
</selectKey>
insert into user (id, username, birthday, address, sex)
values (#{id}, #{username}, #{birthday},#{address},#{sex})
</insert>
注意:
SQL语句中#{}代表占位符,相当于预编译对象的SQL中的?,具体的值由User类中的属性确定
3.3 编写测试代码
@Test
public void testSaveUser(){
User user = new User();
user.setUsername("Tom");
user.setAddress("广东深圳");
user.setBirthday(new Date());
user.setSex("男");
System.out.println("保存之前:" + user);//保存之前,User的id为空
dao.save(user);
session.commit();//注意:必须要手动提交事务
System.out.println("保存之后:" + user);//保存之后,User的id有值
}
注意:执行了DML语句之后,一定要提交事务:session.commit();
4. 修改用户
4.1 在映射器IUserDao中增加方法
void edit(User user);
4.2 在映射配置文件中添加配置信息
<update id="edit" parameterType="com.viking.bean.User">
update user set username = #{username}, birthday = #{birthday},
address = #{address}, sex = #{sex} where id = #{id}
</update>
4.3 编写测试代码
@Test
public void testEditUser(){
User user = new User();
user.setId(50);
user.setUsername("Jerry");
user.setAddress("广东深圳宝安");
user.setSex("女");
user.setBirthday(new Date());
dao.edit(user);
session.commit();
}
5. 删除用户
5.1 在映射器IUserDao中增加方法
void delete(Integer id);
5.2 在映射配置文件中增加配置信息
<delete id="delete" parameterType="int">
delete from user where id = #{id}
</delete>
注意:
如果只有一个参数,且参数是简单类型的,那么#{id}中的id可以随意写成其它内容,例如:#{abc}
简单类型参数:
int, double, short, boolean, … 或者:java.lang.Integer, java.lang.Double, …
string 或者 java.lang.String
5.3 编写测试代码
@Test
public void testDeleteUser(){
dao.delete(50);
session.commit();
}
注意:执行了DML语句之后,要提交事务:session.commit();
6. 根据主键查询一个用户
6.1 在映射器IUserDao中增加方法
User findById(Integer id);
6.2 在映射配置文件中增加配置信息
<select id="findById" parameterType="int" resultType="com.viking.bean.User">
select * from user where id = #{id}
</select>
6.3 编写测试代码
@Test
public void testFindUserById(){
User user = dao.findById(48);
System.out.println(user);
}
7. 模糊查询
7.1 使用#{}方式进行模糊查询
7.1.1 在映射器IUserDao中增加方法
/**
* 使用#{}方式进行模糊查询
*/
List<User> findByUsername1(String username);
7.1.2 在映射配置文件中增加配置信息
<select id="findByUsername1" parameterType="string" resultType="com.viking.bean.User">
select * from user where username like #{username}
</select>
注意:只有一个参数,且是简单参数时, #{username}中的username可以写成其它任意名称
7.1.3 编写测试代码
/**
* 使用#{}方式进行模糊查询--单元测试方法
*/
@Test
public void testFindUserByUsername1(){
List<User> users = dao.findByUsername1("%王%");
for (User user : users) {
System.out.println(user);
}
}
注意:模糊查询的条件值,前后需要有%
7.2 使用${value}方式进行模糊查询
7.2.1 在映射器IUserDao中增加方法
/**
* 使用${value}方式进行模糊查询
*/
List<User> findByUsername2(String username);
7.2.2 在映射配置文件中增加配置信息
<select id="findByUsername2" parameterType="string" resultType="com.viking.bean.User">
select * from user where username like '%${value}%'
</select>
注意:
${value}是固定写法,不能做任何更改
在SQL语句中已经加了%,那么在测试代码中,传递参数值时就不需要再加%了
7.2.3 编写测试代码
/**
* 使用${value}方式进行模糊查询--单元测试方法
*/
@Test
public void testFindUserByUsername2(){
List<User> users = dao.findByUsername2("王");
for (User user : users) {
System.out.println(user);
}
}
注意:SQL语句中已经加了%, 参数值前后不需要再加%
7.3 #{}和${value}的区别
-
#{}
:表示一个占位符,相当于预编译对象的SQL中的?- 可以有效防止SQL注入;
- Mybatis会自动进行参数的Java类型和JDBC类型转换;
#{}
中间可以是value或者其它名称
映射配置文件中的SQL:select * from user where username like #{username} 单元测试中传递实参:%王% 最终执行的SQL:select * from user where username like ? 参数值:%王%
-
${value}
:表示拼接SQL串,相当于把实际参数值,直接替换掉${value}
- 不能防止SQL注入
- Mybatis不进行参数的Java类型和JDBC类型转换
${value}
中只能是value,不能是其它名称
映射配置文件中的SQL:select * from user where username like '%${value}%' 单元测试中传递实参:王 最终执行的SQL:select * from user where username like '%王%'
8. 查询数量(聚合函数)
8.1 在映射器IUserDao中增加方法
Integer findTotalCount();
8.2 在映射配置文件中增加配置信息
<select id="findTotalCount" resultType="int">
select count(*) from user
</select>
8.3 编写测试代码
@Test
public void testFindTotalCount(){
Integer totalCount = dao.findTotalCount();
System.out.println(totalCount);
}
二、Mybatis的参数和结果集
1. OGNL表达式了解
OGNL:Object Graphic Navigator Language,是一种表达式语言,用来从Java对象中获取某一属性的值。本质上使用的是JavaBean的getXxx()方法。例如:user.getUsername()—> user.username
在#{}里、${}可以使用OGNL表达式,从JavaBean中获取指定属性的值
2. parameterType
2.1 简单类型
例如:int, double, short 等基本数据类型,或者string
或者:java.lang.Integer, java.lang.Double, java.lang.Short, java.lang.String
2.2 POJO(JavaBean)
如果parameterType是POJO类型,在SQL语句中,可以在#{}
中使用OGNL表达式来获取JavaBean的属性值。
例如:parameterType是com.viking.bean.User, 在SQL语句中可以使用#{username}
获取username属性值。
2.3 POJO包装类–QueryVO
在web应用开发中,通常有综合条件的搜索功能,例如:根据商品名称 和 所属分类 同时进行搜索。这时候通常是把搜索条件封装成JavaBean对象;JavaBean中可能还有JavaBean。
练习:根据用户名搜索用户信息,查询条件放到QueryVO的user属性中
2.3.1 在bean中创建QueryVO
public class QueryVO {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
2.3.2 在映射器IUserDao中增加方法
List<User> findByVO(QueryVO vo);
2.3.3 在映射配置文件中增加配置信息
<select id="findByVO" parameterType="com.viking.bean.QueryVO" resultType="com.viking.bean.User">
select * from user where username like #{user.username}
</select>
2.3.4 编写测试代码
@Test
public void testFindByVO(){
QueryVO vo = new QueryVO();
User user = new User();
user.setUsername("%王%");
vo.setUser(user);
List<User> users = dao.findByVO(vo);
for (User user1 : users) {
System.out.println(user1);
}
}
3. resultType
3.1 简单类型
例如:int, double, short 等基本数据类型,或者string
或者:java.lang.Integer, java.lang.Double, java.lang.Short, java.lang.String
3.2 POJO(JavaBean)
例如:com.viking.bean.User
注意:JavaBean的属性名要和字段名保持一致
3.3 JavaBean中属性名和字段名不一致的情况处理
JavaBean如下:
public class User2 {
private Integer userId;
private String username;
private Date userBirthday;
private String userSex;
private String userAddress;
//get/set方法...
//toString方法...
}
3.3.1 处理方案一:SQL语句中使用别名,别名和JavaBean属性名保持一致(用的少)
- 在映射器IUserDao中增加方法
/**
* JavaBean属性名和字段名不一致的情况处理---方案一
* @return
*/
List<User2> queryAll_plan1();
- 在映射配置文件中增加配置信息
<select id="queryAll_plan1" resultType="com.viking.bean.User2">
select id as userId, username as username, birthday as userBirthday, address as userAddress, sex as userSex from user
</select>
- 编写测试代码
/**
* JavaBean属性名和字段名不一致的情况处理---方案一 单元测试代码
*/
@Test
public void testQueryAllUser2_plan1(){
List<User2> user2List = dao.queryAll_plan1();
for (User2 user2 : user2List) {
System.out.println(user2);
}
}
3.3.2 处理方案二:使用resultMap配置字段名和属性名的对应关系(推荐)
- 在映射器IUserDao中增加方法
/**
* JavaBean属性名和字段名不一致的情况处理--方案二
* @return
*/
List<User2> queryAll_plan2();
- 在映射配置文件中增加配置信息
<select id="queryAll_plan2" resultMap="user2Map">
select * from user
</select>
<!--
resultMap标签:设置结果集中字段名和JavaBean属性的对应关系
id属性:唯一标识
type属性:要把查询结果的数据封装成什么对象,写全限定类名
-->
<resultMap id="user2Map" type="com.viking.bean.User2">
<!--id标签:主键字段配置。 property:JavaBean的属性名; column:字段名-->
<id property="userId" column="id"/>
<!--result标签:非主键字段配置。 property:JavaBean的属性名; column:字段名-->
<result property="username" column="username"/>
<result property="userBirthday" column="birthday"/>
<result property="userAddress" column="address"/>
<result property="userSex" column="sex"/>
</resultMap>
- 编写测试代码
/**
* JavaBean属性名和字段名不情况处理--方案二 单元测试代码
*/
@Test
public void testQueryAllUser2_plan2(){
List<User2> user2List = dao.queryAll_plan2();
for (User2 user2 : user2List) {
System.out.println(user2);
}
}
三、Mybatis实现传统开发CURD(了解)
Mybatis中提供了两种dao层的开发方式:一是使用映射器接口代理对象的方式;二是使用映射器接口实现类的方式。其中代理对象的方式是主流,也是我们主要学习的内容。
1. 相关类介绍
1.1 SqlSession
SqlSession是一个面向用户的接口,定义了操作数据库的方法,例如:selectList, selectOne等等。
每个线程都应该有自己的SqlSession对象,它不能共享使用,也是线程不安全的。因此最佳的使用范围是在请求范围内、或者方法范围内,绝不能将SqlSession放到静态属性中。
要做到SqlSession:随用随取,用完就关,一定要关
SqlSession操作数据库的常用方法有:
方法 | 作用 |
---|---|
selectList(String statement, Object param) | 查询多条数据,封装JavaBean集合 |
selectOne(String statement, Object param) | 查询一条数据,封装JavaBean对象 查询一个数据 |
insert(String statement, Object param) | 添加数据,返回影响行数 |
update(String statement, Object param) | 修改数据,返回影响行数 |
delete(String statement, Object param) | 删除数据,返回影响行数 |
以上方法中的参数statment,是映射配置文件中的namespace 和 id的值方法名组成的。
例如:
映射配置文件的namespace值为com.viking.dao.IUserDao,执行的方法名是queryAll
那么statement的值就是:com.viking.dao.IUserDao.queryAll
1.2 SqlSessionFactory
是一个接口,定义了不同的openSession()方法的重载。SqlSessionFactory一旦创建后,可以重复使用,通常是以单例模式管理。
一个应用中,只要有一个SqlSessionFactory对象即可。
1.3 SqlSessionFactoryBuilder
用于构建SqlSessionFactory工厂对象的。一旦工厂对象构建完成,就不再需要SqlSessionFactoryBuilder了,通常是作为工具类使用。
2. 创建Maven的Java项目,pom.xml如下:
<!-- 项目坐标 -->
<groupId>com.viking</groupId>
<artifactId>mybatis02_dao</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- 添加依赖 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
</dependencies>
3. 创建映射器接口IUserDao
public interface IUserDao {
/**查询全部用户*/
List<User> queryAll();
/**添加用户*/
void save(User user);
/**修改用户*/
void edit(User user);
/**删除用户*/
void delete(Integer id);
/**根据主键查找一个用户*/
User findById(Integer id);
/**使用#{}方式进行模糊查询*/
List<User> findByUsername1(String username);
/**使用${value}方式进行模糊查询*/
List<User> findByUsername2(String username);
/**查询数量*/
Integer findTotalCount();
}
4. 创建映射器配置文件IUserDao.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.viking.dao.IUserDao">
<!-- 查询全部用户 -->
<select id="queryAll" resultType="User">
select * from user
</select>
<!-- 添加用户 -->
<insert id="save" parameterType="User">
<selectKey resultType="int" keyProperty="id" order="AFTER">
select last_insert_id()
</selectKey>
insert into user (id, username, birthday, address, sex) values (#{id}, #{username}, #{birthday},#{address},#{sex})
</insert>
<!-- 修改用户 -->
<update id="edit" parameterType="User">
update user set username = #{username}, birthday = #{birthday}, address = #{address}, sex = #{sex}
where id = #{id}
</update>
<!-- 删除用户 -->
<delete id="delete" parameterType="int">
delete from user where id = #{uid}
</delete>
<!-- 根据主键查询一个用户 -->
<select id="findById" parameterType="int" resultType="User">
select * from user where id = #{id}
</select>
<!-- 使用#{}方式进行模糊查询 -->
<select id="findByUsername1" parameterType="string" resultType="User">
select * from user where username like #{username}
</select>
<!-- 使用${value}方式进行模糊查询 -->
<select id="findByUsername2" parameterType="string" resultType="User">
select * from user where username like '%${value}%'
</select>
<!-- 查询数量 -->
<select id="findTotalCount" resultType="int">
select count(*) from user
</select>
</mapper>
5. 创建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>
<typeAliases>
<package name="com.viking.bean"/>
</typeAliases>
<environments default="mysql_mybatis">
<environment id="mysql_mybatis">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/viking/dao/IUserDao.xml"/>
</mappers>
</configuration>
6. 创建映射器接口IUserDao的实现类UserDaoImpl,实现CURD
public class UserDaoImpl implements IUserDao {
private SqlSessionFactory factory;
/**
* 构造方法。因为工厂对象,是整个应用只要一个就足够了,所以这里不要创建SqlSessionFactory对象
* 而是接收获取到工厂对象来使用。
*/
public UserDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
/**
* 查询全部用户,得到List<User>
*/
@Override
public List<User> queryAll() {
SqlSession session = factory.openSession();
List<User> users = session.selectList("com.viking.dao.IUserDao.queryAll");
session.close();
return users;
}
/**
* 添加用户
*/
@Override
public void save(User user) {
SqlSession session = factory.openSession();
session.insert("com.viking.dao.IUserDao.save", user);
session.commit();
session.close();
}
/**
* 修改用户
*/
@Override
public void edit(User user) {
SqlSession session = factory.openSession();
session.update("com.viking.dao.IUserDao.edit", user);
session.commit();
session.close();
}
/**
* 删除用户
*/
@Override
public void delete(Integer id) {
SqlSession session = factory.openSession();
session.delete("com.viking.dao.IUserDao.delete", id);
session.commit();
session.close();
}
/**
* 根据主键查询一个用户User
*/
@Override
public User findById(Integer id) {
SqlSession session = factory.openSession();
User user = session.selectOne("com.viking.dao.IUserDao.findById", id);
session.close();
return user;
}
/**
* 使用#{}方式进行模糊查询
*
* @param username
*/
@Override
public List<User> findByUsername1(String username) {
SqlSession session = factory.openSession();
List<User> users = session.selectList("com.viking.dao.IUserDao.findByUsername1", username);
session.close();
return users;
}
/**
* 使用${value}方式进行模糊查询
*
* @param username
*/
@Override
public List<User> findByUsername2(String username) {
SqlSession session = factory.openSession();
List<User> users = session.selectList("com.viking.dao.IUserDao.findByUsername2", username);
session.close();
return users;
}
/**
* 查询数量
*/
@Override
public Integer findTotalCount() {
SqlSession session = factory.openSession();
Integer count = session.selectOne("com.viking.dao.IUserDao.findTotalCount");
session.close();
return count;
}
}
7. 编写测试代码,测试CURD
public class MybatisDaoCURDTest {
private InputStream is;
private SqlSessionFactory factory;
private IUserDao dao;
/**
* 测试查询全部
*/
@Test
public void testQueryAll(){
List<User> users = dao.queryAll();
for (User user : users) {
System.out.println(user);
}
}
/**
* 测试添加用户
*/
@Test
public void testSaveUser(){
User user = new User();
user.setUsername("Tom");
user.setAddress("广东深圳");
user.setBirthday(new Date());
user.setSex("男");
System.out.println("保存之前:" + user);
dao.save(user);
System.out.println("保存之后:" + user);
}
/**
* 测试修改用户
*/
@Test
public void testEditUser(){
User user = new User();
user.setId(71);
user.setUsername("Jerry");
user.setAddress("广东深圳宝安");
user.setSex("女");
user.setBirthday(new Date());
dao.edit(user);
}
/**
* 测试删除用户
*/
@Test
public void testDeleteUser(){
dao.delete(71);
}
/**
* 测试根据主键查询一个用户
*/
@Test
public void testFindUserById(){
User user = dao.findById(48);
System.out.println(user);
}
/**
* 测试 使用#{}方式进行模糊查询
*/
@Test
public void testFindUserByUsername1(){
List<User> users = dao.findByUsername1("%王%");
for (User user : users) {
System.out.println(user);
}
}
/**
* 测试 使用${value}方式进行模糊查询
*/
@Test
public void testFindUserByUsername2(){
List<User> users = dao.findByUsername2("王");
for (User user : users) {
System.out.println(user);
}
}
/**
* 测试查询数量
*/
@Test
public void testFindTotalCount(){
Integer totalCount = dao.findTotalCount();
System.out.println(totalCount);
}
@Before
public void init() throws IOException {
is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(is);
//创建Dao实现类对象时,把factory作为构造参数传递进去---一个应用只要有一个factory就够了
dao = new UserDaoImpl(factory);
}
@After
public void destory() throws IOException {
is.close();
}
}
8. 映射器接口代理对象方式和实现类方式运行原理
8.1 映射器接口代理对象的方式 运行过程
debug跟踪—>实现类传统方式的sqlsession的方法—>底层是JDBC的代码
8.2 映射器接口实现类的方式 运行过程
debug跟踪—>底层是JDBC的代码
四、SqlMapConfig.xml核心配置文件
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性) ★
settings(全局配置参数)
typeAliases(类型别名) ★
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器) ★
1. properties属性
可以在SqlMapConfig.xml中引入properties文件的配置信息,实现配置的热插拔效果。例如:
1.1 准备jdbc.properties放在resources下
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=root
1.2 在SqlMapConfig.xml中引入jdbc.properties
<configuration>
<!--
properties标签:
resource属性:properties资源文件的路径,从类加载路径下开始查找
url属性:url地址
-->
<properties resource="jdbc.properties"/>
<environments default="mysql_mybatis">
<environment id="mysql_mybatis">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 使用${OGNL}表达式,获取从properties中得到的配置信息 -->
<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>
<mappers>
<mapper resource="com/viking/dao/IUserDao.xml"/>
</mappers>
</configuration>
1.3 注意加载顺序
假如:
有jdbc.properties配置文件在resource下
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=root
SqlMapConfig.xml配置如下:
<properties resurce="jdbc.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="123456"/>
</properties>
那么:
Mybatis会首先加载properties中的property标签,得到了jdbc.username和jdbc.password
然后再加载外部jdbc.properties配置文件,覆盖掉刚刚得到的jdbc.username和jdbc.password的值
总结:
外部properties配置文件的优先级,要高于properties/property标签的配置
2. typeAlias类型别名
在映射配置文件中,我们要写大量的parameterType和resultType,如果全部都写全限定类名的话,代码就太过冗余,开发不方便。可以使用类型别名来解决这个问题。
类型别名:是Mybatis为Java类型设置的一个短名称,目的仅仅是为了减少冗余。
注意:类型别名不区分大小写
Mybatis提供的别名有:
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
3. 自定义类型别名
例如:自己定义的JavaBean,全限定类名太长,可以自定义类型别名。
3.1 给一个类指定别名
3.1.1 在SqlMapConfig.xml中配置一个类的别名
<typeAliases>
<!-- type:要指定别名的全限定类名 alias:别名 -->
<typeAlias type="com.viking.bean.QueryVO" alias="vo"/>
<typeAlias type="com.viking.bean.User" alias="user"/>
<typeAlias type="com.viking.bean.User2" alias="user2"/>
</typeAliases>
3.1.2 在映射配置文件中使用类型别名
<!-- parameterType使用别名:vo, resultType使用别名:user -->
<select id="findByVO" parameterType="vo" resultType="user">
select * from user where username like #{user.username}
</select>
3.2 指定一个包名
3.2.1 在SqlMapConfig.xml中为一个package下所有类注册别名:类名即别名
<typeAliases>
<!-- 把com.viking.bean包下所有JavaBean都注册别名,类名即别名,不区分大小写 -->
<package name="com.viking.bean"/>
</typeAliases>
3.2.2 在映射配置文件中使用类型别名
<!-- parameterType使用别名:queryvo, resultType使用别名:user -->
<select id="findByVO" parameterType="queryvo" resultType="user">
select * from user where username like #{user.username}
</select>
4. mappers映射器
用来配置映射器接口的配置文件位置,或者映射器接口的全限定类名
4.1 <mapper resource=""/>
用于指定映射配置文件xml的路径,支持xml开发方式,例如:
<mapper resource="com/viking/dao/IUserDao.xml"/>
注意:
映射配置文件的名称,和映射器接口类名 可以不同
映射配置文件的位置,和映射器接口位置 可以不同
4.2 <mapper class=""/>
用于指定映射器接口的全限定类名,支持XML开发和注解开发,例如:
<mapper class="com.viking.dao.IUserDao"/>
如果是使用xml方式开发,那么要注意:
映射配置文件的名称 要和 映射器接口的类名相同
映射配置文件的位置 要和 映射器接口的位置相同
4.3 <package name=""/>
用于自动注册指定包下所有的映射器接口,支持XML开发和注解开发,例如:
<package class="com.viking.dao"/>
如果是使用XML方式开发,那么要注意:
映射配置文件的名称 要和 映射器接口的类名相同
映射配置文件的位置 要和 映射器接口的位置相同