dao包
UserMapper接口
package com.itheima.dao;
import com.itheima.pojo.User;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface UserMapper {
/*
需求1 : 查询id是1的用户信息
定义接口方法 : User selectUserById(Integer id);
*/
public abstract User selectUserById(Integer id);
/*
练习2 :向数据库添加一行数据
定义接口方法:void addUser(User user);
*/
public abstract void addUser(User user);
/*
练习3 : 根据id修改用户数据
定义接口方法 : void updateUser(User user);
*/
public abstract void updateUser(User user);
/*
练习4 : 根据id删除用户数据
定义接口方法 : void deleteById(Integer id);
*/
public abstract void deleteById(Integer id);
/*
练习5 : 根据id查找用户
定义接口方法 : User selectUserById2(Integer id);
*/
public abstract User selectUserById2(Integer id);
/*
练习6 : 根据用户名和性别查询用户
定义接口方法 : List<User> findUsersByUserNameAndSex(String name,String sex);
*/
public abstract List<User> findUsersByUserNameAndSex(@Param("name") String name, @Param("sex") String sex);
/*
练习7 : 向数据库中增加一行数据,接口参数是复杂类型(POJO实体类)
定义接口方法 : void saveUser(User user);
*/
public abstract void saveUser(User user);
/*
练习8 : 根据用户名和性别查询用户信息,入参为Map集合,泛型都是String类型分别表示用户名和性别。
定义接口方法 : queryByNameAndSex(Map map);
*/
public abstract List<User> queryByNameAndSex(Map map);
/*
练习9 : 新增一条数据,查看自增主键回填效果
定义接口方法 : void addUserAndGetId(User user);
*/
public abstract void addUserAndGetId(User user);
/*
练习10 : 根据用户名和地址查找用户,演示sql注入的问题
定义接口方法 : List<User> queryUserByNameAndAddress(@Param("name") String name , @Param("address") String address);
*/
public abstract List<User> queryUserByNameAndAddress(@Param("name") String name, @Param("address") String address);
/*
练习11 : 根据输入的表名统计指定表下的总记录数;
定义接口方法 : Integer countByTableName(@Param("tableName") String tableName);
*/
public abstract Integer countByTableName(@Param("tableName") String tableName);
/*
练习12 : ${}获取配置文件中的值
因为${key}可以获取外部配置文件中键所对应的值, 所以参数中的标识符( @Param(标识符) ) 不要和配置文件中的key相同
定义接口方法 : List<User> queryByUserName(String username)
*/
public abstract List<User> queryByUserName(@Param("username") String username);
/*
练习13 : 查询id是1的数据,将查询的结果封装到Map<String,Object>中
定义接口方法 : Map<String,Object> findMapById(@Param("id") Integer id);
*/
public abstract Map<String, Object> findMapById(@Param("id") Integer id);
/*
练习14 : 获取所有用户,其中key为id值,value为user对象
@MapKey("id")
Map<Integer,User> findAllToMap();
*/
@MapKey("id")
public abstract Map<Integer, User> findAllToMap();
/*
练习15 : 查询id是1的用户 , 需要注释核心配置文件中的经典驼峰命名映射
定义接口方法 : User selectUserById3(@param("id")Integer id);
*/
public abstract User selectUserById3(@Param("id") Integer id);
}
pojo文件夹
User类
package com.itheima.pojo;
import java.util.Date;
public class User {
private Integer id;
private String userName;
private Date birthday;
private Character sex;
private String address;
public User() {
}
public User(Integer id, String userName, Date birthday, Character sex, String address) {
this.id = id;
this.userName = userName;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
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 Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Character getSex() {
return sex;
}
public void setSex(Character sex) {
this.sex = sex;
}
public String getAdd() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + userName + '\'' +
", birthday=" + birthday +
", sex=" + sex +
", address='" + address + '\'' +
'}';
}
}
utils工具包
SessionFactoryUtils
package com.itheima.util;
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 java.io.IOException;
public class SessionFactoryUtils {
// 私有构造方法,防止外界创建对象
private SessionFactoryUtils() {
}
// 定义成成员变量,整个类去使用
private static SqlSessionFactory sessionFactory;
/*
1 在静态代码块中创建会话工厂对象
*/
static {
// 1 获取会话工厂创建类对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2 加载mybatis核心配置文件,获取会话工厂对象
// SqlSessionFactory sessionFactory = builder.build(MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml"));
try {
sessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
/*
2 编写静态方法得到会话对象,设置自动提交事务
*/
public static SqlSession getSqlSession() {
// 获取会话对象 , 设置自动提交事务
SqlSession sqlSession = sessionFactory.openSession(true);
return sqlSession;
}
/*
3 编写静态方法得到会话对象,方法接收调用者传递的布尔类型,决定是否自动提交事务
*/
public static SqlSession getSqlSession(boolean isAutoCommit) {
// 获取会话对象 , 设置自动提交事务
SqlSession sqlSession = sessionFactory.openSession(isAutoCommit);
return sqlSession;
}
/*
4 编写静态方法接收会话对象,手动提交事务并且关闭会话
*/
public static void closeSession(SqlSession sqlSession) {
if (sqlSession != null) {
// 手动提交事务
sqlSession.commit();
// 关闭会话对象
sqlSession.close();
}
}
/*
5 编写静态方法接收会话对象,回滚事务并且关闭会话
*/
public static void rollBack(SqlSession sqlSession) {
if (sqlSession != null) {
// 回滚事务
sqlSession.rollback();
// 关闭会话对象
sqlSession.close();
}
}
}
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="com.itheima.dao.UserMapper">
<!--
需求1 : 查询id是1的用户信息
public abstract User selectUserById(Integer id);
1 查询语句使用 select 标签
2 id属性的值 : 接口方法名
3 parameterType属性的值 : 表示此方法入参的类型 , 可以写别名
4 resultType属性的值 : 表示此方法返回值类型 , 可以写别名
-->
<select id="selectUserById" parameterType="int" resultType="user">
select *
from user
where id = #{id}
</select>
<!--
练习2 :向数据库添加一行数据
定义接口方法:void addUser(User user);
1 添加数据使用insert标签
2 id表示接口中抽象方法名
3 没有返回值属性
4 获取实体类的对象值通过 #{成员变量名}
-->
<insert id="addUser">
insert into user
values (null, #{userName}, #{birthday}, #{sex}, #{address})
</insert>
<!--
练习3 : 根据id修改用户数据
定义接口方法 : void updateUser(User user);
1 修改数据使用update标签
2 id表示接口中抽象方法名
3 没有返回值属性
4 获取实体类的对象值通过 #{成员变量名}
-->
<update id="updateUser">
update user
set user_name = #{userName},
sex = #{sex}
where id = #{id}
</update>
<!--
练习4 : 根据id删除用户数据
定义接口方法 : void deleteById(Integer id);
1 修改数据使用update标签
2 id表示接口中抽象方法名
3 没有返回值属性
4 获取接口的方法的实参值 #{变量名}
-->
<delete id="deleteById">
delete
from user
where id = #{id}
</delete>
<!--
练习5 : 根据id查找用户
定义接口方法 : User selectUserById2(Integer id);
1 id属性值 : 书写接口中的方法名
2 resultType属性值 : 书写抽象方法的返回值类型 , 可以写别名
3 如果入参是简单类型 , 并且是一个参数 , 那么获取方式 #{任意标识符} , 标识符最好见名之意
-->
<select id="selectUserById2" resultType="user">
select *
from user
where id = #{id}
</select>
<!--
练习6 : 根据用户名和性别查询用户
定义接口方法 : List<User> findUsersByUserNameAndSex(String name,String sex);
1 查询标签使用select
2 id属性值为 : 接口中方法的名字
3 resultType属性值: 方法的返回值类型 , 可以写别名
4 如果方法的参数是多个,那么有三种方式可以获取实参的值
方式1 : #{arg0} 代表第一个参数值 , #{arg1} 代表第二个参数值
方式2 : #{param1}代表第一个参数值 , #{param2}代表第二个参数值
方式3 : 定义接口时. 给接口的参数设置注解 , 获取时只要使用#{给定的注解名即可} 推荐方式!!
-->
<select id="findUsersByUserNameAndSex" resultType="user">
select *
from user
where user_name = #{name}
and sex = #{sex}
</select>
<!--
练习7 : 向数据库中增加一行数据,接口参数是复杂类型(POJO实体类)
定义接口方法 : void saveUser(User user);
1 插入数据使用insert标签
2 id的属性值 : 书写接口中抽象方法名saveUser
3 如果入参是复杂类型POJO ,那么获取对象的属性的方式是
方式1 : #{成员变量名}
方式2 : getXxx方法 去调用 get 大X变小x 举例 : getAdd ==> add 了解!!!
-->
<insert id="saveUser">
insert into user
values (null, #{userName}, #{birthday}, #{sex}, #{add})
</insert>
<!--
练习8 : 根据用户名和性别查询用户信息,入参为Map集合,泛型都是String类型分别表示用户名和性别。
定义接口方法 : queryByNameAndSex(Map map);
-->
<select id="queryByNameAndSex" resultType="user">
select *
from user
where user_name = #{userName}
and sex = #{gender}
</select>
<!--
练习9 : 新增一条数据,查看自增主键回填效果
定义接口方法 : void addUserAndGetId(User user);
-->
<insert id="addUserAndGetId" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into user
values (null, #{userName}, #{birthday}, #{sex}, #{address})
</insert>
<!--
练习10 : 根据用户名和地址查找用户,演示sql注入的问题
定义接口方法 : List<User> queryUserByNameAndAddress(@Param("name") String name , @Param("address") String address);
-->
<select id="queryUserByNameAndAddress" resultType="user">
select *
from user
where user_name = #{name}
and address = #{address}
</select>
<!--
练习11 : 根据输入的表名统计指定表下的总记录数;
定义接口方法 : Integer countByTableName(@Param("tableName") String tableName);
-->
<select id="countByTableName" resultType="int">
select count(id)
from ${tableName}
</select>
<!--
练习12 : ${}获取配置文件中的值
定义接口方法 : List<User> queryByUserName(String username)
-->
<select id="queryByUserName" resultType="user">
select *
from user
where user_name = '${username}'
</select>
<!--
练习13 : 查询id是1的数据,将查询的结果封装到Map<String,Object>中
定义接口方法 : Map<String,Object> findMapById(@Param("id") Integer id);
注意 : 如果方法的返回值是一个Map并且是一条数据, 那么字段名作为Map集合键 , 字段值对应Map集合的值
-->
<select id="findMapById" resultType="map">
select *
from user
where id = #{id}
</select>
<!--
练习14 : 获取所有用户,其中key为id值,value为user对象
@MapKey("id")
Map<Integer,User> findAllToMap();
注意 : 如果resultType返回的是一个Map集合 , 并且是多条数据 , 需要在方法上加上注解@MapKey("集合中的字段")
-->
<select id="findAllToMap" resultType="map">
select *
from user
</select>
<!--
练习15 : 查询id是1的用户 , 需要注释核心配置文件中的经典驼峰命名映射
定义接口方法 : User selectUserById3(@param("id")Integer id);
-->
<resultMap id="selectUserById3ResultMap" type="User" autoMapping="true">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
</resultMap>
<select id="selectUserById3" resultMap="selectUserById3ResultMap">
select *
from user
where id = #{id}
</select>
</mapper>
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">
<!-- mybatis的根标签,configuration中文配置的意思 -->
<configuration>
<!--
properties标签可以引入外部文件,目的解耦
resource属性的值: 书写外部文件的路径
-->
<properties resource="db.properties"/>
<!-- 开启经典驼峰命名映射 -->
<settings>
<setting name="mapUnderscoreToCamelCase" value="false"/>
</settings>
<!-- 类型别名
使用typeAliases的子标签package的属性name进行配置包名com.itheima.pojo
那么只要是com.itheima.pojo包下的类,只要使用别名就可以
-->
<typeAliases>
<package name="com.itheima.pojo"/>
</typeAliases>
<!--
mybatis的环境标签,根据default的值选择使用哪一个环境
一个environments标签中可以多个environment环境标签
-->
<environments default="development">
<!-- environment的id是development表示当前环境是开发环境 -->
<environment id="development">
<!-- transactionManager事物管理标签 , type的值是JDBC表示事物由JDBC管理 ,后期由spring管理 -->
<transactionManager type="JDBC"/>
<!-- dataSource标签属于数据库连接池 , 当前mybatis默认数据库连接池属于POOLED,后期由spring管理 -->
<dataSource type="POOLED">
<!-- 数据库驱动 -->
<property name="driver" value="${jdbc.driver}"/>
<!-- 数据库url -->
<property name="url" value="${jdbc.url}"/>
<!-- 数据库用户名 -->
<property name="username" value="${jdbc.username}"/>
<!-- 数据库密码 -->
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- mappers属于关联映射文件标签-->
<mappers>
<!-- 扫描com.itheima.dao下的映射文件,注意:这里写的是映射文件所在的路径-->
<!-- <mapper resource="com/itheima/dao/UserMapper.xml"/>-->
<package name="com.itheima.dao"/>
</mappers>
</configuration>