1. 程式人生 > 實用技巧 >【JZOJ 5814】【NOIP提高A組模擬2018.8.14】 樹

【JZOJ 5814】【NOIP提高A組模擬2018.8.14】 樹

Mybatis-study

pom檔案

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>mybatis-study-02-crud</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
</dependencies>
</project>

mybatis 的配置檔案

<?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>

<!-- <settings>-->
<!-- &lt;!&ndash;-->
<!-- setting:設定某些屬性-->
<!-- - name:設定屬性的名-->
<!-- - value:設定屬性的值-->
<!-- &ndash;&gt;-->
<!-- <setting name="" value=""/>-->
<!-- </settings>-->


<!--
在 servlet 的初始化時載入 spring 的容器

-->

<!--
environments:設定連線資料庫的環境
- default :設定預設使用發資料庫環境
-->
<environments default="mysql">
<!--
environment: 某個具有的環境
- id:資料庫環境的唯一標識
-->
<environment id="mysql">
<!--
transactionManager:
- type:設定事務管理方式
-:JDBC:使用最JDBC最原始的事務管理進行事務管理方式
提交和回滾需要手動處理
-:MANAGED:被管理,交個可用管理的框架進行管理
-->
<transactionManager type="JDBC"/>
<!--
dataSource:
- type:
- JNDI:呼叫上下文的資料來源
- POOLED:使用預設的資料庫連線池(每次使用前都會先到連線池中獲取)
- UNPOOLED:不使用資料庫連線池(每次連線都會建立)
-->
<dataSource type="POOLED">
<!--
設定連線池
-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--
設定連地址
-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_study"/>
<!--
設定連線名
-->
<property name="username" value="root"/>
<!--
設定連線密碼
-->
<property name="password" value=""/>
</dataSource>
</environment>
</environments>

<mappers>
<mapper resource="mapper/EmpMapper.xml"></mapper>
<mapper resource="mapper/EmpSelectMapper.xml"></mapper>
<!-- 如果使用 package 需要把包和 xml 檔案在同一包下 -->
<!-- <package name="lyy.mapper"/>-->
</mappers>
</configuration>

對映檔案

<?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="lyy.mapper.EmpMapper">

<select id="getEmpByEid" resultType="lyy.bean.Emp">
SELECT * FROM `emp` WHERE `eid` = #{eid}
</select>

<select id="getAllEmp" resultType="lyy.bean.Emp">
SELECT * FROM `emp`
</select>

<insert id="addEmp">
INSERT INTO `emp`(`ename`, `age`, `sex`)
VALUES (#{ename},#{age},#{sex})
</insert>

<!--
parameterType : 執行方法的引數型別
myBatis 中有型別推斷機制,可用不用使用 parameterType
-->
<update id="updateEmp" parameterType="lyy.bean.Emp">
UPDATE `emp` SET `ename`=#{ename},`age`=#{age},`sex`=#{sex}
WHERE `eid` = #{eid}
</update>

<delete id="deleteEmp">
DELETE FROM `emp` WHERE `eid` = #{eid}
</delete>

<select id="getEmpMapBy" resultType="lyy.bean.Emp">
SELECT * FROM `emp`
</select>

</mapper>

mapper介面類

package lyy.mapper;

import lyy.bean.Emp;

import java.util.List;

/**
* @program: mybatis-2020
* @description:
* @author: LYY
* @create: 2020-08-11 12:07
*/
public interface EmpMapper {

// 更具 eid 查詢資訊
Emp getEmpByEid(String eid);
// 獲取所有的資訊
List<Emp> getAllEmp();
// 新增資訊
int addEmp(Emp emp);
// 修改資訊
int updateEmp(Emp emp);

// 刪除資訊
// 返回值(int):受影響的行數
// 返回值(boolean): 是否操作成功
Boolean deleteEmp(String eid);

// 更具 map 集合查詢所有的員工
@MapKey("eid")// 設定 map 集合的鍵,在查詢時傳出所有的員工資訊,可用把員工資訊作為值,但是必須設定 map 集合的 key 值
Map<String,Object> getEmpMapBy();
}

實體類

package lyy.bean;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
* @program: mybatis-2020
* @description:
* @author: LYY
* @create: 2020-08-11 12:05
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Emp {

private Integer eid;
private String ename;
private Integer age;
private String sex;

@Override
public String toString() {
return "Emp{" +
"eid=" + eid +
", ename='" + ename + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}

使用mybatis

  @Test
public void test() throws IOException {
// 獲取 mybatis 配置檔案的輸入流物件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 根據位元組輸入流建立 SqlSessionFactory
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(is);
// 獲取 sqlSession 方法
SqlSession sqlSession = sqlSessionFactory.openSession();// 需要手動提交事務
SqlSession sqlSessionOuto = sqlSessionFactory.openSession(true);// 自動提交事務

// 通過 session 獲取 mapper 介面的實現物件
// .getMapper 通過動態代理,動態生成 UserMapper 的代理的實現類
// 會先通過 全類名找到對應的對映檔案,在通過其方法的方法名找到對映檔案中id對應的sql語句
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 檢視 mapper 的實現類
System.out.println(mapper.getClass().getName());
List<User> userList = mapper.getAllUser();
System.out.println(userList);
sqlSession.commit();// 提交事務
}

${}和#{}的區別

${}和#{} 生成的 Sql 語句的區別

${} : 在執行時,如果有字串必須手動拼接

#{} : 不用考慮是否是字串的問題

<!--
#{}:
執行的 sql 語句是 INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES (?,?,?)
會使用到 PreparedStatement 物件(預編譯物件)
然後使用 :
PreparedStatement.set(1,value);替換第1個 ? 的值為 value
PreparedStatement.set(2,value2):替換第2個 ? 的值為 value2
......
最後使用
PreparedStatement.excuteUpdate

特點:
-- 可用防止 sql 注入攻擊
-- 可用和傳入的引數名不同

-->
<insert id="addEmp">
INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES (#{ename},#{age},#{sex})
</insert>
<!--
${}:
執行的 sql 語句是 INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES (老王王,12,男)
會使用到 Statement 物件
Steatement statement = Connection(java.sel).createStatement 物件();
String sql = INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES ('+"ename+"'',"+age+",'"+sex+"')
直接執行 sql 語句,需要自己拼接sql語句
statement.execute(String sql);

特點:
-- 不能防止 sql 注入
-- 在模糊查詢和批量刪除的時候使用 ${}
-- ${}:必須和引數名一致
-->
<insert id="addEmp">
<!--
如果使用 ${} 需要手動加上 ''
-->
INSERT INTO `emp`(`ename`, `age`, `sex`) VALUES ('${ename}',${age},'${sex}')
</insert>

${}和#{}取值的方式

如果出現 : BindingException 那麼說明通過 #{} 或者 ${} 獲取值的方式出現了問題

<!--
Emp getEmpByEid(String eid);

1、傳入的值為單個 基本資料型別 和 其包裝類 或 String 值
#{}:可用不用和引數名一致
${}:必須和引數名一致
會把傳入的值當成實體類物件,通過 get 方法獲取其值
但是可用使用 value 獲取 _parameter 獲取出傳入的值
2、當傳輸為 javaBean(實體類) 時
#{} 和 ${} 可用通過屬性名獲取其屬性值,但是要注意 ${} 的單引號問題
3、傳入的值為多個值

#{}:可用使用 #{0}(根據索引獲取值) 或者 #{parameter1}(第幾個引數獲取其值) 進行訪問
-- 索引
...... eid = #{0} and ename = #{1}
-- 引數
...... eid = #{param1} and ename = #{param2}

${}:不能使用索引 ${數值} 只能使用 #{param2}
--
...... ${param1} and ename = ${param2}

mybatis 會預設將這些引數放在 map 集合中,會以兩種方式實現
-- 1、鍵為 1,2,3 ... n-1 值為引數
-- 2、鍵為 param1,param2 ... paramN 值為引數
4、傳輸為的引數為 map 時
#{} 和 ${} 都可以通過鍵的名字獲取值
5、使用 @Param 註解
可以為其自動生成鍵,自定義鍵的名字
Emp getEmpByEidAndEname(@Param("eid") String eid,@Param("ename") String ename);
在 xml 直接使用 ${eid} 或者 #{eid}
6、傳入的引數為 List 或者 Array
mybatis 會將 List 或者 Array 放在 map 中
List 以 list 為鍵
Array 以 array 為鍵
-->
<select id="getEmpByEid" resultType="lyy.bean.Emp">
SELECT * FROM emp WHERE eid = #{eid}
</select>
<!--Emp getEmpByEidAndEname(String eid,String ename);-->
<select id="getEmpByEidAndEname">
SELECT * FROM emp WHERE eid = #{eid} and ename = #{ename}
</select>

mybatis獲取自動生成的主鍵

在 JDBC 中獲取自自動生成主鍵

Class.forName("")
Connrction(java.sql) conn = DriverManager.getConnection(url,name,pwd)
PreparedStatement ps = conn.prepareStatement(sql語句)
ResultSet rs = ps.getGeneratedKeys();
// 替換 ?
......
re.next();
int ud = rs.getInt();

mapper.xml 中寫法

  <!--
useGeneratedKeys : 開啟自動生成的主鍵
keyProperty : 設定生成的主鍵賦值給傳遞過來的引數的哪一個屬性
如: lyy.bean.Emp 的 eid 屬性(parameterType可以省略)
-->
<insert id="addEmp" parameterType="lyy.bean.Emp" useGeneratedKeys="true" keyProperty="eid">
INSERT INTO `emp`(`eid`,`ename`, `age`, `sex`) VALUES (null,#{ename},#{age},#{sex})
</insert>