我们只需要编写DAO接口和mapper.xml文件即可,DAO接口实现对象由mybatis自动生成代理对象。
如:
一、为什么不使用原始的DAO方式开发呢?
1、dao的实现类中存在重复代码,整个mybatis操作的过程代码模板重复(先创建sqlsession、调
用sqlsession的方法、关闭sqlsession)
2、dao的实现类中存在硬编码,调用sqlsession方法时将statement的id硬编码。
如:
二、mapper代理方式开发规范,或者说,开发规则?必须要遵守人家的规定:
2.1 规范:
1、mapper.xml中namespace指定为mapper接口的全限定名(就是指类的全路径)
此步骤目的:通过mapper.xml和mapper.java进行关联。
2、mapper.xml中statement的id就是mapper.java中方法名
3、mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
4、mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.
2.2 什么是statement?
三、mapper.xml文件介绍(如UserMapper.xml文件)
mapper映射文件的命名方式建议:表名 + Mapper.xml
namespace指定为mapper接口的全限定名
将UserMapper.xml放在classpath 下mapper目录下。
如文件内容:
<?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"> <!-- namespace命名空间,为了对sql语句进行隔离,方便管理 ,mapper开发dao方式,使用namespace有特殊作用 --> <!-- com.xingej.mybatis.mapper.UserMapper 这种方式,就是 全限定名 --> <mapper namespace="com.xingej.mybatis.mapper.UserMapper"> <!-- 在mapper.xml文件中配置很多的sql语句,执行每个sql语句时, 封装为MappedStatement对象 mapper.xml以statement为单位管理sql语句 --> <!-- 根据id查询用户信息 --> <!-- id:唯一标识 一个statement #{}:表示 一个占位符,如果#{}中传入简单类型的参数,#{}中的名称随意 parameterType:输入 参数的类型,通过#{}接收parameterType输入 的参数 resultType:输出结果 类型,不管返回是多条还是单条,指定单条记录映射的pojo类型 --> <select id="findUserById" parameterType="int" resultType="user"> SELECT * FROM USER WHERE id= #{id} </select> <!-- 根据用户名称查询用户信息,可能返回多条 ${}:表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。 ${}方式的缺点:不能防止sql的注入;select * from user where name like 'xiaoming' or '1=1' 这条语句,始终成立,后面的' or '1= 就是sql注入; 有的时候,软件在交付的时候,会进行sql注入的校验。 --> <select id="findUserByName" parameterType="java.lang.String" resultType="com.xingej.mybatis.po.User"> select * from user where username like '%${value}%' </select> <!-- 添加用户 parameterType:输入 参数的类型,User对象 包括 username,birthday,sex,address #{}接收pojo数据,可以使用OGNL解析出pojo的属性值 #{username}表示从parameterType中获取pojo的属性值 selectKey:用于进行主键返回,定义了获取主键值的sql order:设置selectKey中sql执行的顺序,相对于insert语句来说 keyProperty:将主键值设置到哪个属性 resultType:select LAST_INSERT_ID()的结果 类型 --> <insert id="insertUser" parameterType="com.xingej.mybatis.po.User"> <selectKey keyProperty="id" order="AFTER" resultType="int"> select LAST_INSERT_ID() </selectKey> INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address}) </insert> <!-- mysql的uuid生成主键 --> <!-- <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="BEFORE" resultType="string"> select uuid() </selectKey> INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address}) </insert> --> <!-- oracle 在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性 --> <!-- <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey keyProperty="id" order="BEFORE" resultType="int"> select 序列.nextval() from dual </selectKey> INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address}) </insert> --> <!-- 用户删除 --> <delete id="deleteUser" parameterType="int"> delete from user where id=#{id} </delete> <!-- 用户更新 要求:传入的user对象中包括 id属性值 --> <update id="updateUser" parameterType="com.xingej.mybatis.po.User"> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> <!-- 自定义查询条件,查询用户信息 parameterType:指定包装类型 %${userCustom.username}%:userCustom是userQueryVo中的属性,通过OGNL获取属性的值 --> <select id="findUserList" parameterType="userQueryVo" resultType="user"> select * from user where username like '%${userCustom.username}%' </select> </mapper>
四、mapper接口 说明:
mybatis提出了mapper接口,相当 于dao 接口。
mapper接口的命名方式建议:表名+Mapper
例子:
public interface UserMapper {
// 根据ID来查询用户信息
public User findUserById(int id);
// 根据用户名称来查询用户信息
public List<User> findUserByName(String userName);
//
public List<User> findUserList(UserQueryVo userQueryVo);
public void insertUser(User user);
public void deleteUser(int id);
public void updateUser(User user);
}
4.1 将mapper.xml在SqlMapConfig.xml中加载(也就是注册)
在SqlMapConfig.xml中添加mappers标签,如下所示:
<mappers> <!-- 通过resources一弄mapper的映射文件 --> <mapper resource="sqlMap/User.xml" /> <!-- 注册 --> <mapper resource="mapper/UserMapper.xml" /> </mappers>
4.2 mapper接口返回单个对象和集合对象
不管查询记录是单条还是多条,在 statement中resultType定义一致,都是单条记录映射的pojo类型。
mapper接口方法返回值:
如果是返回的单个对象,返回值类型是pojo类型,生成的代理对象内部通过selectOne获取记录,
如果返回值类型是集合对象,生成的代理对象内部通过selectList获取记录。
如:
public interface UserMapper {
// 根据ID来查询用户信息,返回单个对象
public User findUserById(int id);
// 根据用户名称来查询用户信息,返回集合对象
public List<User> findUserByName(String userName);
}
五、SqlMapConfig.xml文件介绍
5.1 SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
5.1.1 properties属性定义?
就是把一些通用的属性值配置在属性文件中,加载到mybatis运行环境内。
如:创建db.properties配置数据库连接参数。
db.properties文件的内容如下:
#这里定义的属性,是用在SqlMapConfig.xml里的properties属性里 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=123456
通过properties属性,就可以将db.properties文件加载到SqlMapConfig.xml里,如下所示:
注意: MyBatis 将按照下面的顺序来加载属性:
在 properties 元素体内定义的属性首先被读取。
然后会读取properties元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
建议使用properties,不要在properties中定义属性,只引用定义的properties文件中属性,并且properties文件中定义的key要有一些特殊的规则。
5.1.2 settings全局参数配置
mybatis运行时可以调整一些全局参数(相当于软件的运行参数),参考:mybatis-settings.xlsx
根据使用需求进行参数配置。
注意:小心配置,配置参数会影响mybatis的执行。
ibatis的全局配性能的运行,mybatis没有这些性能参数,由mybatis自动调节。置参数中包括很多的性能参数(最大线程数,最大待时间。。。),通过调整这些性能参数使ibatis达到高
5.1.3 typeAliases 指定别名(常用)
可以将parameterType、resultType中指定的类型通过别名引用
在SqlMapConfig.xml文件里自定义别名,在mapper.xml文件使用。
定义:
使用:
5.1.4 mappers 参数说明:
作用:就是加载/注册mapper.xml文件的
操作的文件:SqlMapConfig.xml
目前,这里有三种方式注册,如下图说说:
六、参考例子:
定义UserMapper接口:
package com.xingej.mybatis.mapper;
import java.util.List;
import com.xingej.mybatis.po.User;
import com.xingej.mybatis.po.UserQueryVo;
public interface UserMapper {
// 根据ID来查询用户信息,返回单个对象
public User findUserById(int id);
// 根据用户名称来查询用户信息,返回集合对象
public List<User> findUserByName(String userName);
//
public List<User> findUserList(UserQueryVo userQueryVo);
public void insertUser(User user);
public void deleteUser(int id);
public void updateUser(User user);
}
进行测试:
package com.xingej.mybatis.mapper;
import java.io.InputStream;
import java.util.Date;
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 org.junit.Before;
import org.junit.Test;
import com.xingej.mybatis.po.User;
import com.xingej.mybatis.po.UserCustom;
import com.xingej.mybatis.po.UserQueryVo;
public class UserMapperTest {
// 先创建一个会话工厂
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
// 配置文件(SqlMapConfig.xml)
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
// 根据用户ID来查询用户信息
@Test
public void testFindUserById() {
// 创建一个session
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println("----mapper方式-----:\n" + user);
}
// 根据用户名称来查询用户信息
@Test
public void testFindUserByUserName() {
// 创建一个session
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
List<User> userList = userMapper.findUserByName("小明");
System.out.println("----mapper方式-----:\n" + userList.get(0).getUsername());
}
// 插入用户信息
@Test
public void testInsertUser() {
// 创建一个session
SqlSession session = sqlSessionFactory.openSession();
// 产生代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setAddress("北京");
user.setBirthday(new Date());
user.setSex("1");
user.setUsername("燕青");
userMapper.insertUser(user);
session.commit();
System.out.println("----mapper方式-----:\n");
}
// 删除用户
@Test
public void testDeleteUser() {
// 创建一个session
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
userMapper.deleteUser(1);
session.commit();
}
// 更新用户
@Test
public void testUpdateUser() {
// 创建一个session
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setAddress("北京");
user.setBirthday(new Date());
user.setSex("1");
user.setUsername("燕青");
user.setId(1);
userMapper.updateUser(user);
session.commit();
}
// 通过包装的类型,查询用户的信息
@Test
public void testFindUserList() {
// 创建一个session
SqlSession session = sqlSessionFactory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUsername("小");
userQueryVo.setUserCustom(userCustom);
List<User> userList = userMapper.findUserList(userQueryVo);
session.close();
System.out.println("----->:\t" + userList.size());
}
}
代码已提交到git上:
https://github.com/xej520/xingej-mybatis
转载于:https://blog.51cto.com/xingej/1979555