項目目錄結構:
依賴包:
<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); }; }