進行了一周的崗前培訓,特到這來總結一下這周學的內容。
本周主要學了iBatis,SQL和TA3(公司自己封裝的框架)的jsp頁面組件。我在想是分開寫還是寫在一起,鑒于是總結本周培訓的相關知識,所以還是寫在一起吧~
iBatis
iBatis是一款使用方便的數據訪問工具,也可作為數據持久層的框架。和ORM框架(如Hibernate)將數據庫表直接映射為Java對象相比,iBatis是將SQL語句映射為Java對象。相對于全自動SQL的Hibernate,iBatis允許你對SQL有完全控制權,可以視為半自動的數據訪問工具。
iBatis在idea配置普通項目的過程就略過了,遇到問題最大的還是老師最后留給我們的將ibatis配置到Web項目中去,那么就大概描述以下,這中間遇到的一系列的坑。
- 在idea中創(chuàng)建web項目,配置過程略過
-
導入iBatis必要的jar包。主要的jar包主要如下:
主要的jar包
在這里注意ojdbc6這個jar包,我在這里踩了坑,具體的錯誤顯示如下:
ORA-28040: No matching authentication protocol(沒有匹配的身份驗證協(xié)議)
具體的解決辦法見下。 - 創(chuàng)建與數據庫表相對應的實體類,比如我創(chuàng)建的account類,其中包含了表中的所需的字段,代碼如下:
package com.yinhai.domain;
public class Account {
private int id;
private String firstName;
private String lastName;
private String emailAddress;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
@Override
public String toString() {
return "Account [id=" + id + ", FirstName=" + firstName + ", LastName=" + lastName + "Email" +
emailAddress + "]";
}
}
-
創(chuàng)建iBatis的配置文件
SqlMapConfig.xml:顧名思義,就是數據庫映射配置文件,即配置數據庫連接環(huán)境,iBatis使用type="SIMPLE"來獲取數據庫環(huán)境
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<!-- Configure a built-in transaction manager. If you're using an
app server, you probably want to use its transaction manager
and a managed datasource -->
<transactionManager type="JDBC" commitRequired="false">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="oracle.jdbc.OracleDriver"/>
<property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="JDBC.Username" value="c##scott"/>
<property name="JDBC.Password" value="tiger"/>
</dataSource>
</transactionManager>
<!--還沒完!這將在后續(xù)配置的過程中完善SqlMapConfig.xml的代碼-->
</sqlMapConfig>
- 創(chuàng)建iBatis的實體與映射關系文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Account">
<!-- Use type aliases to avoid typing the full classname every time. -->
<typeAlias alias="Account" type="com.yinhai.domain.Account"/>
<!-- Result maps describe the mapping between the columns returned
from a query, and the class properties. A result map isn't
necessary if the columns (or aliases) match to the properties
exactly. -->
<resultMap id="AccountResult" class="Account">
<result property="id" column="ACC_ID"/>
<result property="firstName" column="ACC_FIRST_NAME"/>
<result property="lastName" column="ACC_LAST_NAME"/>
<result property="emailAddress" column="ACC_EMAIL"/>
</resultMap>
<!-- Select with no parameters using the result map for Account class. -->
<select id="selectAllAccounts" resultMap="AccountResult">
select * from ACCOUNT
</select>
<!-- A simpler select example without the result map. Note the
aliases to match the properties of the target result class. -->
<select id="selectAccountById" parameterClass="int" resultClass="Account">
select
ACC_ID as id,
ACC_FIRST_NAME as firstName,
ACC_LAST_NAME as lastName,
ACC_EMAIL as emailAddress
from ACCOUNT
where ACC_ID = #id#
</select>
<!-- Insert example, using the Account parameter class -->
<insert id="insertAccount" parameterClass="Account">
insert into ACCOUNT (
ACC_ID,
ACC_FIRST_NAME,
ACC_LAST_NAME,
ACC_EMAIL
)
values (
#id#,
#firstName#,
#lastName#,
#emailAddress#
)
</insert>
<!-- Update example, using the Account parameter class -->
<update id="updateAccount" parameterClass="Account">
update ACCOUNT set
ACC_FIRST_NAME = #firstName#,
ACC_LAST_NAME = #lastName#,
ACC_EMAIL = #emailAddress#
where
ACC_ID = #id#
</update>
<!-- Delete example, using an integer as the parameter class -->
<delete id="deleteAccountById" parameterClass="int">
delete from ACCOUNT where ACC_ID = #id#
</delete>
<select id="queryById" parameterClass="java.lang.Integer" resultClass="java.util.HashMap">
select ACC_ID,
ACC_FIRST_NAME,
ACC_LAST_NAME,
ACC_EMAIL
where ACC_ID = #id#
</select>
</sqlMap>
-
現在我們已經有了Mybatis的配置文件和表與實體之前的映射文件了,因此我們要將配置文件和映射文件關聯起來
下面這個代碼將添加至SqlMapConfig.xml文件中
<sqlMap resource="resources/Account.xml"/>
- 在test包中創(chuàng)建工具測試類SimpleExample,static靜態(tài)語句塊通過配置文件和數據庫的信息,獲取sqlMapper,通過sqlMapper中的數據操縱函數來對數據庫進行操作。
package com.yinhai.test;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.ibatis.common.resources.Resources;
import com.yinhai.domain.Account;
import java.io.Reader;
import java.io.IOException;
import java.util.List;
import java.sql.SQLException;
/**
* This is not a best practices class. It's just an example
* to give you an idea of how iBATIS works. For a more complete
* example, see JPetStore 5.0 at http://www.ibatis.com.
*/
public class SimpleExample {
/**
* SqlMapClient instances are thread safe, so you only need one.
* In this case, we'll use a static singleton. So sue me. ;-)
*/
private static SqlMapClient sqlMapper;
/**
* It's not a good idea to put code that can fail in a class initializer,
* but for sake of argument, here's how you configure an SQL Map.
*/
static {
try{
Reader reader = Resources.getResourceAsReader("resources/SqlMapConfig.xml");
sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);
reader.close();
} catch (IOException e) {
// Fail fast.
throw new RuntimeException("Something bad happened while building the SqlMapClient instance." + e, e);
}
}
public static List selectAllAccounts () throws SQLException {
return sqlMapper.queryForList("selectAllAccounts");
}
public static Account selectAccountById (int id) throws SQLException {
return (Account) sqlMapper.queryForObject("selectAccountById", id);
}
public static void insertAccount (Account account) throws SQLException {
sqlMapper.insert("insertAccount", account);
}
public static void updateAccount (Account account) throws SQLException {
sqlMapper.update("updateAccount", account);
}
public static void deleteAccount (int id) throws SQLException {
sqlMapper.delete("deleteAccount", id);
}
}
至此,我們就把iBatis的環(huán)境配置完畢,下面我們就可以將其與web結合,將數據顯示在網頁上,用到的方法就是簡單的servlet
- 創(chuàng)建ServletDemo類來將數據呈現在web頁面上即可,代碼如下:
package com.yinhai.test;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.List;
@WebServlet("/example")
public class ServletDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
try{
List list = SimpleExample.selectAllAccounts();
out.println(list.toString());
}catch (SQLException e){
e.printStackTrace();
}
}
}
運行效果如圖:

這個是對上文的ORA-28040: No matching authentication protocol(沒有匹配的身份驗證協(xié)議)進行解釋:
問題描述:嘗試利用ojdbc6來連接oracle12c數據庫時發(fā)生該問題
網絡上的解決方法,參見網址:
http://logic.edchen.org/how-to-resolve-ora-28040-no-matching-authentication-protocol/
發(fā)生該錯誤的原因:
There was no acceptable authentication protocol for either client or server.
版本之間可能存在一些互操作性問題,特別是當版本差距很大時。管理員應將客戶端和服務器上的SQLNET.ALLOWED_LOGON_VERSION_SERVER和SQLNET. ALLOWED_LOGON_VERSION_CLIENT參數的值設置為與系統(tǒng)中支持的最低版本軟件匹配的值。
當客戶端對沒有適用于客戶端軟件版本的驗證器創(chuàng)建的用戶帳戶進行身份驗證時,也會引發(fā)此錯誤ORA-28040。在這種情況下,必須重置該帳戶的密碼,以便生成所需的驗證程序并允許驗證成功進行。
應該使用SQLNET.ALLOWED_LOGON_VERSION_SERVER與身份驗證協(xié)議的兩端兼容。
使用該命令的目的在于設置連接到Oracle數據庫實例時允許的最低身份驗證協(xié)議。
使用說明:參數名稱中的version指的是身份驗證協(xié)議的版本,不是Oracle數據庫版本
如果客戶端版本不滿足或者超過此參數定義的值,就會報出ORA-28040: No matching authentication protocol error 或者 ORA-03134: Connections to this server version are no longer supported error.
1.試圖將ojdbc6換成ojdbc8 ---> 調試失敗
2.在sqlnet.ora配置文件中加入SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
----> 成功
Oracle相關
培訓老師只需讓我掌握具體的sql的查詢語句,即數據操縱語言(DML)。關于DDL等其他語言不重點掌握,想來也是,公司部門分工明確,我的崗位是java開發(fā)工程師,并非數據庫管理員,建立用戶,表信息等工作并非我等需要掌握的技能。但是個人覺得還是不能荒廢觸發(fā)器,試圖,索引等相關知識,所以必須有空將其掌握熟悉,以便于整個職業(yè)生涯的發(fā)展。
由于主要學習的是SQL查詢語句,所以將比較難的查詢語句貼上來,以便后續(xù)的復習
題目1:查詢scott用戶下的所有表
答案:
select * from tabs
題目6:查詢所有雇員編號,姓名,工作.按以下格式顯示:編號:7369,姓名:SMITH,工作:CLERK
答案:
select '編號:'||empno || ',姓名:'||ename || ',工作:'||job from emp
題目14:查詢在1981年雇用的員工信息
答案:
除了利用extract(year from hiredate)也可以用to_char(hiredate,’YYYY’)
select * from emp where extract(year from hiredate)=1981
題目43:找出早于12年前受雇的員工信息
答案:months_between(sysdate-hiredate)/12
select * from emp where (sysdate - hiredate)/365 >=12
題目44:以首字母大寫的方式顯示所有員工的姓名
答案:
select upper(substr(ename,1,1)) || lower (substr(ename,2,length(ename)-1)) from emp
題目65:創(chuàng)建報告,顯示員工名和獎金系數,如果獎金系數為空,則顯示"無獎金"
答案:
select ename,decode(comm,'','無獎金',comm) from emp;
解釋:如果comm是null,則返回無獎金,不是null就返回獎金的數目
- decode函數
decode(條件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值),這行代碼就是decode全部的精髓以及用法。
該函數的含義如下:
IF 條件=值1 THEN RETURN(返回值1)
ELS IF 條件=值2 THEN RETURN(返回值2)
......
ELSIF 條件=值n THEN RETURN(返回值n)
ELSE RETURN(缺省值)
END IF
decode(字段或字段的運算,值1,值2,值3)
這個函數運行的結果是,當字段或字段的運算的值等于值1時,該函數返回值2,否則返回值3
當然值1,值2,值3也可以是表達式,這個函數使得某些sql語句簡單了許多
下面舉兩個栗子:
栗子1:
你要統(tǒng)計students表中,男生女生的數量:
傳統(tǒng)寫法如下:
select count() from students where 性別 = 男;
select count() from students where 性別 = 女;
然后使用Union連接,得到最終的統(tǒng)計結果。
現在你只需要這樣來寫:
select decode(性別,男,1,0),decode(性別,女,1,0) from students
題目67:請使用decode語句,查詢員工的job_id和級別.例如:
Job Grade
AD_PRES A
ST_MAN B
IT_PROG C
SA_REP D
ST_CLERK E
None of the above 0
答案:
select job,decode(job,
'CLERK','E',
'SALESMAN','D',
'ANALYST','C',
'MANAGER','B',
'PRESIDENT','A',
'0')
from emp;
題目68:請使用case語句,查詢員工的job_id和級別.例如:
Job Grade
AD_PRES A
ST_MAN B
IT_PROG C
SA_REP D
ST_CLERK E
None of the above 0
答案:
SELECT job_id, CASE job_id
WHEN 'ST_CLERK' THEN 'E'
WHEN 'SA_REP' THEN 'D'
WHEN 'IT_PROG' THEN 'C'
WHEN 'ST_MAN' THEN 'B'
WHEN 'AD_PRES' THEN 'A'
ELSE '0' END GRADE
from employees;
題目78:查詢每個部門中工資最高的雇員姓名,工作,工資,部門名稱,最后按工資從高到低排序,工資相同的情況下按姓名排升序
答案:
select e.ename,e.job,e.sal,d.dname
from emp e,dept d,(select max(e.sal) sal
from emp e,dept d
where e.deptno=d.deptno
group by d.deptno) temp
where e.deptno=d.deptno and e.sal=temp.sal
order by e.sal desc;
題目81:按部門分組,并顯示部門的名稱,以及每個部門的員工數
答案:
select d.dname,count(e.empno)
from dept d left join emp e
on e.deptno=d.deptno
group by e.deptno,d.dname;
TA3Cloud具體學習
今天剛開頭,僅僅學了jsp頁面組件,后續(xù)在更新
