MyBatis学习总结一
Mybatis学习总结一
- 1、Mybatis介绍
- 2、Mybatis架构图
- 3、入门案例
- 4、Mybatis开发的两种方式
- 4.0、映射文件User.xml详解
- 4.1、dao类实现CRUD
- 4.1.0、工程目录
- 4.1.1、UserDao
- 4.1.2、UserDaoImp
- 4.1.3、User.xml
- 4.1.3、测试Dao的CRUD
- 4.1.4、测试结果
- 4.1.5、log4j.properties导入及其测试结果
- 4.1.4、编写Dao类的问题
- 4.2、使用动态代理mapper实现CRUD
- 5、全局配置文件详解
- 6、输入映射与输出映射
- 6.1、输入映射与简单类型输出映射
- 6.2、简单类型输入映射与输出映射
- 7、动态sql
1、Mybatis介绍
Mybatis是一个类似于Hibernate的ORM持久化框架,支持普通SQL查询,存储过程以及高级映射。Mybatis通过使用简单的XML或注解用于配置和原始映射,将接口和POJO对象映射成数据库中的记录。
Hibernate是一个完全的ORM框架,而Mybatis是一个不完全的orm框架。Mybatis让程序员只关注sql本身,而不需要去关注如连接的创建、statement的创建等操作。Mybatis会将输入参数、输出结果进行映射。
由于Mybatis是直接基于JDBC做了简单的映射包装,所有从性能角度来看:JDBC > Mybatis > Hibernate。
2、Mybatis架构图
2.1、架构图的意义
2.1.1、JDBC编写
package com.csa.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.jupiter.api.Test;
public class App {
@Test
public void app() throws Exception {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/mybatis";
String user = "root";
String password = "3306";
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 创建数据库连接
connection = DriverManager.getConnection(url, user, password);
// 创建Statement对象
String sql = "SELECT * FROM user WHERE username = ?";
statement = connection.prepareStatement(sql);
// 设置参数,下标从1开始
statement.setString(1, "rose");
// 执行sql,变量结果集
resultSet = statement.executeQuery();
while (resultSet.next()) {
System.out.println("id: " + resultSet.getInt("id"));
System.out.println("name: " + resultSet.getString("username"));
System.out.println("age: " + resultSet.getString("age"));
}
} finally {
// 释放资源
if (null != resultSet) {
resultSet.close();
}
if (null != statement) {
statement.close();
}
if (null != connection) {
connection.close();
}
}
}
}
2.1.2、反思问题
JDBC这种固定的东西,完全可以用框架加以实现。因为编写的内容都是一样的!
差不多有以下几个问题:
- 在创建连接时,存在硬编码
- 在执行statement时存在硬编码
- 频繁的开启和关闭数据库连接,会造成数据库性能下降
解决方案:配置xml文件来解决这些问题,使得管理起来方便、高效!
2.2、Mybatis架构图
3、入门案例
3.1、下载地址以及导入jar包
Mybatis下载地址
别忘记连接数据库的jar!
3.2、工程目录
3.3、创建PO类
package com.csa.po;
public class User {
private Integer id;
private String username;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", age=" + age + "]";
}
}
3.4、创建全局配置文件
编写SqlMapConfig.xml:
<?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>
<!-- 引入外部文件 -->
<properties resource="jdbc.properties"></properties>
<!-- 环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<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>
<!-- 加载UserMapper.xml文件
<mappers>
<mapper resource="User.xml"/>
</mappers>
-->
</configuration>
3.5、创建映射文件
编写User.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="app">
<select id="findUserById" parameterType="int" resultType="com.csa.po.User">
select * from User where id = #{id}
</select>
</mapper>
3.6、在全局配置文件中加载映射文件
重新编写SqlMapConfig.xml(在最后添加一个mappers):
<configuration>
...
...
...
<environments ...>
...
</environments>
<!-- 加载UserMapper.xml文件 -->
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>
3.7、测试
package com.csa.app;
import java.io.InputStream;
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 com.csa.po.User;
public class App {
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 调用SqlSession的增删改查的方法
User user = sqlSession.selectOne("app.findUserById",1);
// 打印user
System.out.println(user);
// 关闭资源
sqlSession.close();
}
}
3.8、实验结果
4、Mybatis开发的两种方式
4.0、映射文件User.xml详解
4.0.1、mapper元素
<mapper namespace="app">...</mapper>
其中namespace是命名空间。
4.0.2、CRUD元素
分别是select、insert、update、delete
元素。
例如:
<select id="findUserById" parameterType="int" resultType="com.csa.po.User">
select *from User where id = #{id}
</select>
4.0.3、CRUD元素常用属性
CRUD元素的几个常用属性:
- id:唯一,用于被程序调用
- parameterType:参数类型,POJO类型或者基本数据类型
- parameterMap:参数类型,一个Map集合
- resultType:结果类型,POJO类型或者基本数据类型
- resultMap:结果类型,一个Map集合
4.0.4、#{id}与${id}的区别
#{id}是占位符,安全。
${id}是用于字符串连接的,不安全,会被sql注入。
4.1、dao类实现CRUD
4.1.0、工程目录
4.1.1、UserDao
package com.csa.dao;
import java.util.List;
import com.csa.po.User;
public interface UserDao {
/**
* 添加用户
* @return 是否添加成功
*/
public boolean addUser(User user);
/**
* 删除指定id的用户
* @param id
*/
public boolean deleteUserById(Integer id);
/**
* 更新用户信息
* @param user
*/
public boolean updateUser(User user);
/**
* 通过id查找用户
* @param id
* @return
*/
public User findUserById(Integer id);
/**
* 查找所有用户
* @return
*/
public List<User> selectUserList();
}
4.1.2、UserDaoImp
package com.csa.dao.imp;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.csa.dao.UserDao;
import com.csa.po.User;
public class UserDaoImp implements UserDao {
// DI依赖注入
private SqlSessionFactory sqlSessionFactory;
public UserDaoImp(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public boolean addUser(User user) {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 调用SqlSession的增删改查的方法
int insert = sqlSession.insert("app.addUser", user);
// 提交事务
sqlSession.commit();
// 关闭资源
sqlSession.close();
return insert != 0;
}
@Override
public boolean deleteUserById(Integer id) {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 调用SqlSession的增删改查的方法
int delete = sqlSession.delete("app.deleteUserById", id);
// 提交事务
sqlSession.commit();
// 关闭资源
sqlSession.close();
return delete != 0;
}
@Override
public boolean updateUser(User user) {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 调用SqlSession的增删改查的方法
int update = sqlSession.update("app.updateUser", user);
// 提交事务
sqlSession.commit();
// 关闭资源
sqlSession.close();
return update != 0;
}
@Override
public User findUserById(Integer id) {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 调用SqlSession的增删改查的方法
User user = sqlSession.selectOne("app.findUserById", id);
// 关闭资源
sqlSession.close();
return user;
}
@Override
public List<User> selectUserList() {
// 创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 调用SqlSession的增删改查的方法
List<User> userList = sqlSession.selectList("app.selectUserList");
// 关闭资源
sqlSession.close();
return userList;
}
}
4.1.3、User.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="app">
<!-- 增加 -->
<insert id="addUser" parameterType="com.csa.po.User">
<!--
对于这个例子
keyProperty:查找的结果放在id中
order:在执行insert语句''之后(AFTER)"再执行select last_insert_id()
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
insert into User(username,age) values(#{username},#{age})
</insert>
<!-- 删除 -->
<delete id="deleteUserById" parameterType="int">
delete from User where id=#{id}
</delete>
<!-- 改 -->
<update id="updateUser" parameterType="com.csa.po.User">
update User set username=#{username},age=#{age} where id like #{id}
</update>
<!-- 查询一个对象 -->
<select id="findUserById" parameterType="int" resultType="com.csa.po.User">
select * from User where id = #{id}
</select>
<!-- 查询多个对象 -->
<select id="selectUserList" resultType="com.csa.po.User">
select * from User
</select>
</mapper>
4.1.3、测试Dao的CRUD
package com.csa.app;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.csa.dao.UserDao;
import com.csa.dao.imp.UserDaoImp;
import com.csa.po.User;
public class App {
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建dao类
UserDao userDao = new UserDaoImp(sqlSessionFactory);
// 调用增删改查方法
// 1.增
User user = new User();
user.setUsername("hack");
user.setAge(19);
boolean insert = userDao.addUser(user);
if(insert) {
System.out.println("增加"+user+"成功");
}else {
System.out.println("增加失败:"+user);
}
// 2.改
user.setUsername("mybatis");
user.setAge(0);
boolean update = userDao.updateUser(user);
if(update) {
System.out.println("更新"+user+"成功");
}else {
System.out.println("更新失败:"+user);
}
// 3.删
boolean delete = userDao.deleteUserById(user.getId());
if(delete) {
System.out.println("删除"+user+"成功");
}else {
System.out.println("删除失败:"+user);
}
// 4.查
// 4.1查询单个
user = userDao.findUserById(user.getId());
if(user!=null) {
System.out.println("查询"+user+"成功");
}else {
System.out.println("查询失败:"+user);
}
// 4.2查询所有
List list = userDao.selectUserList();
System.out.println(list);
}
}
4.1.4、测试结果
如果发现WARN这种结果,是因为没有log4j.properties文件。
4.1.5、log4j.properties导入及其测试结果
4.1.5.1、创建log4j.properties
4.1.5.1、编写log4j.properties
log4j.rootLogger=DEBUG, Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=INFO
4.1.5.1、测试
4.1.4、编写Dao类的问题
我们发现一个问题:编写了很多重复性的代码,而且都是固定(模板)形式!
解决方案:使用动态代理(Mapper)来解决!
4.2、使用动态代理mapper实现CRUD
4.2.0、Mapper代理的开发规范
- mapper接口的全限定名要和mapper映射文件的namespace值一致。
- mapper接口的方法名称要和mapper映射文件的statement的id一致。
- mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致,而且它的参数是一个。
- mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。
4.2.1、开发目录
与上一个相比,只是少了实现类。
4.2.2、创建UserDao
与上面一样。
4.2.3、配置mapper映射文件
不同的地方就只有一处:注意看namespace属性的不同
。
<mapper namespace="com.csa.dao.UserDao">内容与上面的一样</mapper>
4.2.4、测试
不同之处也只在于这两行:
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao类
UserDao userDao = sqlSession.getMapper(UserDao.class);
下面是一个完整的:
package com.csa.app;
import java.io.InputStream;
import java.util.List;
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 com.csa.dao.UserDao;
import com.csa.po.User;
public class App {
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao类
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 调用增删改查方法
// 1.增
User user = new User();
user.setUsername("hack");
user.setAge(19);
boolean insert = userDao.addUser(user);
if(insert) {
System.out.println("增加"+user+"成功");
}else {
System.out.println("增加失败:"+user);
}
// 2.改...
// 3.删...
// 4.查
// 4.1查询单个...
// 4.2查询所有...
}
}
4.2.5、测试结果
5、全局配置文件详解
5.1、properties元素
用于加载配置文件。比如<properties resource="配置文件的路径"></properties>
。使用时${属性名}
即可。
5.2、settings
<!--
参数说明:
cacheModelsEnabled:
启用或禁用SqlMapClient的所有缓存model。调试程序时使用。
enhancementEnabled:
启用或禁用运行时字节码增强,以优化访问Java Bean属性的性能,同时优化延迟加载
的性能。
lazyLoadingEnabled:
启用或禁用SqlMapClient的所有延迟加载。调试程序时使用。
maxRequests:
同时执行SQL语句的最大线程数。大于这个值的线程将阻塞直到另一个线程执行完成。
不同的DBMS有不同的限制值,但任何数据库都有这些限制。通常这个值应该至少是
maxTransactions的10倍,并且总是大于maxSessions和maxTranactions。减小这个参数值通常能提高性能。
maxSessions:
同一时间内活动的最大session数。一个session可以是代码请求的显式session,
也可以是当线程使用SqlMapClient实例(即执行一条语句)自动获得的session。
它应该总是大于或等于maxTransactions并小于maxRequests。减小这个参数值通常能
减少内存使用。
maxTransactions:
同时进入SqlMapClient.startTransaction()的最大线程数。大于这个值的线程将阻塞
直到另一个线程退出。不同的DBMS有不同的限制值,但任何数据库都有这些限制。这个
参数值应该总是小于或等于maxSessions并总是远远小于maxRequests。减小这个参数值
通常能提高性能。
useStatementNamespaces:
如果启用本属性,必须使用全限定名来引用mapped statement。Mapped statement的
全限定名由sql-map的名称和mapped-statement的名称合成,例如
queryForObject(“sqlMapName.statementName”)
-->
<settings cacheModelsEnabled="true"
enhancementEnabled="false"
lazyLoadingEnabled="false"
maxRequests="3000"
maxSessions="3000"
maxTransactions="3000"
useStatementNamespaces="false"/>
5.3、typeAliases
5.3.1、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 |
5.3.2、自定义别名
<typeAliases>
<!--定义单个别名 -->
<typeAlias type="com.csa.po.User" alias="user"/>
<!--
批量定义别名
规则:类首字母小写
-->
<package name="com.csa.po"/>
</typeAliases>
5.4、mappers
以下4种形式,加载映射文件:
<!-- 加载UserMapper.xml文件 -->
<mappers>
<!-- 相对路径 -->
<mapper resource="User.xml"/>
<!-- 完全限定路径 -->
<mapper url="file:///D:\Mybatis\MybatisPro2\src\User.xml"/>
<!-- 接口路径 -->
<mapper class="com.csa.dao.UserDao"/>
<!-- 包路径(常用) -->
<package name="com.csa.dao"/>
</mappers>
6、输入映射与输出映射
6.1、输入映射与简单类型输出映射
6.1.1、简单类型输入
映射文件
<!-- 查询对应ID的用户名 -->
<select id="findUsernameById" parameterType="int" resultType="string">
select username from User where id = #{id}
</select>
UserDao接口
/**
* 通过id查找用户名
* @param id
* @return 用户名
*/
public String findUsernameById(Integer id);
测试方法
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao类
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 执行简单类型的查找
userDao.findUsernameById(16);
System.out.println(username);
// 关闭sqlSession
sqlSession.close();
}
实验结果
6.1.2、POJO类型输入
映射文件
<!-- 查询符合年龄和出生月份的用户 -->
<select id="selectUsernamesByBrithday" parameterType="com.csa.po.User" resultType="string">
select username from User where age=${age} and brithdayMonth=${brithdayMonth}
</select>
UserDao接口
/**
* 查找与User的同年同月生的用户的用户名
* @param user
* @return
*/
public List<String> selectUsernamesByBrithday(User user);
测试方法
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao类
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.findUserById(15);
System.out.println(user);
List<String> usernames = userDao.selectUsernamesByBrithday(user);
System.out.println(usernames);
// 关闭sqlSession
sqlSession.close();
}
实验结果
6.1.3、POJO类型嵌套POPJ类型的输入映射
User
package com.csa.po;
public class User {
private Integer id;
private String username;
private Integer age;
private Integer brithdayMonth;
// set/get...
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", age=" + age + ", brithdayMonth=" + brithdayMonth + "]";
}
}
UserVo
package com.csa.po;
public class UserVo {
private User user;
// set/get...
@Override
public String toString() {
return "UserVo [user=" + user + "]";
}
}
映射文件
<!-- POJO类型嵌套POPJ类型的输入映射,查询符合年龄和出生月份的用户 -->
<select id="selectUserVonamesByBrithday" parameterType="com.csa.po.UserVo" resultType="string">
select username from User where age=${user.age} and brithdayMonth=${user.brithdayMonth}
</select>
UserDao接口
/**
* POJO类型嵌套POPJ类型的输入映射
* 查找与UserVo的同年同月生的用户的用户名
* @param userVo
* @return
*/
public List<String> selectUserVonamesByBrithday(UserVo userVo);
测试方法
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao类
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.findUserById(15);
UserVo userVo = new UserVo();
userVo.setUser(user);
System.out.println(userVo);
List<String> usernames = userDao.selectUserVonamesByBrithday(userVo);
System.out.println(usernames);
// 关闭sqlSession
sqlSession.close();
}
实验结果
6.1.4、Map类型的输入映射
映射文件
<!-- 查询在某年某月出生的用户的用户名 -->
<select id="findUsernamesByBrithday" parameterType="hashmap" resultType="string">
select username from User where age=${age} and brithdayMonth=${brithdayMonth}
</select>
UserDao接口
/**
* 通过hashmap查询在某年某月出生的用户的用户名
* @param map
* @return
*/
public List<String> findUsernamesByBrithday(Map<String,Object> map);
测试
public static void main(String[] args) throws Exception {
//读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao类
UserDao userDao = sqlSession.getMapper(UserDao.class);
Map<String,Object> map = new HashMap<>();
map.put("age", 12);
map.put("brithdayMonth", 10);
List<String> usernames = userDao.findUsernamesByBrithday(map);
System.out.println(usernames);
// 关闭sqlSession
sqlSession.close();
}
测试结果
6.2、简单类型输入映射与输出映射
6.2.1、resultMap属性
映射文件
<!-- 定义一个resultMap,id唯一标识 -->
<resultMap type="com.csa.po.User" id="userMap">
<result column="_id" property="id"/>
<result column="_username" property="username"/>
<result column="_age" property="age"/>
<result column="_brithdayMonth" property="brithdayMonth"/>
</resultMap>
<!-- 使用resultMap,通过id查询User -->
<select id="selectUserMap" parameterType="int" resultMap="userMap">
select id _id,username _username,age _age,brithdayMonth _brithdayMonth
from User
where id=#{id}
</select>
UserDao接口
/**
* 通过id查询User
* @param id
* @return
*/
public User selectUserMap(Integer id);
测试
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.selectUserMap(15);
System.out.println(user);
// 关闭sqlSession
sqlSession.close();
}
测试结果
复杂输入类型与复杂输出类型的一个例子
输入类型是map,输出类型是一个UserVo。
UserVo类
package com.csa.po;
public class UserVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "UserVo [user=" + user + "]";
}
}
UserDao接口
/**
* 通过map类型查找UserVo
* @param map
* @return
*/
public List<UserVo> selectUserVosMap(Map<String,Object> map);
映射文件
<!-- 复杂输入类型与复杂输出类型的一个例子 -->
<!-- resultmap -->
<resultMap type="com.csa.po.UserVo" id="userVoMap">
<result column="id" property="user.id"/>
<result column="username" property="user.username"/>
<result column="age" property="user.age"/>
<result column="brithdayMonth" property="user.brithdayMonth"/>
</resultMap>
<!-- 使用resultMap,查询在某年某月出生的User并封装到UserVo -->
<select id="selectUserVosMap" parameterType="hashmap" resultMap="userVoMap">
select * from User where age=#{age} and brithdayMonth=#{brithdayMonth}
</select>
测试
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao
UserDao userDao = sqlSession.getMapper(UserDao.class);
Map<String,Object> map = new HashMap<>();
map.put("age", 12);
map.put("brithdayMonth", 10);
List<UserVo> userVo = userDao.selectUserVosMap(map);
System.out.println(userVo);
// 关闭sqlSession
sqlSession.close();
}
测试结果
7、动态sql
7.1、动态sql介绍
在mybatis中,它提供了一些动态sql标签,可以让程序员更快的进行mybatis的开发,这些动态sql可以通过sql的可重用性。
常用的动态sql标签:if标签、where标签、sql片段、foreach标签。
7.2、If标签/where标签
映射文件
<!-- 复杂输入类型与复杂输出类型的一个例子 -->
<!-- resultmap -->
<resultMap type="com.csa.po.UserVo" id="userVoMap">
<result column="id" property="user.id"/>
<result column="username" property="user.username"/>
<result column="age" property="user.age"/>
<result column="brithdayMonth" property="user.brithdayMonth"/>
</resultMap>
<!--
输入类型:UserVo
输出类型:UserVo
查询特定某年某月出生的用户,如果这个用户年龄和月份没有透露完全,则根据对应的去查找
-->
<select id="selectUserVoList" parameterType="com.csa.po.UserVo" resultMap="userVoMap">
select * from User
<!-- where标签:默认去掉后面第一个and,如果没有参数,则把自己干掉 -->
<where>
<!-- if标签:可以对输入的参数进行判断 -->
<!-- 与OGNL表达式类似 -->
<if test="user != null">
<if test="user.age != null">
and age=#{user.age}
</if>
<if test="user.brithdayMonth != null">
and brithdayMonth=#{brithdayMonth}
</if>
</if>
</where>
</select>
UserDao接口
/**
* 查询特定某年某月出生的用户,如果这个用户年龄和月份没有透露完全,则根据对应的去查找
* @param userVo
* @return
*/
public List<UserVo> selectUserVoList(UserVo userVo);
测试
public static void main(String[] args) throws Exception {
// 读取全局配置文件
String resource = "SqlMapConfig.xml";
InputStream input = Resources.getResourceAsStream(resource);
// 创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
// 创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建dao
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
UserVo userVo = new UserVo();
user.setAge(12);
userVo.setUser(user);
List<UserVo> userVoList = userDao.selectUserVoList(userVo);
System.out.println(userVoList);
// 关闭sqlSession
sqlSession.close();
}
测试结果
7.3、sql片段
映射文件
<!--
输入类型:UserVo
输出类型:UserVo
查询特定某年某月出生的用户,如果这个用户年龄和月份没有透露完全,则根据对应的去查找
-->
<select id="selectUserVoList" parameterType="com.csa.po.UserVo" resultMap="userVoMap">
select * from User
<include refid="whereUser"></include>
</select>
<sql id="whereUser">
<!-- where标签:默认去掉后面第一个and,如果没有参数,则把自己干掉 -->
<where>
<!-- if标签:可以对输入的参数进行判断 -->
<!-- 与OGNL表达式类似 -->
<if test="user != null">
<if test="user.age != null">
and age=#{user.age}
</if>
<if test="user.brithdayMonth != null">
and brithdayMonth=#{brithdayMonth}
</if>
</if>
</where>
</sql>
7.4、sql片段
<foreach collection="迭代集合" item="迭代对象" open="()" close=")" separator=",">
#{迭代对象.属性}
</foreach>
参考
黑马笔记和各种博客!