您的位置:首页 > 编程语言 > Java开发

Mybatis学习笔记(五)——DAO开发

2018-03-18 17:01 330 查看

本博客源码下载:戳我一下

Mybatis学习笔记汇总:戳我一下

一、原始Dao开发方式

1、这里配置文件仍然使用在Mybatis学习笔记(三)——入门程序中的配置文件。

2、写一个Dao接口

package com.jiayifan.dao;

import com.jiayifan.po.User;

/**
* dao接口,用户管理
* @author 贾一帆
*
*/
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;
}


3、写一个Dao接口的实现类

package com.jiayifan.dao;

import java.util.Date;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import com.jiayifan.po.User;

/**
* dao接口实现类
* @author 贾一帆
*
*/
public class UserDaoImpl implements UserDao {
//需要向dao实现类注入SQLSessionFactory
//这里通过构造方法注入
private SqlSessionFactory sqlSessionFactory = null;
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);
sqlSession.close();
return user;
}

@Override
public void insertUser(User user) throws Exception {
// TODO Auto-generated method stub
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
sqlSession.insert("test.insertUser",user);
System.out.println(user.getId());
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}

@Override
public void deleteUser(int id) throws Exception {
// TODO Auto-generated method stub
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser",id);
sqlSession.commit();
sqlSession.close();
}

}


4、测试代码和运行情况

package com.jiayifan.dao;

import static org.junit.jupiter.api.Assertions.*;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.jiayifan.po.User;

class UserDaoImplTest {
private SqlSessionFactory sessionFactory;
//此方法是在所有方法执行之前执行
@BeforeEach
void setUp() throws Exception {
//创建SqlSessionFactory
//Mybatis的配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}

@Test
void testFindUserById() throws Exception {
//创建一个UserDao对象
UserDao userDao = new UserDaoImpl(sessionFactory);
//调用UserDao方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}


DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
Sun Mar 18 16:50:11 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
DEBUG [main] - Created connection 1582028874.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e4bd84a]
DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e4bd84a]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@5e4bd84a]
DEBUG [main] - Returned connection 1582028874 to pool.
User [id=1, username=hahaha, sex=null, birthday=Sun Mar 18 00:00:00 CST 2018, address=null]


5、总结原始Dao开发中的问题

Dao方法体存在重复代码:通过
SqlSessionFactory
创建
SqlSession
,调用
SqlSession
的数据库操作方法

调用
sqlSession
的数据库操作方法需要指定
statement
id
,这里存在硬编码,不得于开发维护。

二、Mapper动态代理方式开发Dao

1、实现原理

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

Mapper.xml文件中的namespace与mapper接口的类路径相同。

Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同

Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

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有特殊的作用,namespace等于mapper接口地址
-->
<mapper namespace="com.jiayifan.mapper.UserMapper">
<!-- 在映射文件中配置很多sql语句 -->
<!-- 通过select执行查询数据库操作
id:标识映射文件中的sql。称为statement的id
#{}表示一个占位符
parameterType:指定输入参数的类型,这里指定int型,与数据库中类型对应
#{id}:其中id表示接收输入的参数,参数名称就是id,如果输入的参数是简单类型
#{}中的参数名可以任意。
resultType:指定sql输出结果所映射的java对象类型
-->
<select id="findUserById" parameterType="int"
resultType="com.jiayifan.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="com.jiayifan.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<!--
添加用户
parameterType:指定的输入参数类型是pojo(用户信息)
#{}中指定pojo的属性名,接收到pojo的属性值
-->
<insert id="insertUser" parameterType="com.jiayifan.po.User">
<!--
将插入的主键返回,返回到User对象中
select last_insert_id():得到刚插入进的记录的主键值,只适用于自增长
keyProperty:将查询的主键值设置到parameterType指定对象的那个属性
order:select last_insert_id()相对于insert语句来说执行顺序
resultType:指定select last_insert_id()的结果类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
INSERT INTO user(username,birthday,sex,address)VALUE(
#{username},#{birthday},#{sex},#{address})
</insert>
<!-- 删除用户
根据id删除用户,需要输入id值
-->
<delete id="deleteUser" parameterType="java.lang.Integer" >
delete from user where id=#{id}
</delete>
<!--
更新用户,根据id更新,需要输入用户id,以及更新信息
-->
<update id="updateUser" parameterType="com.jiayifan.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>


3、在
SqlMapConfig.xml
配置
Mapper.xml


<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>


4、写一个
Mapper.java(接口文件)


接口定义有如下特点:

Mapper
接口方法名和
Mapper.xml
中定义的statement的id相同

Mapper
接口方法的输入参数类型和
mapper.xml
中定义的statement的
parameterType
的类型相同

Mapper
接口方法的输出参数类型和
mapper.xml
中定义的statement的
resultType
的类型相同

package com.jiayifan.mapper;

import java.util.List;

import com.jiayifan.po.User;

/**
* mapper接口
* @author 贾一帆
*
*/
public interface UserMapper {
//根据ID查询用户信息
public User findUserById(int id) throws Exception;
//根据name查询用户信息
public List<User> findUserByName(String name) throws Exception;
//添加用户信息
public void insertUser(User user) throws Exception;
//删除用户信息
public void deleteUser(Integer id) throws Exception;
}


5、测试代码和运行结果

package com.jiayifan.mapper;

import static org.junit.jupiter.api.Assertions.*;

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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.jiayifan.po.User;

class UserMapperTest {
private SqlSessionFactory sessionFactory;
@BeforeEach
void setUp() throws Exception {
//创建SqlSessionFactory
//Mybatis的配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}

@Test
void testFindUserById() throws Exception {
SqlSession sqlSession = sessionFactory.openSession();
//得到UserMapper对象,Mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper方法
User user = userMapper.findUserById(28);
System.out.println(user);
sqlSession.close();
}

@Test
void testFindUserByName() throws Exception {
SqlSession sqlSession = sessionFactory.openSession();
//得到UserMapper对象,Mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper方法
List<User> list = userMapper.findUserByName("%小明%");
System.out.println(list);
sqlSession.close();
}

@Test
void testInsertUser() throws Exception {
SqlSession sqlSession = sessionFactory.openSession();
//得到UserMapper对象,Mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper方法
User user = new User();
user.setUsername("朱奇瑞");
user.setAddress("河南");
user.setBirthday(new Date());
user.setSex("1");
userMapper.insertUser(user);
sqlSession.commit();
System.out.println(user.getId());
sqlSession.close();
}

@Test
void testDeleteUser() throws Exception {
SqlSession sqlSession = sessionFactory.openSession();
//得到UserMapper对象,Mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper方法
userMapper.deleteUser(27);
sqlSession.commit();
sqlSession.close();
}
}


DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
Sun Mar 18 16:59:32 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
DEBUG [main] - Created connection 2117173674.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7e3181aa]
DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE username LIKE '%%小明%%'
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 3
[User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州], User [id=22, username=陈小明, sex=1, birthday=null, address=河南郑州], User [id=25, username=陈小明, sex=1, birthday=null, address=河南郑州]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7e3181aa]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@7e3181aa]
DEBUG [main] - Returned connection 2117173674 to pool.


6、总结

selectOne
selectList


动态代理对象调用
sqlSession.selectOne()
sqlSession.selectList()
是根据mapper接口方法的返回值决定,如果返回
list
则调用
selectList
方法,如果返回单个对象则调用
selectOne
方法。

namespace


mybatis
官方推荐使用
mapper
代理方法开发
mapper接口
,程序员不用编写
mapper接口
实现类,使用
mapper
代理方法时,输入参数可以使用
pojo
包装对象或
map
对象,保证
dao
的通用性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java mybatis