public class User {
private Integer id;
private String userName;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
'}';
}
}
import com.example.mybatis.domain.User;
import com.example.mybatis.service.impl.UserServiceImpl;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
/**
* @Description:
* @Author: baxiang
* @Date: 2021/8/31.
*/
public class UserServiceTest {
private InputStream is;
private UserService userService;
private SqlSession sqlSession;
@Before
public void setUp() throws Exception {
String resource = "mybatis-config.xml";
// 读取配置文件
is = Resources.getResourceAsStream(resource);
// 构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// 获取sqlSession
sqlSession = sqlSessionFactory.openSession();
this.userService = new UserServiceImpl(sqlSession);
}
@After
public void tearDown() throws Exception {
sqlSession.commit();
sqlSession.close();
is.close();
}
@Test
public void queryUserById() {
System.out.println(this.userService.queryUserById(1));
}
@Test
public void insertUser() {
User user = new User();
user.setUserName("test");
user.setPassword("123456");
this.userService.insertUser(user);
this.sqlSession.commit();
}
@Test
public void updateUser() {
User user = new User();
user.setId(1);
user.setUserName("Test1");
user.setPassword("654321");
this.userService.updateUser(user);
this.sqlSession.commit();
}
@Test
public void deleteUserById() {
this.userService.deleteUserById(1);
this.sqlSession.commit();
}
}
mybatis-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>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test?useSSL=false&characterEncoding=utf-8&allowMultiQueries=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
<!-- 全局设置 -->
<settings>
<!-- 使用jdbc的getGeneratedKeys 获取数据库自增主键值 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 开启驼峰命名转换 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 环境,可以配置多个,default:指定采用哪个环境 -->
<environments default="dev">
<!-- id:唯一标识 -->
<environment id="dev">
<!-- 事务管理器,JDBC类型的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,池类型的数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}" /> <!-- 配置了properties,所以可以直接引用 -->
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/UserMapper.xml" />
</mappers>
</configuration>
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:命名空间,保证命名空间唯一 -->
<mapper namespace="UserMapper">
<!--获取用户-->
<select id="selectUser" resultType="com.example.mybatis.domain.User">
SELECT
id ,
user_name ,
password
FROM
user
WHERE id = #{id};
</select>
<!--插入数据-->
<insert id="insertUser" parameterType="com.example.mybatis.domain.User">
INSERT INTO user (
user_name,
password
)
VALUES
(
#{userName},
#{password}
);
</insert>
<update id="updateUser" parameterType="com.example.mybatis.domain.User">
UPDATE user
<trim prefix="set" suffixOverrides=",">
<if test="userName!=null">user_name = #{userName},</if>
<if test="password!=null">password = #{password},</if>
</trim>
WHERE
(id = #{id});
</update>
<delete id="deleteUser">
DELETE FROM user WHERE id=#{id}
</delete>
</mapper>
接口类
public interface UserService {
/**
* 根据id查询用户信息
*
* @param id
* @return
*/
User selectUser(Integer id);
/**
* 新增用户
*
* @param user
*/
void insertUser(User user);
/**
* 更新用户信息
*
* @param user
*/
void updateUser(User user);
/**
* 根据id删除用户信息
*
* @param id
*/
void deleteUser(Integer id);
}
UserServiceImpl
�
import com.example.mybatis.domain.User;
import com.example.mybatis.service.UserService;
import org.apache.ibatis.session.SqlSession;
public class UserServiceImpl implements UserService {
private SqlSession sqlSession;
public UserServiceImpl(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public User selectUser(Integer id) {
return this.sqlSession.selectOne("UserMapper.selectUser", id);
}
@Override
public void insertUser(User user) {
this.sqlSession.insert("UserMapper.insertUser", user);
}
@Override
public void updateUser(User user) {
this.sqlSession.update("UserMapper.updateUser", user);
}
@Override
public void deleteUser(Integer id) {
this.sqlSession.delete("UserMapper.deleteUser", id);
}
}
动态代理Mapper
- 接口->实现类->mapper.xml
- 2、实现类中,使用mybatis的方式非常类似
- 3、xml中的sql statement 硬编码到java代码中。
思考:能否只写接口,不写实现类。只编写接口和Mapper.xml即可?
因为在dao(mapper)的实现类中对sqlsession的使用方式很类似。因此mybatis提供了接口的动态代理。
import com.example.mybatis.domain.User;
public interface UserMapper {
/**
* 根据id查询用户信息
*
* @param id
* @return
*/
User selectUser(Integer id);
/**
* 新增用户
*
* @param user
*/
void insertUser(User user);
/**
* 更新用户信息
*
* @param user
*/
void updateUser(User user);
/**
* 根据id删除用户信息
*
* @param id
*/
void deleteUser(Integer id);
}
,在UserMapper.xml中配置接口的全路径
mapper.xml namespace
如果希望使用mybatis通过的动态代理的接口,就需要namespace中的值,和需要对应的Mapper(dao)接口的全路径一致。Mapper中Namespace的定义本身是没有限制的,只要不重复即可,但如果使用Mybatis的DAO接口动态代理,则namespace必须为DAO接口的全路径,例如:com.example.mybatis.mapper.UserMapper
�
// 1. 映射文件的命名空间(namespace)必须是mapper接口的全路径
// 2. 映射文件的statement的id必须和mapper接口的方法名保持一致
// 3. Statement的resultType必须和mapper接口方法的返回类型一致
// 4. statement的parameterType必须和mapper接口方法的参数类型一致(不一定)