02_mybatis开发dao的方法
MyBatis开发dao的方法
1. SqlSession使用范围
1.1 SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
1.2 SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。 将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。
1.3 SqlSession
SqlSession是一个面向用户(程序员)的接口。
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。
SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
**SqlSession*最佳应用场合在方法体内,定义成局部变量使用。
2. 原始dao开发方法
需要写dao接口和dao实现类
2.1 思路
程序员需要写dao接口和dao实现类,需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。
2.2 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 namespace="test">
<!--sql语句-->
<!--通过select查询数据库信息
id:标识映射文件的sql,将SQL语句封装到prepareStatement.称为statementid
-->
<select id="findUserById" parameterType="int" resultType="User">
SELECT * FROM user where id=#{id}
</select>
<!--根据用户名模糊查询用户信息-->
<!--
resultType:表示单条记录所映射的java类型
使用${}表示拼接sql串,将接受到的参数不加任何修饰拼接到sql中
使用${}拼接sql,会引起sql注入,
${value}:接受输入参数的内容,如果传入类型是简单类型,${}中只能是value
-->
<select id="findUserByName" parameterType="java.lang.String" resultType="com.mybatis.po.User">
SELECT * FROM USER WHERE USERNAME LIKE '%${value}%'
</select>
<!--添加用户(非自增主键的返回)-->
<insert id="insertUser" parameterType="com.mybatis.po.User">
<!--
将插入数据的主键返回,返回到user对象中
keyProperty:将查询到的主键值,设置到parameterType(目标对象)的那个属性
order:表示执行顺序
resultType:表示类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address});
</insert>
<!--添加用户1自增主键值的返回-->
<insert id="insertUser1" parameterType="com.mybatis.po.User" useGeneratedKeys="true" keyProperty="id">
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address});
</insert>
<!--删除用户-->
<!--根据用户id删除用户:输入id值-->
<delete id="deleteUserById" parameterType="java.lang.Integer">
DELETE FROM USER WHERE ID=#{ID}
</delete>
<!--更新用户-->
<!--根据用户id,更新,
用户的更新信息
parameterType:指定user对象,包含用户的所有信息
#{id}从user对象中获取user的值
-->
<update id="updateUserById" parameterType="User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
2.3 dao
/**
* Description:演示原始开发方法dao
* User: jiatp
* Date:2019/9/2 0002 下午 10:39
*/
public interface UserDao {
//根据id查询用户信息
public User findUserById(int id) throws Exception;
//添加用户信息
public void insertUser(User user) throws Exception;
//删除用户信息
public void deleteUser(int id) throws Exception;
}
2.4 dao接口实现类
/**
* Description:dao实现类
* User: jiatp
* Date:2019/9/2 0002 下午 10:44
*/
public class UserDaoImpl implements UserDao {
//需要向dao中注入SqlsessionFactory,这里使用构造方法注入
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById",id);
return user;
}
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser",user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUserById",id);
sqlSession.commit();
sqlSession.close();
}
}
2.5 测试代码
/**
* Description:传统dao、dao实现类开发方法
* User: jiatp
* Date:2019/9/3 0003 下午 10:18
*/
public class MyBatisSecond {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws IOException{
//mybatis配置文件
String resource = "com/mybatis/config/sqlMapConfig.xml";
//得到配置文件流
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
}
//查询用户
@Test
public void findById() throws Exception {
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserById(27);
System.out.println(user);
}
//删除用户
@Test
public void deleteUserById() throws Exception {
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
userDao.deleteUser(26);
}
}
2.6 总结原始dao开发问题
1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
2、调用sqlsession方法时将statement的id硬编码了
3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
3. mapper代理开发
**mapper代理开发规范:**程序员还需要编写mapper.xml映射文件;程序员编写mapper接口要遵循一些开发规范,mybatis可以自动实现类代理对象。
**开发规范:***1.mapper.xml中namespace等于mapper接口地址;
<!--namespace-sql的隔离-->
<mapper namespace="com.mybatis.mapper.UserMapper">
<!--sql语句-->
<!--通过select查询数据库信息
id:标识映射文件1的sql,将SQL语句封装到prepareStatement.称为statementid
-->
<select id="findUserById" parameterType="int" resultType="com.mybatis.po.User">
SELECT * FROM user where id=#{id}
</select>
- mapper.java接口中的方法名和mapper.xml中statement的id一致;
- mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致;
- mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致;
以上开发规范主要是对下边的代码进行统一生成。
3.1 mapper.java
/**
* Description:mapper代理开发
* User: jiatp
* Date:2019/9/2 0002 下午 10:39
*/
public interface UserMapper {
//根据id查询用户信息
public User findUserById(int id) throws Exception;
//添加用户信息
public void insertUser(User user) throws Exception;
//删除用户信息
public void deleteUserById(int id) throws Exception;
//根据用户名查询用户列表
public List<User> findUserByName(String name) throws Exception;
}
3.2 mapper.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">
<!--namespace-sql的隔离-->
<mapper namespace="com.mybatis.mapper.UserMapper">
<!--sql语句-->
<!--通过select查询数据库信息
id:标识映射文件1的sql,将SQL语句封装到prepareStatement.称为statementid
-->
<select id="findUserById" parameterType="int" resultType="com.mybatis.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="user">
SELECT * FROM USER WHERE USERNAME LIKE '%${value}%'
</select>
<!--添加用户(非自增主键的返回)-->
<insert id="insertUser" parameterType="com.mybatis.po.User">
<!--
将插入数据的主键返回,返回到user对象中
keyProperty:将查询到的主键值,设置到parameterType(目标对象)的那个属性
order:表示执行顺序
resultType:表示类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address});
</insert>
<!--添加用户1自增主键值的返回-->
<insert id="insertUser1" parameterType="com.mybatis.po.User" useGeneratedKeys="true" keyProperty="id">
<!--
将插入数据的主键返回,返回到user对象中
keyProperty:将查询到的主键值,设置到parameterType(目标对象)的那个属性
order:表示执行顺序
resultType:表示类型
-->
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address});
</insert>
<!--删除用户-->
<!--根据用户id删除用户:输入id值-->
<delete id="deleteUserById" parameterType="java.lang.Integer">
DELETE FROM USER WHERE ID=#{ID}
</delete>
<!--更新用户-->
<!--根据用户id,更新,
用户的更新信息
parameterType:指定user对象,包含用户的所有信息
#{id}从user对象中获取user的值
-->
<update id="updateUserById" parameterType="com.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
3.3 测试
/**
* Description:测试mapper.java mapper.xml
* User: jiatp
* Date:2019/9/3 0003 上午 9:08
*/
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws IOException {
//mybatis配置文件
String resource = "com/mybatis/config/sqlMapConfig.xml";
//得到配置文件流
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
}
//根据id查询用户
@Test
public void testFindById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建userMapper对象,mybatis自动代理生成mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(27);
System.out.println(user);
sqlSession.close();
}
//插入用户
@Test
public void testInsertUser() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建userMapper对象,mybatis自动代理生成mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("东方不败");
user.setSex("2");
user.setBirthday(new Date());
user.setAddress("北京东城");
mapper.insertUser(user);
//不要忘记增删改,完了要提交和关闭资源
sqlSession.commit();
sqlSession.close();
}
// 删除用户
@Test
public void testDeleteUser() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建userMapper对象,mybatis自动代理生成mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUserById(196);
//不要忘记增删改,完了要提交和关闭资源
sqlSession.commit();
sqlSession.close();
}
//根据用户名称查询用户列表
@Test
public void findUserByName() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建userMapper对象,mybatis自动代理生成mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.findUserByName("小明");
for(User user:list) {
System.out.println(user);
}
/* User user = mapper.findUserByName("小明");
System.out.println(user);*/
sqlSession.close();
}
}
4. 问题总结
4.1 代理对象内部调用selectOne或selectList
1.如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
2.如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
4.2 mapper接口方法参数只能有一个是否影响系统 开发
1.mapper接口方法参数只能有一个,系统是否不利于扩展维护。
2.系统 框架中,dao层的代码是被业务层公用的。即使mapper接口只有一个参数,可以使用包装类型的pojo****满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型、map。service方法中建议不要使用包装类型(不利于业务层的可扩展)。
02_mybatis开发dao的方法的更多相关文章
- MyBatis学习--mybatis开发dao的方法
简介 使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法. 主要概念介绍: MyBatis中进行Dao开发时候有几个重要的类,它们是SqlSessionFac ...
- 11Mybatis_mybatis开发Dao的方法
在介绍开发Dao的方法之前先介绍下SqlSession. 1.先介绍一下SqlSessionFactoryBuilder:通过SqlSessionFactoryBuilder创建会话工厂SqlSess ...
- 四 mybatis开发dao的方法
mybatis开发dao的方法 1.1 SqlSession使用范围 1.1.1 SqlSessionFactoryBuilder //以流的方式读取总的配置文件 Reader rea ...
- mybatis由浅入深day01_5mybatis开发dao的方法(5.1SqlSession使用范围_5.2原始dao开发方法)
5 mybatis开发dao的方法 5.1 SqlSession使用范围 5.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂 ...
- mybatis学习记录二——mybatis开发dao的方法
4.1 SqlSession使用范围 4.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSession ...
- Mybatis学习记录(二)----mybatis开发dao的方法
1 SqlSession使用范围 1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory 将Sq ...
- mybatis系列-04-mybatis开发dao的方法
4.1 SqlSession使用范围 4.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSession ...
- mybatis开发dao的方法——(三)
------------------------1. SqlSession使用范围------------------- 1.1 SqlSessionFactoryBuilder 通过S ...
- Mybatis 开发 dao 的方法
1.分析SqlSession使用范围 1.1.SqlSessionFactoryBuilder 通过 SqlSessionFactoryBuilder 创建会话工厂 SqlSessionFactory ...
随机推荐
- leetcood学习笔记-203-移除链表元素
题目描述: 方法:#在改pre链表时 head中的值也改变 class Solution(object): def removeElements(self, head, val): "&qu ...
- (转)元类metaclass
阅读目录 一 前言 二 什么是元类 三 class关键字创建类的流程分析 五 自定义元类控制类OldboyTeacher的创建 六 自定义元类控制类OldboyTeacher的调用 六 再看属性查找 ...
- AtCoder ABC 130F Minimum Bounding Box
题目链接:https://atcoder.jp/contests/abc130/tasks/abc130_f 题目大意 给定地图上 N 个点的坐标和移动方向,它们会以每秒 1 个单位的速度移动,设 A ...
- linux mysql udf 提权
连接远程数据库 查看插件库路径 show variables like '%plugin%'; 写入udf库到插件目录: 32位: select unhex('7F454C46020101000000 ...
- 剑指offer——27二叉树的镜像
题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ ...
- CSS3教程:Responsive框架常见的Media Queries片段
CSS3 Media Queries片段在这里主要分成三类:移动端.PC端以及一些常见的响应式框架的Media Queries片段.移动端Media Queries片段iPhone5@media sc ...
- 初探分布式环境的指挥官ZooKeeper
目录 1. 从单机到集群,分布式环境中的挑战 1.1 集中式的特点 1.2 集中式的痛点 1.3 从单体到SOA的转变 1.4 分布式服务总体框架 1.5 分布式应用概述 2. ZK基本概念及核心原理 ...
- Spring Cloud Feign设计原理
什么是Feign? Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直 ...
- 「LibreOJ NOI Round #2」签到游戏
题目 瞎猜一下我们只要\(n\)次询问就能确定出\(\{A_i\}\)来 感受一下大概是询问的区间越长代价就越小,比如询问\([l,n]\)或\([1,r]\)的代价肯定不会超过\([l,r]\) 所 ...
- 23种常用设计模式的UML类图
23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...