项目目录结构:

依赖包:
<dependencies>
<!--单测-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!--MyBatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
<!--到slf4j与log4j的关联jar包,通过这个东西,将对slf4j接口的调用转换为对log4j的调用,不同的日志实现框架,这个转换工具不同-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!--alibaba 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
实体类:
public class Department {
private int departmentId;
private String departmentName;
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public Department() {
}
public Department(int departmentId, String departmentName) {
this.departmentId = departmentId;
this.departmentName = departmentName;
}
@Override
public String toString() {
return "Department{" +
"departmentId=" + departmentId +
", departmentName='" + departmentName + '\'' +
'}';
}
}
mybatis-config.xml配置
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置的属性都是可外部配置且可动态替换的-->
<properties resource="database.properties" />
<settings>
<setting name="logImpl" value="SLF4J"/>
</settings>
<!--定义别名,存在的意义仅在于用来减少类完全限定名的冗余。-->
<typeAliases>
<!--使用扫描包,扫描指定包下的所有类,扫描之后的别名就是类名(不区分大小写),建议使用的时候和类名一致。-->
<package name="cn.pojo"/>
</typeAliases>
<!--环境数据源-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="cn.util.DruidDataSourceFactory">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--告诉 MyBatis 到哪里查找sql映射语句-->
<mappers>
<mapper resource="mapper/PracticeMapper.xml" />
</mappers>
</configuration>
工具类:
MyBatisUtil
public class MyBatisUtil {
//创建SqlSessionFactory工厂
public static SqlSessionFactory factory;
static {
InputStream is = null;
try {
//读取mybatis-config.xml
is = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession createSqlSession(){
return factory.openSession(false);//关闭自动提交事物
}
public static void closeSqlSession(SqlSession sqlSession){
if(null!=sqlSession){
sqlSession.close();
}
}
}
阿里云Druid数据源类
public class DruidDataSourceFactory extends PooledDataSourceFactory {
public DruidDataSourceFactory(){
this.dataSource = new DruidDataSource();
}
}
database.properties
jdbc.driver:com.mysql.cj.jdbc.Driver
jdbc.url:jdbc:mysql://localhost:3306/tests?characterEncoding=utf8&useSSL=false&serverTimezone=UTC
jdbc.username:root
jdbc.password:123456
log4j.properties
### set log levels ###
log4j.rootLogger = DEBUG,Console,File
### Output To Console ###
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
#log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
#log4j.appender.Console.layout.ConversionPattern= [%p] %d{yyyy-MM-dd HH\:mm\:ss,SSS} %c{1}:%L - %m%n
log4j.appender.Console.layout.ConversionPattern= %d{ABSOLUTE} %5p %c{1}:%L - %m%n
#log4j.appender.File.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c]%m%n
### Output To File ###
log4j.appender.File=org.apache.log4j.RollingFileAppender
log4j.appender.File.File=d:\\mylog.log
#log4j.appender.File.DatePattern=_yyyyMMdd'.log'
log4j.appender.File.MaxFileSize=10MB
#log4j.appender.File.Threshold=ALL
log4j.appender.File.layout=org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c]%m%n
dao
public interface PracticeMapper {
//查询所有部门
public List<Department> queryDepartmentList();
//根据部门ID,查询单个部门信息
public Department queryDepartmentByDepartmentId(@Param("departmentId")Integer departmentId);
/**
* 根据部门名称,模糊查询部门信息
* @param departmentName
* @return
*/
public List<Department> queryDepartmentListLikeByDepartmentName(@Param("departmentName")String departmentName);
//添加一个部门
public Integer insertDepartmentList(Department department);
//删除一个部门,根据部门ID
public Integer deleteDepartmentByDepartmentId(@Param("departmentId")Integer departmentId);
//修改一个部门,根据部门ID
public Integer updateDepartentByDepartmentId(@Param("departmentName")String departmentName,@Param("departmentId")Integer departmentId);
//如果输入了部门名称,就按部门名称来查询,否则查询所有部门
public List<Department> queryDepartmentIf(@Param("departmentName")String departmentName);
//where和if 如果有部门名称和部门ID,查询单个部门,否则查询所有部门
public List<Department> queryDepartmentIfAndTrim(Department department);
//if+set进行更新操作
public Integer updateDepartmentIfAndSet(Department department);
//foreach 根据部门ID查询多条信息
public List<Department> queryDepartmentByArrayDepartmentId(Integer[] departmentId);
//List类型的foreach迭代
public List<Department> queryDepartmentByListDepartmentId(List<Integer> departmentId);
}
PracticeMapper.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.dao.PracticeMapper">
<!--开启mybatis的二级缓存-->
<!--
配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,
而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
-->
<!--
二级缓存是事务性的。
这意味着,当 SqlSession 完成并提交时,或是完成并回滚,
但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
flushCache=true:将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
-->
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
<!--
id:唯一标识,随便写,在同一个命名空间下保持唯一,使用动态代理之后要求和方法名保持一致
parameterType:参数的类型,使用动态代理之后和方法的参数类型一致
-->
<!--基本查询-->
<!--查询所有部门-->
<select id="queryDepartmentList" parameterType="Department" resultType="Department">
SELECT
<include refid="DepartmentInfo"/>
from tests.department
</select>
<!--根据部门ID,查询单个部门信息-->
<select id="queryDepartmentByDepartmentId" parameterType="Department" resultType="Department">
SELECT <include refid="DepartmentInfo"></include> from tests.department where departmentId = #{departmentId}
</select>
<!--根据部门名称,模糊查询部门信息-->
<select id="queryDepartmentListLikeByDepartmentName" parameterType="String" resultType="Department">
SELECT <include refid="DepartmentInfo"></include> FROM tests.department WHERE departmentName LIKE
CONCAT('%',#{departmentName},'%')
</select>
<!--添加一个部门-->
<insert id="insertDepartmentList" parameterType="Department">
INSERT INTO department (departmentName) VALUES (#{departmentName});
</insert>
<!--删除一个部门-->
<delete id="deleteDepartmentByDepartmentId" parameterType="Integer">
delete from department where departmentId = #{departmentId}
</delete>
<!--修改一个部门,根据部门ID-->
<update id="updateDepartentByDepartmentId" parameterType="Department">
update department set departmentName= #{departmentName} where departmentId = #{departmentId}
</update>
<!--SQL代码片段-->
<sql id="DepartmentInfo">
departmentId,departmentName
</sql>
<!--动态sql查询-->
<!--if 如果输入了部门名称,就按部门名称来查询,否则查询所有部门-->
<select id="queryDepartmentIf" parameterType="String" resultType="Department">
SELECT
<include refid="DepartmentInfo"/>
from tests.department
WHERE 1=1
<if test="''!=departmentName and null != departmentName">
AND departmentName LIKE CONCAT('%',#{departmentName},'%')
</if>
</select>
<!--if和trim 如果有部门名称和部门ID,查询单个部门,否则查询所有部门-->
<!--trim 会自动删除and和or,并且会自动识别标签是否有返回值,有则加上前缀(prefix)和后缀(suffix)-->
<select id="queryDepartmentIfAndTrim" parameterType="Department" resultType="Department">
SELECT
<include refid="DepartmentInfo"/>
from tests.department
<trim prefix="where" prefixOverrides="and |or">
<if test="''!=departmentName and null != departmentName">
AND departmentName = #{departmentName}
</if>
<if test="''!=departmentId and null != departmentId">
AND departmentId = #{departmentId}
</if>
</trim>
</select>
<!--if+set 进行更新操作-->
<update id="updateDepartmentIfAndSet" parameterType="Department">
update department
<set>
<if test="''!=departmentName and null != departmentName">departmentName=#{departmentName},</if>
<if test="''!=departmentId and null != departmentId">departmentId=#{departmentId}</if>
</set>
where departmentId = #{departmentId}
</update>
<!--foreach 根据部门ID查询多条信息-->
<!--
item:集合中每个元素进行迭代的别名
open:以什么开始
close:以什么结束
separator:以什么分隔
collection:若入参为单参数,且参数类型是一个List的时候,collection属性值为list
若入参为单参数,且参数类型是一个数组的时候,collection属性值为array
若入参为多参数,就需要将他们封装为一个Map进行处理
-->
<select id="queryDepartmentByArrayDepartmentId" parameterType="Department" resultType="Department">
SELECT <include refid="DepartmentInfo"></include> from tests.department where departmentId in
<foreach collection="array" item="departmentId" open="(" close=")" separator=",">
${departmentId}
</foreach>
</select>
<!--List类型的foreach迭代-->
<select id="queryDepartmentByListDepartmentId" parameterType="Department" resultType="Department">
SELECT <include refid="DepartmentInfo"></include> from tests.department where departmentId in
<foreach collection="list" item="departmentId" open="(" close=")" separator=",">
${departmentId}
</foreach>
</select>
</mapper>
单测
public class PracticeMapperTest {
private static final Logger logger = LoggerFactory.getLogger(PracticeMapperTest.class);
SqlSession sqlSession = MyBatisUtil.createSqlSession();
/**
* 查询所有部门
*
* @throws IOException
*/
@Test
public void queryDepartmentList() throws IOException {
//获取mapper接口的对象
List<Department> departments = sqlSession.getMapper(PracticeMapper.class).queryDepartmentList();
for (Department department : departments) {
System.out.println(department.toString());
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
/**
* 根据部门ID,查询单个部门信息
*/
@Test
public void queryDepartmentByDepartmentId(){
Department department = sqlSession.getMapper(PracticeMapper.class).queryDepartmentByDepartmentId(5);
System.out.println(department);
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
/**
* 根据部门名称,模糊查询部门信息
*/
@Test
public void queryDepartmentListLikeByDepartmentName(){
List<Department> list = sqlSession.getMapper(PracticeMapper.class).queryDepartmentListLikeByDepartmentName("气");
for(Department item:list){
System.out.println(item);
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
/**
* 添加一个部门
*/
@Test
public void insertDepartmentList(){
Department department = new Department();
department.setDepartmentName("卡牌部门");
Integer integer = sqlSession.getMapper(PracticeMapper.class).insertDepartmentList(department);
if(integer > 0){
sqlSession.commit();//自动提交
}else{
sqlSession.rollback();//回滚
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
/**
* 删除一个部门
*/
@Test
public void deleteDepartmentByDepartmentId(){
Integer integer = sqlSession.getMapper(PracticeMapper.class).deleteDepartmentByDepartmentId(11);
if(integer > 0){
sqlSession.commit();//自动提交
}else{
sqlSession.rollback();//回滚
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
/**
* 修改一个部门,根据部门ID
*/
@Test
public void updateDepartentByDepartmentId(){
Integer integer = sqlSession.getMapper(PracticeMapper.class).updateDepartentByDepartmentId( "灵气部门",4);
if(integer > 0){
sqlSession.commit();//自动提交
}else{
sqlSession.rollback();//回滚
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
/**
* 如果输入了部门名称,就按部门名称来查询,否则查询所有部门
*/
@Test
public void queryDepartmentIf(){
List<Department> list = sqlSession.getMapper(PracticeMapper.class).queryDepartmentIf("魔");
for(Department item : list){
System.out.println(item);
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
//where和if 如果有部门名称和部门ID,查询单个部门,否则查询所有部门
@Test
public void queryDepartmentIfAndTrim(){
Department department = new Department();
department.setDepartmentName("灵气部门");
List<Department> list = sqlSession.getMapper(PracticeMapper.class).queryDepartmentIfAndTrim(department);
for(Department item : list){
System.out.println(item);
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
//if+set进行更新操作
@Test
public void updateDepartmentIfAndSet(){
Department department = new Department();
department.setDepartmentId(4);
department.setDepartmentName("仙气大陆");
Integer integer = sqlSession.getMapper(PracticeMapper.class).updateDepartmentIfAndSet(department);
if(integer > 0){
sqlSession.commit();//自动提交
}else{
sqlSession.rollback();//回滚
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
//foreach 根据部门ID查询多条信息
@Test
public void queryDepartmentByArrayDepartmentId(){
Integer[] integers = {3,5,8};
List<Department> departments = sqlSession.getMapper(PracticeMapper.class).queryDepartmentByArrayDepartmentId(integers);
for(Department items: departments){
System.out.println(items);
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
//List类型的foreach迭代
@Test
public void queryDepartmentByListDepartmentId(){
List<Integer> list = new ArrayList<Integer>();
list.add(3);
list.add(9);
List<Department> departments = sqlSession.getMapper(PracticeMapper.class).queryDepartmentByListDepartmentId(list);
for(Department items: departments){
System.out.println(items);
}
MyBatisUtil.closeSqlSession(sqlSession);//关闭资源
}
}
一对一
实体类
public class Department {
private int departmentId;
private String departmentName;
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public Department() {
}
public Department(int departmentId, String departmentName) {
this.departmentId = departmentId;
this.departmentName = departmentName;
}
@Override
public String toString() {
return "Department{" +
"departmentId=" + departmentId +
", departmentName='" + departmentName + '\'' +
'}';
}
}
public class Employees {
private int employeesId;
private String employeesName;
private int departmentId;
private String employeesAddress;
private Date employeesBirthday; //java.sql.Date;
private Department department;
public Employees() {
}
public Employees(int employeesId, String employeesName, int departmentId, String employeesAddress, Date employeesBirthday, Department department) {
this.employeesId = employeesId;
this.employeesName = employeesName;
this.departmentId = departmentId;
this.employeesAddress = employeesAddress;
this.employeesBirthday = employeesBirthday;
this.department = department;
}
public int getEmployeesId() {
return employeesId;
}
public void setEmployeesId(int employeesId) {
this.employeesId = employeesId;
}
public String getEmployeesName() {
return employeesName;
}
public void setEmployeesName(String employeesName) {
this.employeesName = employeesName;
}
public int getDepartmentId() {
return departmentId;
}
public void setDepartmentId(int departmentId) {
this.departmentId = departmentId;
}
public String getEmployeesAddress() {
return employeesAddress;
}
public void setEmployeesAddress(String employeesAddress) {
this.employeesAddress = employeesAddress;
}
public Date getEmployeesBirthday() {
return employeesBirthday;
}
public void setEmployeesBirthday(Date employeesBirthday) {
this.employeesBirthday = employeesBirthday;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Employees{" +
"employeesId=" + employeesId +
", employeesName='" + employeesName + '\'' +
", departmentId=" + departmentId +
", employeesAddress='" + employeesAddress + '\'' +
", employeesBirthday=" + employeesBirthday +
", department=" + department +
'}';
}
}
Mapper
public Employees getEmployeesListByEmployeesId(@Param("employeesId")Integer employeesId);
Mapper.xml
<resultMap id="employeesDepartmentList" type="Employees">
<id property="employeesId" column="employeesId"/>
<result property="employeesName" column="employeesName"/>
<result property="employeesAddress" column="employeesAddress"/>
<result property="employeesBirthday" column="employeesBirthday"/>
<result property="departmentId" column="departmentId"/>
<association property="department" javaType="Department">
<id property="departmentId" column="departmentId"/>
<result property="departmentName" column="departmentName"/>
</association>
</resultMap>
<!--1对一查询 查询出员工id为2的员工信息和他的部门信息-->
<select id="getEmployeesListByEmployeesId" resultMap="employeesDepartmentList" >
select e.employeesId,e.employeesName,e.employeesAddress,e.employeesBirthday,e.departmentId,d.departmentName
from employees e,department d
where e.employeesId = #{employeesId} and e.departmentId = d.departmentId
</select>
单侧
//1对一查询 查询出员工id为2的员工信息和他的部门信息
@Test
public void getEmployeesListByEmployeesId(){
Integer integer = 3;
Employees employees = sqlSession.getMapper(PracticeMapper.class).getEmployeesListByEmployeesId(integer);
System.out.println(employees);
}
一对多
修改mapper
public List<Employees> getEmployeesListByDepartmentId(@Param("departmentId")Integer departmentId);
修改mapper.xml
<!--1对多查询 根据部门ID查询多此部门下的员工信息-->
<select id="getEmployeesListByDepartmentId" resultMap="employeesDepartmentList">
select e.employeesId,e.employeesName,e.employeesAddress,e.employeesBirthday,e.departmentId,d.departmentName
from employees e,department d
where e.departmentId = #{departmentId} and e.departmentId = d.departmentId
</select>
单侧
//1对多查询 根据部门ID查询多此部门下的员工信息
@Test
public void getEmployeesListByDepartmentId(){
Integer integer = 2;
List<Employees> employees = sqlSession.getMapper(PracticeMapper.class).getEmployeesListByDepartmentId(integer);
for(Employees item : employees){
System.out.println(item);
};
}