赞
踩
大家好,我是黄小布,大家可以叫我小布。今天我来教大家Mybatis的编写。
首先我们先认识一下Mybatis。MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects。
Mybatis框架的简介
Mybatis是SSM中的M,它是一个开源的数据持久层框架。它内部封装了通过jdbc访问数据库的操作,支持普通的SQL查询,存储过程喝高级映射,基本上消除了所有的jdbc代码喝参数的手工设置以及结果集的检索。Mybatis作为持久层框架,其主要思想是将程序中的大量SQL语句剥离出来,配置在配置文件中,实现SQL的灵活配置。这样做的好处是将SQL与程序代码分离,可以在不修改程序代码的情况下,直接在配置文件中修改SQL。
好了,我们废话不多说,直接上手吧。
4.创建持久化类(POJO)和SQL的映射文件
四、Mybatis全局配置文件
SqlMapConfig.xml是Mybatis的全局配置文件,它的名称可以是任意,但是一般命名都为(SqlMapConfig)
4.1.全局配置文件的类容和顺序
Properties(属性)
Settings(全局参数设置)
plugins(插件)
environments(环境信息集合)
environment(单个环境信息)
transactionManager(事物)
dataSource(数据源)
mappers(映射器)
4.2.常见配置详解
properties标签:
Mybatis可以通过该标签来读取java配置信息:
例如在工程中对数据源信息写在db.properties文件中,可以通过properties标签来加载该文件。
<?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">
1、 先加载properties中property标签声明的属性
因此在property中的name属性的值和value比properties中的resource属性先加载。后加载的db.properties会覆盖于property加载属性和值。
<property name="db.username",value="1234"/>
2、 再加载properties标签引入的java配置文件中的属性
3、 parameterType的值会和properties的属性值发生冲突。因此,在properties文件里的内容命名最好加上db.代表是跟数据源相关的属性,这样就不容易跟以后的属性发生冲突。
settings标签:
该标签时mybatis的全局设置,该设置会影响mybatis的运行。
一般我们使用使用该标签来开启二级缓存和懒加载。
以下是几张settings配置项的说明:
typeAliases标签
该标签是对po类进行别名设置,这样,在后面使用po类的时候就可以直接通过别名引用,而不需要通过po类的全限定名来引用。这样可以提高我们的开发效率。
首先介绍下Mybatis的默认提供的别名有:
别名
映射的类型
_byte
byte
_long
long
_short
short
_int
int
_integer
int
_double
double
_float
float
_boolean
boolean
string
等等,我这里就不一一介绍了。
自定义单个别名:这种方式只能定义单个类的别名。
下面的代码就是把com.lc.mybatis.po.User类定义为user的别名
自定义之批量定义别名:下面代码是把com.lc.mybatis.po类下的所有类都声明别名,默认的别名就是类名(类名大小写都可以)
<typeAliases>
<!-- 批量设置别名 -->
<!-- package:指定包名称来为该包下的po类声明别名,默认的别名就是类名(类名首字母大小写都可以) -->
<package name="com.lc.mybatis.po"/>
</typeAliases>
mappers标签
该标签的作用是加载映射文件
方式一:
该方式是加载相对于类路径下的映射文件:
方式二:
该方式使用全限定路径
方式三:该方式使用mapper接口的全限定类名
此方式要求:Mapper接口Mapper映射文件名称相同且在同一个目录下。
方式四:
该方式是加载指定包下的所有映射文件
Mapper接口Mapper映射文件名称相同且在同一个目录下。
5.1.输入映射parameterType
第一种:简单类型
#{}表示占位符?,parameterType接收简单类型的参数时,里面的名称可以任意
SELECT * FROM USER WHERE id = #{id}${}表示拼接符,parameterType接收简单类型的参数时,里面的名称必须是value
SELECT * FROM USER WHERE username LIKE "%${value}%" 第二种:pojo类型这里通过用户的用户名进行模糊查询演示pojo类型
在映射文件中添加模糊查询语句:
<select id="findUsersByPojo" parameterType="com.lc.mybatis.po.User" resultType="com.lc.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE "%${username}%"
</select>
user类
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
测试类:
public class UserDao{
//根据用户名进行模糊查询
@Override
public List findUserByPojo(){
//全局配置文件路径:
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsetname(“张三”);
List users = (List)sqlSession.selectList(“test.findUsersByPojo”,user);//传入pojo
System.out.println(users);
sqlSession.close();
return users;
}
}
第三种:包装类型pojo
这里通过用户名和用户地址对用户进行查询来演示包装类型pojo:
首先创建包装pojo类:
public class UserVO {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
在映射文件中添加查询语句:
<select id="findUsersByPojo1" parameterType="com.lc.mybatis.po.UserVO" resultType="user">
SELECT * FROM USER WHERE username LIKE "%${user.username}%" AND address=#{user.address}
</select>
测试类:
public class UserDao{
//根据用户名和地址进行查询
@Override
public List findUserByPojo1(){
//全局配置文件路径:
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setUsetname(“张三”);
user.setAddress(“郝汉山”);
UserVO userVo = new UserVO();
userVo.setUser(user);
List users = (List)sqlSession.selectList(“test.findUsersByPojo1”,userVo);//传入pojo包装类
System.out.println(users);
sqlSession.close();
return users;
}
}
第四种:map集合类型
这里通过查询用户信息演示:
在映射文件中添加该查询语句:
<select id="findUsersByMap" parameterType="java.util.Map" resultType="user">
SELECT * FROM USER WHERE username LIKE "%${username}%" AND address=#{address}
</select>
测试方法:
public class UserDao{
//根据用户名和地址进行查询
@Override
public List findUserByMap(){
//全局配置文件路径:
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
Map<String,String> map = new HashMap<>();
map.put(“username”,“张三”);
map.put(“address”,“郝汉山”);
List users = (List) sqlSession.selectList(“test.findUsersByMap”,map);//传入pojo包装类
System.out.println(users);
sqlSession.close();
return users;
}
}
5.2.resultType结果映射
resultType结果映射要求:需要查询结果的列名和映射的对象的属性名一致,这样才能映射成功。如果映射没成功也不会报错,只是映射结果中对象的相应属性没有值,为空。如果映射的列名和对象中的属性名全部不一致,那么映射的对象为空。如果在使用sql语句查询的时候给查询结果列设置了别名,则别名要和映射结果对象的属性名一致,这样才能保证映射成功。
第一种:简单类型
注意: 如果结果映射为简单类型,则需要查询的结果为一列才能映射成功。
例如:查询用户表中用户的总数。
映射文件为:
<select id="findUserCount" resultType="int">
select count(*) from user;
</select>
测试代码:
public class UserDao{
@Override
public int findUserCount(){
//全局配置文件路径:
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
int userCount= sqlSession.selectOne(“test.findUserCount”);
System.out.println(userCount);
sqlSession.close();
return userCount;
}
}
第二种:pojo结果映射
这里操作pojo输入映射。
5.3.resultMap结果映射
使用resultMap结果映射时,不需要查询出来的结果集的列名和映射结果对象的属性名相同,但是需要声明一个resultMap,手动的方式来对列名和对象属性进行映射。(resultMap一般用于多表关联映射)
例如:通过查询用户表中的用户,并对查询出来的用户表的列名设置别名。
映射文件添加查询语句:
[id]:定义resultMap的唯一标识
[type]:定义该resultMap最终映射的pojo对象
[id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签
[result标签]:映射结果集的普通列
[column]:SQL查询的列名,如果列有别名,则该处填写别名
[property]:pojo对象的属性名
<resultMap type="user" id="userMap">
<!-- id标签:专门查询结果中唯一列映射 -->
<id column="id_" property="id"/>
<!-- result标签:映射查询结果中的普通列 -->
<result column="username_" property="username"/>
<result column="address_" property="address"/>
</resultMap>
<select id="findUserResultMap" parameterType="int" resultMap="userMap">
select id id_,username username_,address address_ from user where id=#{id}
</select>
测试类:
public class UserDao{
@Override
public User findUserResultMap(){
//全局配置文件路径:
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne(“test.findUserResultMap”,1);
System.out.println(user);
sqlSession.close();
return user;
}
}
在mybatis中提供了一些动态sql标签,可以让我们开发效率更快,这些动态sql语句可以增加我们写的sql语句的重用性,常用的动态sql语句标签有:if标签、sql片段(需要先定义后使用)、where标签、foreach标签
通过下面例子来演示动态sql常用的标签:
需求分析:查询用户表中相关的用户。
发出相关的sq语句有:select * from user where username like “%张三%” and address= ?;
select * from user;
select * from user where id in(1,2,10);
如何才能让这些语句在我们需要的时候就使用,不需要的时候就不适用。其实我们发现这三条语句有很多重复的地方,我们如果能做到让重复的能够重复使用,没有重复的可以按我们需求使用的话就能减少我们写很多sql语句。当然动态sql就是帮我们解决这些问题的。
映射文件:
<sql id="whereClause"> <!-- if标签:可以对输入的参数进行判断 --> <!-- test:指定判断表达式 --> <if test="user!=null"> <if test="user.username!=null and user.username!=''"> AND username LIKE '%${user.username}%' </if> <if test="user.address!=null and user.address!=''"> AND address=#{user.address} </if> </if> <if test="idList!=null"> AND id IN <!-- foreach标签: 可以循环传入参数值 --> <!-- collenction:标示pojo中集合属性的属性名称 --> <!-- item:每次遍历出来的对象 --> <!--open开始遍历时拼接的串--> <!--close结束遍历时拼接的串--> <!--separator遍历每个对象之间需要拼接字符--> <foreach collection="idList" item="item" open="(" close=")" separator=","> #{item} </foreach> </if> </sql> <select id="findUserList" parameterType="userVO" resultType="user"> SELECT * FROM USER <!-- where标签: 默认去掉第一个AND,如果没有参数就去掉where自己--> <where> <!--引用sql语句片段--> <include refid="whereClause"></include> </where> </select>
userVo类:
public class UserVO {
private User user;
private List idList;
public List<Integer> getIdList() {
return idList;
}
public void setIdList(List<Integer> idList) {
this.idList = idList;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
测试类:
public class UserDao{
@Override
public void findUserList(){
//全局配置文件路径:
String resource = “SqlMapConfig.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//测试foreach语句执行
UserVO userVo = new UserVO();
List idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
userVo.setIdList(idList);
//测试select * from user where username like ? and address=?;
//User user = new User();
//user.setUsername(“张三”);
//user.setAddress(“王五”);
//userVo.setUser(user);
List users = sqlSession.selectOne(“test.findUserList”,userVo);
System.out.println(users);
sqlSession.close();
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。