Mybatis第二章
一、目标
1、mybatis实现CRUD
2、两种Dao开发
3、核心配置文件详解
4、输入参数和输出参数
二、mybatis实现CRUD
a、mybatis 的中文文档网址:http://www.mybatis.org/mybatis-3/zh/getting-started.html
b、 selectList 查询多个对象,返回一个list集合(也能查询一个)
selectOne: 查询单个对象,返回一个对象
c、日志记录日常操作
引入依赖:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
引入日志的配置文件:log4j.properties
d、增删改查
<!--UserMapper删除操作-->
<delete id="del" parameterType="java.lang.Integer">
delete from user where id = #{id}
</delete>
<!--测试类-->
@Test
public void testDel(){
//获取输入流对象
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获取SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession对象
//获取的sqlsession不能自动提交
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句
sqlSession.delete("userMapper.del",3);
//提交:只要修改了数据库必须提交
sqlSession.commit();
sqlSession.close();
}
e、模糊查询
参数: %a%
配置文件: username like #{username}
参数: a
配置文件1: username like "%"#{username}"%"
配置文件2: username like "%${value}%"
如果传的是简单类型必须使用value
如果是pojo,属性名引用
d、参数
简单类型: 基本数据类型,String
如果${} 必须用value引用
如果#{} 随便写
pojo类型:属性名引用
e、${} 与 #{}区别
${}:直接拼接,不会转换类型, 不能防注入
#{}:转换类型后拼接, 相当于占位符?,可以防注入
三、两种Dao开发
1、传统dao开发
1、pom.xml 依赖配置
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
2、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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisdb_sgw?characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cn/sgwks/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>
3、UserMapper.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="userMapper">
<!--查询全部-->
<select id="findAll" resultType="cn.sgwks.domain.User">
select * from user
</select>
<!--根据id查询-->
<!--
id="findById":唯一的标识
resultType="com.itheima.domain.User" :返回值类型
parameterType:参数类型
在mybatis中:引入变量 #{}
1.传递的是对象,里面的${}和#{}参数必须要和对象的属性名一致
2.传递的参数是基本数据类型+String,
#{}里面的参数随意,必须是标识符,不能有标点符号,不能为空
${}里面只能填写value: ${value}
-->
<select id="findById" resultType="cn.sgwks.domain.User" parameterType="java.lang.Integer">
select * from user where id = #{id}
</select>
<!--添加
:不用写返回值类型
参数的名字必须和实体类的属性一致
-->
<insert id="insert" parameterType="cn.sgwks.domain.User">
insert into user values(null ,#{username},#{password},#{sex},#{address},#{birthday});
</insert>
<!--修改-->
<update id="update" parameterType="cn.sgwks.domain.User">
update user set username=#{username},password=#{password},sex=#{sex},address=#{address},birthday=#{birthday}
where id=#{id}
</update>
<!--删除操作-->
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{随意但不能为空}
</delete>
<!--根据姓名模糊查询-->
<select id="findByUsername" resultType="cn.sgwks.domain.User" parameterType="java.lang.String">
select * from user where username like "%"#{随便传递的是基本数据类型}"%"
</select>
<!--模糊查询方法二-->
<!--<select id="findByUsername" resultType="cn.sgwks.domain.User" parameterType="java.lang.String">
select * from user where username like "%${value}%"
</select>-->
<!--查询总的记录数-->
<select id="findTotalCount" resultType="java.lang.Integer">
select count(*) from user
</select>
</mapper>
1、Dao层
package cn.sgwks.dao.impl;
import cn.sgwks.dao.UserDao;
import cn.sgwks.domain.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class UserDaoImpl implements UserDao {
//所有的方法共用的factory对象,应该是属于应用级别
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* 查询所有user表数据
* @return 返回集合类型,遍历
*/
@Override
public List<User> findAll() {
//每一个方法应该获取一个SqlSession对象,用完应该立即关闭,因为线程不安全
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("userMapper.findAll");
//释放资源
sqlSession.close();
return userList;
}
/**
* 添加数据
* @param user 传递user对象
*/
@Override
public void insert(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("userMapper.insert",user);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
/**
* 修改数据
* @param user
*/
@Override
public void update(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("userMapper.update",user);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
/**
* 删除数据
* @param id
*/
@Override
public void delete(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("userMapper.delete",id);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
2、Domain层
public class User {
private Integer id;
private String username;
private String password;
private String sex;
private String address;
private String birthday;
...}
3、测试类
//提升作用域
SqlSessionFactory sqlSessionFactory = null;
/**
* 执行命令前提前初始化
*/
@Before
public void init(){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
/**
* 查询所有数据
*/
@Test
public void testFindAll(){
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
}
/**
* 添加数据
*/
@Test
public void testInsert(){
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = new User();
user.setUsername("索隆");
user.setPassword("suolong");
user.setSex("男");
user.setAddress("大剑客");
user.setBirthday("1995-06-10");
userDao.insert(user);
}
/**
* 添加数据
*/
@Test
public void testUpdate(){
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = new User();
user.setId(3);
user.setUsername("娜美");
user.setPassword("namei");
user.setSex("女");
user.setAddress("航海士");
user.setBirthday("1998-02-11");
userDao.update(user);
}
/**
* 添加数据
*/
@Test
public void testDelete(){
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
userDao.delete(15);
}
2、动态代理模式开发
1、pom.xml
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
2、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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisdb_sgw?characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="cn/sgwks/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>
3、UserMapper.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:必须是对应接口的全限类名
select|update|insert|delete: 四个标签 id必须对应dao接口的方法名
-->
<mapper namespace="cn.sgwks.dao.UserDao">
<select id="findAll" resultType="cn.sgwks.domain.User">
select * from user
</select>
<insert id="insert" parameterType="cn.sgwks.domain.User">
insert into user values(null ,"${username}",#{password},#{sex},#{address},#{birthday})
</insert>
<update id="update" parameterType="cn.sgwks.domain.User">
update user set username=#{username},password=#{password},sex=#{sex},address=#{address},birthday=#{birthday}
where id = #{id}
</update>
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id = #{随意}
</delete>
</mapper>
1、Dao层
package cn.sgwks.dao.impl;
import cn.sgwks.dao.UserDao;
import cn.sgwks.domain.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class UserDaoImpl implements UserDao {
//所有的方法共用的factory对象,应该是属于应用级别
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* 查询所有user表数据
* @return 返回集合类型,遍历
*/
@Override
public List<User> findAll() {
//每一个方法应该获取一个SqlSession对象,用完应该立即关闭,因为线程不安全
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userList = sqlSession.selectList("userMapper.findAll");
//释放资源
sqlSession.close();
return userList;
}
/**
* 添加数据
* @param user 传递user对象
*/
@Override
public void insert(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("userMapper.insert",user);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
/**
* 修改数据
* @param user
*/
@Override
public void update(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("userMapper.update",user);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
/**
* 删除数据
* @param id
*/
@Override
public void delete(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("userMapper.delete",id);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
2、domain层
public class User {
private Integer id;
private String username;
private String password;
private String sex;
private String address;
private String birthday;
...}
3、测试类
package cn.sgwks;
import cn.sgwks.dao.UserDao;
import cn.sgwks.domain.User;
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 java.util.List;
public class TestMybatisProxy {
//提升作用域
SqlSessionFactory sqlSessionFactory = null;
/**
* 执行命令前提前初始化
*/
@Before
public void init(){
sqlSessionFactory = new SqlSessionFactoryBuilder().build(this.getClass().getClassLoader().getResourceAsStream("SqlMapConfig.xml"));
}
@Test
public void testFindAll(){
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Dao接口的动态代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
//释放资源
sqlSession.close();
}
/**
* 添加数据
*/
@Test
public void testInsert(){
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Dao接口的动态代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setUsername("罗宾");
user.setPassword("luobin");
user.setSex("女");
user.setAddress("魔族");
user.setBirthday("1996-09-10");
userDao.insert(user);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
/**
* 修改数据
*/
@Test
public void testUpdate(){
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Dao接口的动态代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = new User();
user.setId(4);
user.setUsername("乔巴");
user.setPassword("qiaoba");
user.setSex("鹿");
user.setAddress("雪上");
user.setBirthday("2018-01-01");
userDao.update(user);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
/**
* 删除数据
*/
@Test
public void testDelete(){
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取Dao接口的动态代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
userDao.delete(13);
//必须自动提交
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
四、核心配置文件详解
1. 配置文件中的标签和顺序
properties?, 配置属性(学习)
settings?, 全局配置:缓存,延迟加载
typeAliases?, 类型别名(学习)
typeHandlers?, 类型转换(操作)(了解)
objectFactory?, objectWrapperFactory?, reflectorFactory?,
plugins?, 插件:分页插件
environments?, 环境配置(数据源)
databaseIdProvider?,
mappers? 引入映射配置文件(学习)
? : 一个或者零个
| : 任选其一
+ : 最少一个
* : 零个或多个
, : 必须按照此顺序编写
五、输入参数类型和输出参数类型
1. 输入参数
简单类型: 基本数据类型+ String类型
#{} :名称随便
${} :${value}
pojo 类型
#{} :${} : 属性名引用
包装对象类型
引用 #{属性.属性名}
Map集合
引用: #{key}
多个参数
引用时:#{param1},#{param2}.....#{paramN}
2. 返回值类型
如果列与属性名不一致,对应的属性为null, 必须写映射配置