普通方式实现CRUD
user.java
public class User {
private Long id;
// 用户名
private String userName;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别,1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 创建时间
private Date created;
// 更新时间
private Date updated;
//getter and setter
}
public interface UserDAO {
/**
* 根据id查询用户数据
*
* @param id
* @return
*/
public User queryUserById(Long id);
/**
* 新增user数据
*
* @param user
*/
public void saveUser(User user);
/**
* 更新user数据
*
* @param user
*/
public void updateUser(User user);
/**
* 根据id删除用户数据
*
* @param id
*/
public void deleteUserById(Long id);
}
定义实现类UserDAOImpl.java
public class UserDAOImpl implements UserDAO{
private SqlSessionFactory sqlSessionFactory;
public UserDAOImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User queryUserById(Long id) {
SqlSession session = this.sqlSessionFactory.openSession();
User user = session.selectOne("userDAO.queryUserById", id);
session.close();
return user;
}
@Override
public void saveUser(User user) {
SqlSession session = this.sqlSessionFactory.openSession();
session.insert("userDAO.saveUser", user);
//提交事物
session.commit();
session.close();
}
@Override
public void updateUser(User user) {
SqlSession session = this.sqlSessionFactory.openSession();
session.update("userDAO.updateUser", user);
//提交事物
session.commit();
session.close();
}
@Override
public void deleteUserById(Long id) {
SqlSession session = this.sqlSessionFactory.openSession();
session.delete("userDAO.deleteUserById", id);
//提交事物
session.commit();
session.close();
}
}
编写UserDAOMapper.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="userDAO">
<select id="queryUserById" resultType="cn.zto.mybatis.pojo.User">
SELECT *,user_name userName FROM tb_user WHERE id = #{id}
</select>
<insert id="saveUser" parameterType="cn.zto.mybatis.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
NULL,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>
<update id="updateUser" parameterType="cn.zto.mybatis.pojo.User">
UPDATE tb_user
SET
user_name = #{userName},
password = #{password},
name = #{name},
age = #{age},
sex = #{sex},
birthday = #{birthday},
updated = NOW()
WHERE
id = #{id}
</update>
<delete id="deleteUserById">
DELETE FROM tb_user WHERE id = #{id}
</delete>
</mapper>
定义全局配置文件mybaits-config.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>
<!-- 加载配置文件 -->
<properties resource="jdbc.properties"/>
<settings>
<!-- 开启驼峰映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--
配置环境,数据库连接
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserDAOMapper.xml" />
</mappers>
</configuration>
package cn.zto.mybatis.dao.impl;
import java.io.InputStream;
import java.util.Date;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import cn.zto.mybatis.dao.UserDAO;
import cn.zto.mybatis.dao.impl.UserDAOImpl;
import cn.zto.mybatis.pojo.User;
/**
* @Description: 普通方式实现crud
* @author xingyuchao
* @date 2016年8月2日 下午3:13:00
* @version V1.0
*/
public class UserDAOImplTest {
private UserDAO userDAO;
@Before
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
this.userDAO = new UserDAOImpl(sqlSessionFactory);
}
@Test
public void testQueryUserById() {
User user = this.userDAO.queryUserById(2L);
System.out.println(user);
}
@Test
public void testSaveUser() {
User user = new User();
user.setAge(20);
user.setBirthday(new Date());
user.setName("test_1");
user.setPassword("123456");
user.setSex(1);
user.setUserName("test_username_1");
this.userDAO.saveUser(user);
}
@Test
public void testUpdateUser() {
User user = this.userDAO.queryUserById(2L);
user.setAge(40);
this.userDAO.updateUser(user);
}
@Test
public void testDeleteUserById() {
this.userDAO.deleteUserById(5L);
}
}
实现DAO接口中的问题
1、 实现比较繁琐,接口-->实现类 --> Mapper.xml
2、 实现类中使用Mybatis的方法非常的类似
3、 sql statement 硬编码到java代码中。
思考:能否只编写接口,不写实现类,编写Mapper.xml即可?
动态代理方式实现CRUD
流程:
1.mybatis首先读取全局配置文件mybatis-config.xml
2.加载UserDAO2Mapper.xml,读到命名空间找到相应的接口,找到接口中的方法名和statement中的id相互对应起来之后,帮我们生成一个动态代理的实现类,因此我们就不需要自己手动写实现类了.
UserDAOImplTest2.java
package cn.zto.mybatis.dao.impl;
import java.io.InputStream;
import java.util.Date;
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 cn.zto.mybatis.dao.UserDAO;
import cn.zto.mybatis.pojo.User;
/**
*
* @Description: 动态代理实现类测试用例
* @author xingyuchao
* @date 2016年8月2日 下午3:13:38
* @version V1.0
*/
public class UserDAOImplTest2 {
private UserDAO userDAO;
@Before
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//build方法也可以配置数据库连接使用哪一个
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"test");
//注意:这里没有了实现类,需要将事务设置为自动
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//通过sqlSession获取到动态代理的实现类
this.userDAO = sqlSession.getMapper(UserDAO.class);
}
@Test
public void testQueryUserById() {
User user = this.userDAO.queryUserById(1L);
System.out.println(user);
}
@Test
public void testSaveUser() {
User user = new User();
user.setAge(20);
user.setBirthday(new Date());
user.setName("test_3");
user.setPassword("123456");
user.setSex(1);
user.setUserName("test_username_3");
this.userDAO.saveUser(user);
}
@Test
public void testUpdateUser() {
User user = this.userDAO.queryUserById(2L);
user.setAge(35);
this.userDAO.updateUser(user);
}
@Test
public void testDeleteUserById() {
this.userDAO.deleteUserById(7L);
}
}
UserDAO2Mapper.xml
Mapper中Namespace的定义本身是没有限制的,只要不重复即可,但是如果要想使用Mybatis提供的DAO的动态代理,namespace必须为mapper接口的全路径
mybatis-config.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="cn.zto.mybatis.dao.UserDAO">
<select id="queryUserById" resultType="User" parameterType="Long">
SELECT * FROM tb_user WHERE id = #{id}
</select>
<insert id="saveUser" parameterType="cn.zto.mybatis.pojo.User">
INSERT INTO tb_user (
id,
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
NULL,
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
</insert>
<update id="updateUser" parameterType="cn.zto.mybatis.pojo.User">
UPDATE tb_user
SET
user_name = #{userName},
password = #{password},
name = #{name},
age = #{age},
sex = #{sex},
birthday = #{birthday},
updated = NOW()
WHERE
id = #{id}
</update>
<delete id="deleteUserById">
DELETE FROM tb_user WHERE id = #{id}
</delete>
</mapper>
<?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>
<!-- 加载配置文件 -->
<properties resource="jdbc.properties"/>
<settings>
<!-- 开启驼峰映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<!-- <typeAlias type="cn.zto.mybatis.pojo.User" alias="User"/> -->
<!--
配置扫描包,更适合企业开发
-->
<package name="cn.zto.mybatis.pojo" />
</typeAliases>
<!--
配置环境,数据库连接
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserDAO2Mapper.xml" />
</mappers>
</configuration>
其他的实体等一样
使用mapper接口不用写接口实现类即可完成数据库操作,使用非常简单,也是官方所推荐的使用方法。
使用mapper接口的必须具备以几个条件:
使用mapper接口的必须具备以几个条件:
- Mapper的namespace必须和mapper接口的全路径一致。
- Mapper接口的方法名必须和sql定义的id一致。
- Mapper接口中方法的输入参数类型必须和sql定义的parameterType一致(parameterType可以省略)。
- Mapper接口中方法的输出参数类型必须和sql定义的resultType一致。