Java進階學習第三十三天(MyBatis)
一、MyBatis基礎
1、回顧jdbc開發
① 優點:簡單易學、上手快、非常靈活構建SQL、效率高
② 缺點:程式碼繁瑣,難以寫出高質量的程式碼(例如:資源的釋放,SQL注入安全性等)開發者既要寫業務邏輯,又要寫物件的建立和銷燬,必須管底層具體資料庫的語法(例如:分頁)。
③ 適合於超大批量資料的操作,速度快
④ 開發步驟
◇ 載入資料庫驅動
◇ 通過DriverManager獲取Statement/PreparedStatement中去,準備向資料庫傳送SQL語句
◇ 執行完SQL語句之後,返回物件的結果ResultSet=executeQuery(查詢)/int i=executeUpdate(增/刪/改)
◇ 如果以查詢為例,迭代結果集進行處理
while(rs.next){String name = rs.getString("name")}
◇ 依次關閉連線物件ResultSet/Statement/Connection,如果上述操作需要作非查詢的話,還需要事務支援
conn.setAutoConmmit(false);conn.commit()/conn.rollback;
2、回顧hibernate單表開發
① 優點:不用寫SQL,完全以面向物件的方式設計和訪問,不用管底層具體資料庫的語法,(例如:分頁)便於理解。
②缺點:處理複雜業務時,靈活度差, 複雜的HQL難寫難理解,例如多表查詢的HQL語句
③ 適合於中小批量資料的操作,速度慢
④ 開發步驟
◇ 建立Configuration,目的是載入src/hibernate.cfg.xml配置檔案,該配置檔案又去載入Hero.hbm.xml檔案
◇ 通過Configuration建立重量級SessionFactory
◇ 通過SessionFactory建立輕量級Session
◇ 通過Session建立Transaction
◇ 如果做增刪改操作的話,一定要事務,如果做查詢,事務可選
◇ 操作Session常用的api,例如:save()/update()/saveOrUpdate()/delete()
◇ 事務提交,出錯事務回滾
◇ 關閉Session
3、mybatis的特點
① 基於上述二種支援,我們需要在中間找到一個平衡點呢?結合它們的優點,摒棄它們的缺點,這就是myBatis,現今myBatis被廣泛的企業所採用。
② MyBatis 本是apache的一個開源專案iBatis, 2010年這個專案由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。
③ iBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO)
④ jdbc/dbutils/springdao,hibernate/springorm,mybaits同屬於ORM解決方案之一
4、mybatis快速入門
① 建立一個mybatis-day01這麼一個javaweb工程或java工程
② 匯入mybatis和mysql/oracle的jar包到/WEB-INF/lib目錄下
③ 建立students.sql表(mysql語法)
create table students(
id int(5) primary key,
name varchar(10),
sal double(8,2)
);
create table students(
students_id int(5) primary key,
students_name varchar(10),
students_sal double(8,2)
);
④ 建立Student.java
public class Student {
private Integer id;//編號
private String name;//姓名
private Double sal;//薪水
public Student(){}
public Student(Integer id, String name, Double sal) {
this.id = id;
this.name = name;
this.sal = sal;
}
public Integer getId() {
System.out.println("getId()");
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
System.out.println("getName()");
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSal() {
System.out.println("getSal()");
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
}
⑤ 在entity目錄下建立StudentMapper.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">
<!-- namespace屬性是名稱空間,必須唯一 -->
<mapper namespace="cn.itcast.javaee.mybatis.app04.Student">
<!-- resultMap標籤:對映實體與表
type屬性:表示實體全路徑名;id屬性:為實體與表的對映取一個任意的唯一的名字
-->
<resultMap type="student" id="studentMap">
<!-- id標籤:對映主鍵屬性
result標籤:對映非主鍵屬性
property屬性:實體的屬性名;column屬性:表的欄位名
-->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sal" column="sal"/>
</resultMap>
<!--
insert標籤:要書寫insert的sql語句
id屬性:為insert這麼一個sql語句取一個任意唯一的名字
parameterType:要執行的dao中的方法的引數,如果是類的話,必須使用全路徑類
-->
<insert id="add1">
insert into students(id,name,sal) values(1,'哈哈',7000)
</insert>
<insert id="add2" parameterType="student">
insert into students(id,name,sal) values(#{id},#{name},#{sal})
</insert>
</mapper>
⑥ 在src目錄下建立mybatis.xml配置檔案,提倡放在src目錄下,檔名任意
<?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 resource="db.properties"/>
<!-- 設定類型別名 -->
<typeAliases>
<typeAlias type="cn.itcast.javaee.mybatis.app04.Student" alias="student"/>
</typeAliases>
<!-- 設定一個預設的連線環境資訊 -->
<environments default="mysql_developer">
<!-- 連線環境資訊,取一個任意唯一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事務管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用連線池方式來獲取連線 -->
<dataSource type="pooled">
<!-- 配置與資料庫互動的4個必要屬性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!-- 連線環境資訊,取一個任意唯一的名字 -->
<environment id="oracle_developer">
<!-- mybatis使用jdbc事務管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用連線池方式來獲取連線 -->
<dataSource type="pooled">
<!-- 配置與資料庫互動的4個必要屬性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
<!-- 載入對映檔案-->
<mappers>
<mapper resource="cn/itcast/javaee/mybatis/app14/StudentMapper.xml"/>
</mappers>
</configuration>
db.properties
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://127.0.0.1:3306/mybatis
mysql.username=root
mysql.password=root
oracle.driver=oracle.jdbc.driver.OracleDriver
oracle.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
oracle.username=scott
oracle.password=tiger
⑦ 在util目錄下建立MyBatisUtil.java類,並測試與資料庫是否能連線
public class MybatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
/**
* 載入位於src/mybatis.xml配置檔案
*/
static{
try {
Reader reader = Resources.getResourceAsReader("mybatis.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 禁止外界通過new方法建立
*/
private MybatisUtil(){}
/**
* 獲取SqlSession
*/
public static SqlSession getSqlSession(){
//從當前執行緒中獲取SqlSession物件
SqlSession sqlSession = threadLocal.get();
//如果SqlSession物件為空
if(sqlSession == null){
//在SqlSessionFactory非空的情況下,獲取SqlSession物件
sqlSession = sqlSessionFactory.openSession();
//將SqlSession物件與當前執行緒繫結在一起
threadLocal.set(sqlSession);
}
//返回SqlSession物件
return sqlSession;
}
/**
* 關閉SqlSession與當前執行緒分開
*/
public static void closeSqlSession(){
//從當前執行緒中獲取SqlSession物件
SqlSession sqlSession = threadLocal.get();
//如果SqlSession物件非空
if(sqlSession != null){
//關閉SqlSession物件
sqlSession.close();
//分開當前執行緒與SqlSession物件的關係,目的是讓GC儘早回收
threadLocal.remove();
}
}
/**
* 測試
*/
public static void main(String[] args) {
Connection conn = MybatisUtil.getSqlSession().getConnection();
System.out.println(conn!=null?"連線成功":"連線失敗");
}
}
⑧ 在dao目錄下建立StudentDao.java類並測試
public class StudentDao {
public void add1() throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
//事務開始(預設)
//讀取StudentMapper.xml對映檔案中的SQL語句
int i = sqlSession.insert("cn.itcast.javaee.mybatis.app04.Student.add1");
System.out.println("本次操作影響了"+i+"行");
//事務提交
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
//事務回滾
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public void add2(Student student) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
//事務開始(預設)
//讀取StudentMapper.xml對映檔案中的SQL語句
sqlSession.insert(Student.class.getName()+".add2",student);
//事務提交
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
//事務回滾
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
dao.add1();
dao.add2(new Student(2,"呵呵",8000D));
}
}
5、mybatis工作流程
① 通過Reader物件讀取src目錄下的mybatis.xml配置檔案(該文字的位置和名字可任意)
② 通過SqlSessionFactoryBuilder物件建立SqlSessionFactory物件
③ 從當前執行緒中獲取SqlSession物件
④ 事務開始,在mybatis中預設
⑤ 通過SqlSession物件讀取StudentMapper.xml對映檔案中的操作編號,從而讀取sql語句
⑥ 事務提交【必寫】
⑦ 關閉SqlSession物件,並且分開當前執行緒與SqlSession物件,讓垃圾回收站儘早回收
6、MybatisUtil工具類的作用
① 在靜態初始化塊中載入mybatis配置檔案和StudentMapper.xml檔案一次
② 使用ThreadLocal物件讓當前執行緒與SqlSession物件繫結在一起
③ 獲取當前執行緒中的SqlSession物件,如果沒有的話,從SqlSessionFactory物件中獲取SqlSession物件
④ 獲取當前執行緒中的SqlSession物件,再將其關閉,釋放其佔用的資源
7、基於MybatisUtil工具類,完成CURD操作
① StudentDao.java
public class StudentDao1 {
/**
* 增加學生
*/
public void add(Student student) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.insert(Student.class.getName()+".add",student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 根據ID查詢學生
*/
public Student findById(int id) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
Student student = sqlSession.selectOne(Student.class.getName()+".findById",id);
sqlSession.commit();
return student;
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 查詢所有學生
*/
public List<Student> findAll() throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectList(Student.class.getName()+".findAll");
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 更新學生
*/
public void update(Student student) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.update(Student.class.getName()+".update",student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 刪除學生
*/
public void delete(Student student) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.delete(Student.class.getName()+".delete",student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao1 dao = new StudentDao1();
//dao.add(new Student(1,"哈哈",7000D));
//dao.add(new Student(2,"呵呵",8000D));
//dao.add(new Student(3,"班長",9000D));
//dao.add(new Student(4,"鍵狀高",10000D));
//Student student = dao.findById(4);
//List<Student> studentList = dao.findAll();
//for(Student student : studentList){
// System.out.print(student.getId()+":"+student.getName()+":"+student.getSal());
// System.out.println();
//}
//Student student = dao.findById(3);
//student.setName("靚班長");
//dao.update(student);
Student student = dao.findById(3);
System.out.print(student.getId()+":"+student.getName()+":"+student.getSal());
//dao.delete(student);
}
}
② StudentMapper.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.itcast.javaee.mybatis.app09.Student">
<resultMap type="cn.itcast.javaee.mybatis.app09.Student" id="studentMap">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="sal" column="sal"/>
</resultMap>
<!-- 增加學生 -->
<insert id="add" parameterType="cn.itcast.javaee.mybatis.app09.Student">
insert into students(id,name,sal) values(#{id},#{name},#{sal})
</insert>
<!-- 根據ID查詢學生
如果引數不是一個實體的話,只是一個普通變數,例如:int,double,String
這裡的#{中間的變數名可以隨便寫},不過提倡就用方法的形參
-->
<select id="findById" parameterType="int" resultType="cn.itcast.javaee.mybatis.app09.Student">
select id,name,sal from students where id = #{id}
</select>
<!-- 查詢所有學生
理論上resultType要寫List<Student>
但這裡只需書寫List中的型別即可,即只需書寫Student的全路徑名
-->
<select id="findAll" resultType="cn.itcast.javaee.mybatis.app09.Student">
select id,name,sal from students
</select>
<!-- 更新學生 -->
<update id="update" parameterType="cn.itcast.javaee.mybatis.app09.Student">
update students set name=#{name},sal=#{sal} where id=#{id}
</update>
<!-- 刪除學生 -->
<delete id="delete" parameterType="cn.itcast.javaee.mybatis.app09.Student">
delete from students where id = #{id}
</delete>
<!--
<insert id="delete" parameterType="cn.itcast.javaee.mybatis.app09.Student">
delete from students where id = #{id}
</insert>
-->
<!--
注意:這個insert/update/delete標籤只是一個模板,在做操作時,其實是以SQL語句為核心的
即在做增/刪/時,insert/update/delete標籤可通用,
但做查詢時只能用select標籤
我們提倡什麼操作就用什麼標籤
-->
</mapper>
<?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="studentNamespace">
<!-- 當實體屬性與表字段名不相同的時候,必須書寫以下程式碼
當實體屬性與表字段名相同的時候,以下程式碼可選
-->
<resultMap type="cn.itcast.javaee.mybatis.app09.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<!-- 增加學生 -->
<insert id="add" parameterType="cn.itcast.javaee.mybatis.app09.Student">
insert into students(students_id,students_name,students_sal)
values(#{id},#{name},#{sal})
</insert>
<!-- 根據ID查詢學生
mybatis會將查詢出來的表記錄和studentMap這個id所對應的對映結果相互匹配
-->
<select id="findById" parameterType="int" resultMap="studentMap">
select students_id,students_name,students_sal
from students
where students_id = #{xxxxxxxxxxxxxxxxxx}
</select>
</mapper>
8、分頁查詢
① StudentDao.java
public class StudentDao {
/**
* 增加學生
*/
public void add(Student student) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.insert(Student.class.getName()+".add",student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 無條件分頁
* @param start 表示在mysql中從第幾條記錄的索引號開始顯示,索引從0開始
* @param size 表示在mysql中最多顯示幾條記錄
*/
public List<Student> findAllWithFy(int start,int size) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
Map<String,Object> map = new LinkedHashMap<String,Object>();
map.put("pstart",start);
map.put("psize",size);
return sqlSession.selectList(Student.class.getName()+".findAllWithFy",map);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 有條件分頁
*/
public List<Student> findAllByNameWithFy(String name,int start,int size) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
Map<String,Object> map = new LinkedHashMap<String, Object>();
map.put("pname","%"+name+"%");
map.put("pstart",start);
map.put("psize",size);
return sqlSession.selectList(Student.class.getName()+".findAllByNameWithFy",map);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
//for(int i=1;i<=10;i++){
// dao.add(new Student(i,"哈哈",7000D));
//}
System.out.println("--------------------第一頁");
List<Student> studentList1 = dao.findAllByNameWithFy("哈",0,3);
for(Student s : studentList1){
System.out.println(s.getId()+":"+s.getName()+":"+s.getSal());
}
System.out.println("--------------------第二頁");
List<Student> studentList2 = dao.findAllByNameWithFy("哈",3,3);
for(Student s : studentList2){
System.out.println(s.getId()+":"+s.getName()+":"+s.getSal());
}
System.out.println("--------------------第三頁");
List<Student> studentList3 = dao.findAllByNameWithFy("哈",6,3);
for(Student s : studentList3){
System.out.println(s.getId()+":"+s.getName()+":"+s.getSal());
}
}
}
② StudentMapper.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.itcast.javaee.mybatis.app10.Student">
<resultMap type="cn.itcast.javaee.mybatis.app10.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<insert id="add" parameterType="cn.itcast.javaee.mybatis.app10.Student">
insert into students(students_id,students_name,students_sal)
values(#{id},#{name},#{sal});
</insert>
<select id="findAllWithFy" parameterType="map" resultMap="studentMap">
select students_id,students_name,students_sal
from students
limit #{pstart},#{psize}
</select>
<select id="findAllByNameWithFy" parameterType="map" resultMap="studentMap">
select students_id,students_name,students_sal
from students
where students_name like #{pname}
limit #{pstart},#{psize}
</select>
</mapper>
二、動態SQL操作之增刪改查
1、查詢
查詢條件不確定,需要根據情況產生SQL語法,這種情況叫動態SQL
① StudentDao.java
public class StudentDao {
/**
* 有條件的查詢所有學生
*/
public List<Student> findAll(Integer id,String name,Double sal) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
Map<String,Object> map = new LinkedHashMap<String,Object>();
map.put("pid",id);
map.put("pname",name);
map.put("psal",sal);
return sqlSession.selectList("studentNamespace.findAll",map);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
List<Student> studentList = dao.findAll(5,"哈哈",7000D);
for(Student s : studentList){
System.out.println(s.getId()+":"+s.getName()+":"+s.getSal());
}
}
}
② StudentMapper.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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.app11.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<select id="findAll" parameterType="map" resultMap="studentMap">
select * from students
<where>
<if test="pid!=null">
and students_id = #{pid}
</if>
<if test="pname!=null">
and students_name = #{pname}
</if>
<if test="psal!=null">
and students_sal = #{psal}
</if>
</where>
</select>
</mapper>
2、更新
更新條件不確定,需要根據情況產生SQL語法,這種情況叫動態SQL
① StudentDao.java
public class StudentDao {
/**
* 有條件更新學生
*/
public void dynaUpdate(Integer id,String name,Double sal) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
Map<String,Object> map = new HashMap<String, Object>();
map.put("pid",id);
map.put("pname",name);
map.put("psal",sal);
sqlSession.update("studentNamespace.dynaUpdate",map);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
//關注SQL的變化
//dao.dynaUpdate(1,null,9000D);//update students set sal=? where id=?
//dao.dynaUpdate(1,"笨笨",null);//update students set name=? where id=?
dao.dynaUpdate(1,"笨笨",10000D);//update students set name=? and sal=? where id=?
}
}
② StudentMapper.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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.app12.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<!-- set標籤自動判斷哪個是最後一個欄位,會自動去掉最後一個,號 -->
<update id="dynaUpdate" parameterType="map">
update students
<set>
<if test="pname!=null">
students_name = #{pname},
</if>
<if test="psal!=null">
students_sal = #{psal},
</if>
</set>
where students_id = #{pid}
</update>
</mapper>
3、刪除
根據ID刪除學生
① StudentDao.java
public class StudentDao {
/**
* 根據ID批量刪除學生(陣列版本)
*/
public void dynaDeleteArray(int... ids) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.delete("studentNamespace.dynaDeleteArray",ids);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 根據ID批量刪除學生(集合版本)
*/
public void dynaDeleteList(List<Integer> ids) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.delete("studentNamespace.dynaDeleteList",ids);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
//dao.dynaDeleteArray(new int[]{1,3,5,7,77});
//dao.dynaDeleteArray(1,3,5,7,77);
//dao.dynaDeleteArray(2,4,444);
List<Integer> ids = new ArrayList<Integer>();
ids.add(6);
ids.add(8);
ids.add(9);
dao.dynaDeleteList(ids);
}
}
② StudentMapper.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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.app13.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<delete id="dynaDeleteArray">
delete from students where students_id in
<!-- foreach用於迭代陣列元素
open表示開始符號
close表示結束符號
separator表示元素間的分隔符
item表示迭代的陣列,屬性值可以任意,但提倡與方法的陣列名相同
#{ids}表示陣列中的每個元素值
-->
<foreach collection="array" open="(" close=")" separator="," item="ids">
#{ids}
</foreach>
</delete>
<delete id="dynaDeleteList">
delete from students where students_id in
<foreach collection="list" open="(" close=")" separator="," item="ids">
#{ids}
</foreach>
</delete>
</mapper>
4、插入
根據條件,插入一個學生
① StudentDao.java
public class StudentDao {
/**
* 插入學生
*/
public void dynaInsert(Student student) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
sqlSession.insert("studentNamespace.dynaInsert",student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentDao dao = new StudentDao();
//dao.dynaInsert(new Student(1,"哈哈",7000D));//insert into 表名(*,*,*) values(?,?,?)
//dao.dynaInsert(new Student(2,"哈哈",null));//insert into 表名(*,*) values(?,?)
//dao.dynaInsert(new Student(3,null,7000D));//insert into 表名(*,*) values(?,?)
dao.dynaInsert(new Student(4,null,null));//insert into 表名(*) values(?)
}
}
② StudentMapper.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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.app14.Student" id="studentMap">
<id property="id" column="students_id"/>
<result property="name" column="students_name"/>
<result property="sal" column="students_sal"/>
</resultMap>
<!-- sql片段對應欄位名,id屬性值任意 -->
<sql id="key">
<!-- 去掉最後一個, -->
<trim suffixOverrides=",">
<if test="id!=null">
students_id,
</if>
<if test="name!=null">
students_name,
</if>
<if test="sal!=null">
students_sal,
</if>
</trim>
</sql>
<!-- sql片段對應?,id屬性值任意 -->
<sql id="value">
<!-- 去掉最後一個, -->
<trim suffixOverrides=",">
<if test="id!=null">
#{id},
</if>
<if test="name!=null">
#{name},
</if>
<if test="sal!=null">
#{sal},
</if>
</trim>
</sql>
<!-- <include refid="key"/>和<include refid="value"/>表示引用上面定義的sql片段 -->
<insert id="dynaInsert" parameterType="cn.itcast.javaee.mybatis.app14.Student">
insert into students(<include refid="key"/>) values(<include refid="value"/>)
</insert>
</mapper>
三、多表查詢
1、回顧SQL99中的連線查詢
drop table if exists orders;
drop table if exists customers;
drop table if exists emps;
create table if not exists customers(
id int(5) primary key auto_increment,
name varchar(10) not null,
age int(2) not null
);
insert into customers(name,age) values('諸葛亮',33);
insert into customers(name,age) values('孫權',44);
insert into customers(name,age) values('曹操',55);
insert into customers(name,age) values('司馬懿',66);
create table if not exists orders(
id int(5) primary key auto_increment,
isbn varchar(10) not null,
price integer not null,
customers_id int(5),
constraint customers_id_FK foreign key(customers_id) references customers(id)
);
insert into orders(isbn,price,customers_id) values('isbn100',100,1);
insert into orders(isbn,price,customers_id) values('isbn200',200,1);
insert into orders(isbn,price,customers_id) values('isbn100',100,1);
insert into orders(isbn,price,customers_id) values('isbn200',200,2);
insert into orders(isbn,price,customers_id) values('isbn100',100,2);
insert into orders(isbn,price,customers_id) values('isbn100',100,3);
create table if not exists emps(
empno int(5) primary key,
ename varchar(10),
mgr int(5)
);
insert into emps(empno,ename,mgr) values(1,'AA',5);
insert into emps(empno,ename,mgr) values(2,'BB',5);
insert into emps(empno,ename,mgr) values(3,'CC',6);
insert into emps(empno,ename,mgr) values(4,'DD',6);
insert into emps(empno,ename,mgr) values(5,'EE',7);
insert into emps(empno,ename,mgr) values(6,'FF',7);
insert into emps(empno,ename,mgr) values(7,'GG',9);
insert into emps(empno,ename,mgr) values(8,'HH',9);
insert into emps(empno,ename,mgr) values(9,'II',NULL);
select * from customers;
select * from orders;
select * from emps;
① 內連線(等值連線):查詢客戶姓名、訂單編號、訂單價格
---------------------------------------------------
select c.name,o.isbn,o.price
from customers c inner join orders o
where c.id = o.customers_id;
---------------------------------------------------
select c.name,o.isbn,o.price
from customers c join orders o
where c.id = o.customers_id;
---------------------------------------------------
select c.name,o.isbn,o.price
from customers c,orders o
where c.id = o.customers_id;
---------------------------------------------------
select c.name,o.isbn,o.price
from customers c join orders o
on c.id = o.customers_id;
---------------------------------------------------
注意:內連線(等值連線)只能查詢出多張表中連線欄位相同的記錄
② 外連線:按客戶分組,查詢每個客戶的姓名和訂單數
---------------------------------------------------
左外連線:
select c.name,count(o.isbn)
from customers c left outer join orders o
on c.id = o.customers_id
group by c.name;
---------------------------------------------------
右外連線:
select c.name,count(o.isbn)
from orders o right outer join customers c
on c.id = o.customers_id
group by c.name;
---------------------------------------------------
注意:外連線既能查詢出多張表中連線欄位相同的記錄,又能根據一方將另一方不符合相同記錄強行查詢出來
③ 自連線:求出AA的老闆是EE
---------------------------------------------------
內自連線:
select users.ename,boss.ename
from emps users inner join emps boss
on users.mgr = boss.empno;
---------------------------------------------------
外自連線:
select users.ename,boss.ename
from emps users left outer join emps boss
on users.mgr = boss.empno;
---------------------------------------------------
注意:自連線是將一張表,通過別名的方式看作多張表後,再進行連線,這時的連線即可以採用內連線,又可以採用外連線
2、mybatis一對一對映【一名學生對應一張身份證】
① Students.java和Card.java
public class Student {
private Integer id;
private String name;
private Card card;//關聯屬性
public Student(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
}
public class Card {
private Integer id;
private String num;
public Card(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
}
② StudentMapper.xml和CardMapper.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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.one2one.Student" id="studentMap">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!-- 引入CardMapper.xml檔案中的對映資訊
property表示Student類的關聯屬性
resultMap表示引入CardMapper.xml檔案的對映型別
-->
<association property="card" resultMap="cardNamespace.cardMap"/>
</resultMap>
<!-- 查詢1號學生的資訊 -->
<select id="findById" parameterType="int" resultMap="studentMap">
select s.sid,s.sname,c.cid,c.cnum
from students s inner join cards c
on s.scid = c.cid
and s.sid = #{id}
</select>
<!-- 查詢哈哈學生的資訊 -->
<select id="findByName" parameterType="string" resultMap="studentMap">
select s.sname,c.cnum
from students s inner join cards c
on s.scid = c.cid
and s.sname = #{name}
</select>
</mapper>
<?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="cardNamespace">
<resultMap type="cn.itcast.javaee.mybatis.one2one.Card" id="cardMap">
<id property="id" column="cid"/>
<result property="num" column="cnum"/>
</resultMap>
</mapper>
③ StudentCardDao.java
public class StudentCardDao {
/**
* 查詢1號學生的資訊
* @param id 表示學生的編號
*/
public Student findById(int id) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectOne("studentNamespace.findById",id);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 查詢"哈哈"學生的資訊
* @param name 表示學生的姓名
*/
public Student findByName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectOne("studentNamespace.findByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentCardDao dao = new StudentCardDao();
Student s = dao.findById(1);
System.out.println(s.getId()+":"+s.getName()+":"+s.getCard().getId()+":"+s.getCard().getNum());
System.out.println("-------------------------------");
s = dao.findByName("哈哈");
System.out.println(s.getName()+"的身份證號碼為:" + s.getCard().getNum());
}
}
3、mybatis一對多對映【一個班級對應一名學生】
① Grade.java和Student.java
public class Grade {
private Integer id;
private String name;
private List<Student> studentList = new ArrayList<Student>();//關聯屬性
public Grade(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
}
public class Student {
private Integer id;
private String name;
private Grade grade;//關聯屬性
public Student(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
}
② GradeMapper.xml和StudentMapper.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="gradeNamespace">
<resultMap type="cn.itcast.javaee.mybatis.one2many.Grade" id="gradeMap">
<id property="id" column="gid"/>
<result property="name" column="gname"/>
</resultMap>
<!-- 查詢哈哈是哪個學科的 -->
<select id="findByName" parameterType="string" resultMap="gradeMap">
select g.gname
from students s inner join grades g
on s.sgid = g.gid
and s.sname = #{xxxxx}
</select>
</mapper>
<?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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.one2many.Student" id="studentMap">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
</resultMap>
<!-- 查詢java學科有哪些學生資訊 -->
<select id="findAllByName" parameterType="string" resultMap="studentMap">
select s.sid,s.sname
from students s inner join grades g
on s.sgid = g.gid
and g.gname = #{namexxxxxxxxxxxxxxxx}
</select>
</mapper>
③ GradeStudentDao.java
public class GradeStudentDao {
/**
* 查詢java學科有哪些學生資訊
* @param name 表示學科名
*/
public List<Student> findAllByName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectList("studentNamespace.findAllByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 查詢哈哈是哪個學科的
* @param name 表示學生姓名
*/
public Grade findByName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectOne("gradeNamespace.findByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
GradeStudentDao dao = new GradeStudentDao();
List<Student> studentList = dao.findAllByName("java");
System.out.println("java學科有"+studentList.size()+"個學生,它們資訊如下:");
for(Student s : studentList){
System.out.println(s.getId()+":"+s.getName());
}
System.out.println("-----------------------------------------------------------");
Grade grade = dao.findByName("哈哈");
System.out.println("哈哈是"+grade.getName()+"學科的");
System.out.println("-----------------------------------------------------------");
grade = dao.findByName("呵呵");
System.out.println("呵呵是"+grade.getName()+"學科的");
}
}
4、mybatis多對多對映【多名學生對應多門課程】
create table students(
sid int(5) primary key,
sname varchar(10)
);
create table courses(
cid int(5) primary key,
cname varchar(10)
);
create table middles(
msid int(5),
mcid int(5),
primary key(msid,mcid)
);
① Student.java和Course.java
public class Student {
private Integer id;
private String name;
private List<Course> courseList = new ArrayList<Course>();//關聯屬性
public Student(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Course> getCourseList() {
return courseList;
}
public void setCourseList(List<Course> courseList) {
this.courseList = courseList;
}
}
public class Course {
private Integer id;
private String name;
private List<Student> studentList = new ArrayList<Student>();//關聯屬性
public Course(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
}
② StudentMapper.xml和CourseMapper.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="studentNamespace">
<resultMap type="cn.itcast.javaee.mybatis.many2many.Student" id="studentMap">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
</resultMap>
<select id="findAllByCourseName" parameterType="string" resultMap="studentMap">
select s.sname
from students s inner join middles m
on s.sid = m.msid
inner join courses c
on m.mcid = c.cid
and c.cname = #{name}
</select>
</mapper>
<?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="courseNamespace">
<resultMap type="cn.itcast.javaee.mybatis.many2many.Course" id="courseMap">
<id property="id" column="cid"/>
<result property="name" column="cname"/>
</resultMap>
<!-- 查詢哈哈選學了哪些課程 -->
<select id="findAllByName" parameterType="string" resultMap="courseMap">
select c.cid,c.cname
from students s inner join middles m
on s.sid = m.msid
inner join courses c
on m.mcid = c.cid
and s.sname = #{name}
</select>
</mapper>
③ StudentCourseDao.java
public class StudentCourseDao {
/**
* 查詢哈哈選學了哪些課程
* @param name 表示學生的姓名
*/
public List<Course> findAllByName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectList("courseNamespace.findAllByName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
/**
* 查詢java課程有哪些學生選修
* @param name 表示學生的課程
*/
public List<Student> findAllByCourseName(String name) throws Exception{
SqlSession sqlSession = null;
try{
sqlSession = MybatisUtil.getSqlSession();
return sqlSession.selectList("studentNamespace.findAllByCourseName",name);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception{
StudentCourseDao dao = new StudentCourseDao();
List<Course> courseList = dao.findAllByName("哈哈");
System.out.print("哈哈選學了" + courseList.size()+"個課程,分別是:");
for(Course c : courseList){
System.out.print(c.getName()+" ");
}
System.out.println("\n-----------------------------------------------------");
List<Student> studentList = dao.findAllByCourseName("android");
System.out.println("選修了android課程的學生有"+studentList.size()+"個,分別是:");
for(Student s : studentList){
System.out.print(s.getName()+" ");
}
}
}
四、員工管理系統(springmvc+spring+mybatis+oracle)
1、建立一個spring-mybaits-oracle這麼一個javaweb或java工程
2、匯入spring、mybatis、c3p0、oracle(或者mysql)、mybatis提供的與spring整合的外掛包
① mysql的jar:mysql-connector-java-5.1.7-bin.jar
② oracle的jar:ojdbc5.jar
③ c3p0的jar:c3p0-0.9.1.2.jar
④ mybatis的jar:
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
mybatis-3.1.1.jar
⑤ mybatis與spring整合的jar:mybatis-spring-1.1.1.jar
⑥ spring的ioc模組的jar:
org.springframework.asm-3.0.5.RELEASE.jar
org.springframework.beans-3.0.5.RELEASE.jar
org.springframework.context-3.0.5.RELEASE.jar
org.springframework.core-3.0.5.RELEASE.jar
org.springframework.expression-3.0.5.RELEASE.jar
commons-logging.jar
⑦ spring的aop模組的jar:
aopalliance.jar
aspectjweaver.jar
cglib-2.2.2.jar
org.springframework.aop-3.0.5.RELEASE.jar
⑧ spring的transaction模組的jar:
org.springframework.jdbc-3.0.5.RELEASE.jar
org.springframework.orm-3.0.5.RELEASE.jar
org.springframework.transaction-3.0.5.RELEASE.jar
3、建立emps.sql表(使用oracle語法)
create table emps(
eid number(5) primary key,
ename varchar2(20),
esal number(8,2),
esex varchar2(2)
);
4、建立Emp.java類
public class Emp {
private Integer id;
private String name;
private Double sal;
private String sex;
public Emp(){}
public Emp(Integer id, String name, Double sal, String sex) {
this.id = id;
this.name = name;
this.sal = sal;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
5、建立工具類MybatisUtil.java(和spring整合後就不需要使用了)
public class MybatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
/**
* 載入位於src/mybatis.xml配置檔案
*/
static{
try {
Reader reader = Resources.getResourceAsReader("mybatis.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 禁止外界通過new方法建立
*/
private MybatisUtil(){}
/**
* 獲取SqlSession
*/
public static SqlSession getSqlSession(){
//從當前執行緒中獲取SqlSession物件
SqlSession sqlSession = threadLocal.get();
//如果SqlSession物件為空
if(sqlSession == null){
//在SqlSessionFactory非空的情況下,獲取SqlSession物件
sqlSession = sqlSessionFactory.openSession();
//將SqlSession物件與當前執行緒繫結在一起
threadLocal.set(sqlSession);
}
//返回SqlSession物件
return sqlSession;
}
/**
* 關閉SqlSession與當前執行緒分開
*/
public static void closeSqlSession(){
//從當前執行緒中獲取SqlSession物件
SqlSession sqlSession = threadLocal.get();
//如果SqlSession物件非空
if(sqlSession != null){
//關閉SqlSession物件
sqlSession.close();
//分開當前執行緒與SqlSession物件的關係,目的是讓GC儘早回收
threadLocal.remove();
}
}
/**
* 測試
*/
public static void main(String[] args) {
Connection conn = MybatisUtil.getSqlSession().getConnection();
System.out.println(conn!=null?"連線成功":"連線失敗");
}
}
6、建立EmpMapper.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="empNamespace">
<resultMap type="cn.itcast.javaee.mybatis.entity.Emp" id="empMap">
<id property="id" column="eid"/>
<result property="name" column="ename"/>
<result property="sal" column="esal"/>
<result property="sex" column="esex"/>
</resultMap>
<!-- 增加員工 -->
<insert id="add" parameterType="cn.itcast.javaee.mybatis.entity.Emp">
insert into emps(eid,ename,esal,esex) values(#{id},#{name},#{sal},#{sex})
</insert>
</mapper>
7、在src目錄下建立mybatis.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>
<!--
<environments default="oracle_developer">
<environment id="mysql_developer">
<transactionManager type="jdbc"/>
<dataSource type="pooled">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="oracle_developer">
<transactionManager type="jdbc"/>
<dataSource type="pooled">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</dataSource>
</environment>
</environments>
-->
<mappers>
<mapper resource="cn/itcast/javaee/mybatis/entity/EmpMapper.xml"/>
</mappers>
</configuration>
8、建立EmpDao.java類
public class EmpDao {
private SqlSessionFactory sqlSessionFactory;
//springioc容器自動注入
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* 增加員工
*/
public void add(Emp emp) throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("empNamespace.add",emp);
sqlSession.close();
}
}
9、建立TestEmpDao.java測試類
public class TestEmpDao {
//單獨測試mybatis(使用MybatisUtil.java工具類)
@Test
public void test1() throws Exception{
EmpDao empDao = new EmpDao();
empDao.add(new Emp(1,"哈哈",7000D,"男"));
}
//測試spring整合mybatis
@Test
public void test2() throws Exception{
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring.xml"});
EmpDao empDao = (EmpDao) ac.getBean("empDaoID");
empDao.add(new Emp(2,"明明",8000D,"男"));
}
}
10、在src目錄下建立spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
">
<!-- 配置C3P0連線池,目的:管理資料庫連線 -->
<bean id="comboPooledDataSourceID" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
<property name="user" value="scott"/>
<property name="password" value="tiger"/>
</bean>
<!-- 配置SqlSessionFactoryBean,目的:載入mybaits配置檔案和對映檔案,即替代原Mybatis工具類的作用 -->
<bean id="sqlSessionFactoryBeanID" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:mybatis.xml"/>
<property name="dataSource" ref="comboPooledDataSourceID"/>
</bean>
<!-- 配置Mybatis的事務管理器,即因為Mybatis底層用的是JDBC事務管事器,所以在這裡依然配置JDBC事務管理器 -->
<bean id="dataSourceTransactionManagerID" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="comboPooledDataSourceID"/>
</bean>
<!-- 配置事務通知,即讓哪些方法需要事務支援 -->
<tx:advice id="tx" transaction-manager="dataSourceTransactionManagerID">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置事務切面,即讓哪些包下的類需要事務 -->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* cn.itcast.javaee.mybatis.dao.*.*(..))"/>
<aop:advisor advice-ref="tx" pointcut-ref="pointcut"/>
</aop:config>
<!-- 註冊EmpDao -->
<bean id="empDaoID" class="cn.itcast.javaee.mybatis.dao.EmpDao">
<property name="sqlSessionFactory" ref="sqlSessionFactoryBeanID"/>
</bean>
<!-- 註冊EmpService -->
<bean id="empServiceID" class="cn.itcast.javaee.mybatis.service.EmpService">
<property name="empDao" ref="empDaoID"/>
</bean>
<!-- 註冊EmpAction -->
<context:component-scan base-package="cn.itcast.javaee.mybatis.action"/>
<!-- 通知springioc容器這些註解的作用 -->
<context:annotation-config/>
<!-- 檢視解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
11、register.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>員工註冊</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/emp/register.action" method="POST">
<table border="2" align="center">
<tr>
<th>編號</th>
<td><input type="text" name="id"></td>
</tr>
<tr>
<th>姓名</th>
<td><input type="text" name="name"></td>
</tr>
<tr>
<th>薪水</th>
<td><input type="text" name="sal"></td>
</tr>
<tr>
<th>性別</th>
<td>
<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女" checked/>女
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="註冊"/>
</td>
</tr>
</table>
</form>
</body>
</html>
12、success.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>員工註冊</title>
</head>
<body>
註冊成功<br/>
</body>
</html>
13、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 核心springmvc核心控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- POST編碼過濾器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
14、業務層實現類EmpService.java
public class EmpService {
private EmpDao empDao;
public void setEmpDao(EmpDao empDao) {
this.empDao = empDao;
}
/**
* 註冊員工
*/
public void register(Emp emp) throws Exception{
empDao.add(emp);
}
}
15、單例控制器EmpAction.java
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
private EmpService empService;
@Resource(name="empServiceID")
public void setEmpService(EmpService empService) {
this.empService = empService;
}
/**
* 註冊員工
*/
@RequestMapping(value="/register")
public String registerMethod(Emp emp) throws Exception{
//呼叫業務層
empService.register(emp);
return "success";
}
}
五、jdbc訪問oracle儲存過程和儲存函式
1、準備工作
① c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
<property name="jdbcUrl">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
<property name="user">scott</property>
<property name="password">tiger</property>
<property name="acquireIncrement">2</property>
<property name="initialPoolSize">5</property>
<property name="minPoolSize">1</property>
<property name="maxPoolSize">5</property>
</default-config>
</c3p0-config>
② JdbcUtil.java
public class JdbcUtil {
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
public static Connection getConnection() throws Exception{
return dataSource.getConnection();
}
}
2、寫一個計算個人所得稅的應用
--定義過程
create or replace procedure get_rax(salary in number,rax out number)
as
--需要交稅的錢
bal number;
begin
bal := salary - 3500;
if bal<=1500 then
rax := bal * 0.03 - 0;
elsif bal<=4500 then
rax := bal * 0.1 - 105;
elsif bal<=9000 then
rax := bal * 0.2 - 555;
elsif bal<=35000 then
rax := bal * 0.25 - 1005;
elsif bal<=55000 then
rax := bal * 0.3 - 2755;
elsif bal<=80000 then
rax := bal * 0.35 - 5505;
else
rax := bal * 0.45 - 13505;
end if;
end;
/
--呼叫過程
declare
--交稅
rax number;
salary number := &salary;
begin
get_rax(salary,rax);
dbms_output.put_line(salary||'元工資需要交'||rax||'元稅');
end;
/
演示java-jdbc呼叫oracle過程
public class CallOracleProc {
public static void main(String[] args) throws Exception{
String sql = "{call get_rax(?,?)}";
Connection conn = JdbcUtil.getConnection();
CallableStatement cstmt = conn.prepareCall(sql);
//為第一個?號設定值,從1開始
cstmt.setInt(1,7000);
//為第二個?註冊輸出型別
cstmt.registerOutParameter(2,Types.INTEGER);
//執行呼叫過程
cstmt.execute();
//接收過程的返回值,即第二個?號
int rax = cstmt.g