視頻觀看地址:http://edu.51cto.com/course/14674.html?source=sohtml
<!-- id:保證惟一 resultMap和resultType只能2選其一 parameterType:參數類型(基本數據類型、pojo、HashMap) --> <select id="selectUserById" parameterType="" resultMap="" resultType="User"> select userid,user_name as userName,age,pwd,sex,birthday from tb_user where userid = #{userid} </select>
先使用resultMap解決數據庫字段名和java屬性名不一致的問題java
修改mapper.xml文件sql
<resultMap type="User" id="UserMap" autoMapping="true"> <!-- id表示主鍵,必須設置 column:數據庫列名稱 property:實體類中的屬性名 --> <id column="userid" property="userid"/> <result column="user_name" property="userName"/> </resultMap> <select id = "selectAll" resultMap="UserMap"> select * from tb_user </select>
爲了測試完美,將駝峯命名關閉數據庫
<settings> <setting name="mapUnderscoreToCamelCase" value="false"/> </settings>
日誌文件apache
DEBUG - Opening JDBC Connection DEBUG - Created connection 25899648. DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@18b3280] DEBUG - ==> Preparing: select * from tb_user DEBUG - ==> Parameters: DEBUG - <== Total: 5 User [userid=8, userName=阿珂, pwd=123456, age=18, sex=女, birthday=Mon Aug 13 14:06:14 CST 2018] User [userid=2, userName=張三, pwd=123456, age=10, sex=男, birthday=Mon Aug 13 10:07:55 CST 2018] User [userid=3, userName=李四, pwd=123456, age=10, sex=男, birthday=Mon Aug 13 10:07:55 CST 2018] User [userid=4, userName=王五, pwd=123456, age=10, sex=男, birthday=Mon Aug 13 10:07:55 CST 2018] User [userid=5, userName=趙六, pwd=123456, age=10, sex=男, birthday=Mon Aug 13 10:07:55 CST 2018] DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@18b3280] DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@18b3280] DEBUG - Returned connection 25899648 to pool.
總結一下:解決數據庫名和屬性名一致的解決方案:session
1.別名oracle
2.駝峯命名app
3.resultMapdom
修改mapper.xml文件eclipse
<!-- useGeneratedKeys:將生成的id返回給java對象 keyColumn:主鍵列 keyProperty:主鍵的屬性(業務屬性) --> <insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyColumn="userid" keyProperty="userid"> insert into tb_user(userid,user_name,age,pwd,sex,birthday) values(seq_user.nextval,#{userName},#{age},#{pwd},#{sex},#{birthday}) </insert>
測試代碼中
@Test public void testInsertUser() { User vo = new User("阿珂3", "123456", 18, "女", new Date()); try { userMapper.insertUser(vo); //提交事務 sqlSession.commit(); System.out.println(vo.getUserid()); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); } }
測試日誌
DEBUG - Opening JDBC Connection DEBUG - Created connection 1434803926. DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@55855ed6] DEBUG - ==> Preparing: insert into tb_user(userid,user_name,age,pwd,sex,birthday) values(seq_user.nextval,?,?,?,?,?) DEBUG - ==> Parameters: 阿珂3(String), 18(Integer), 123456(String), 女(String), 2018-08-13 14:57:50.296(Timestamp) DEBUG - <== Updates: 1 DEBUG - Committing JDBC Connection [oracle.jdbc.driver.T4CConnection@55855ed6] 10 DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@55855ed6] DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@55855ed6] DEBUG - Returned connection 1434803926 to pool.
當參數有多個的時候,咱們能夠採用天然數,或者pojo對象
方式一:採用天然數傳遞
需求:按照用戶的姓名和年齡進行查詢數據
一、添加一個方法
public List<User> queryByNameAndAge(String name,int age) throws Exception;
二、編寫mapper.xml文件
<select id="queryByNameAndAge" resultMap="UserMap"> select * from tb_user where user_name like #{0} and age =#{1} </select>
三、執行測試代碼
@Test public void testQueryByNameAndAge() throws Exception{ List<User> list = userMapper.queryByNameAndAge("%阿%", 18); for (User user : list) { System.out.println(user); } }
日誌文件
DEBUG - Opening JDBC Connection DEBUG - Created connection 707919597. DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@2a31feed] DEBUG - ==> Preparing: select * from tb_user where user_name like ? and age =? DEBUG - ==> Parameters: %阿%(String), 18(Integer) DEBUG - <== Total: 3 User [userid=8, userName=阿珂, pwd=123456, age=18, sex=女, birthday=Mon Aug 13 14:06:14 CST 2018] User [userid=9, userName=阿珂2, pwd=123456, age=18, sex=女, birthday=Mon Aug 13 14:56:45 CST 2018] User [userid=10, userName=阿珂3, pwd=123456, age=18, sex=女, birthday=Mon Aug 13 14:57:50 CST 2018] DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@2a31feed] DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@2a31feed] DEBUG - Returned connection 707919597 to pool.
實際上還能夠同param傳遞,可是param在傳遞的時候從1開始
修改mapper.xml
<select id="queryByNameAndAge" resultMap="UserMap"> select * from tb_user where user_name like #{param1} and age =#{param2} </select>
可是以上方式實際上可讀性並不高,通常咱們能夠採用註解的形式:
方式二:採用註解的方式傳遞離散的參數
接口的聲明以下
public List<User> queryByNameAndAge(@Param("name")String name,@Param("age")int age) throws Exception;
mapper.xml文件就能夠按以下方式編寫
<select id="queryByNameAndAge" resultMap="UserMap"> select * from tb_user where user_name like #{name} and age =#{age} </select>
方式三:直接傳遞一個pojo對象
一、首先建立一個查詢對象,這個對象中封裝了查詢須要的參數
package cn.org.kingdom.pojo; import java.io.Serializable; public class QueryUser implements Serializable { private String name ; private int age ; public QueryUser() { super(); } public QueryUser(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
二、編寫接口方法
public List<User> queryByPojo(QueryUser vo) throws Exception;
三、編寫mapper.xml文件
<select id = "queryByPojo" parameterType="QueryUser" resultMap="UserMap"> select * from tb_user where user_name like #{name} and age =#{age} </select>
四、測試
@Test public void testQueryByNameAndAge2() throws Exception{ QueryUser vo = new QueryUser("%阿%", 18); List<User> list = userMapper.queryByPojo(vo); for (User user : list) { System.out.println(user); } }
總結:通常狀況下在開發中,會優先選擇註解和pojo的方式來進行開發,關於天然數的方式,你們瞭解便可
需求:
數據庫有兩個如出一轍的表。歷史表,當前表
查詢表中的信息,有時候從歷史表中去查詢數據,有時候須要去新的表去查詢數據。
但願使用 1 個方法來完成操做
接口方法定義
public List<User> queryByTableName(@Param("tableName")String tableName) throws Exception;
mapper.xml文件定義
<select id= "queryByTableName" resultMap="UserMap"> select * from #{tableName} </select>
測試類代碼
@Test public void testQuerybyTableName() throws Exception{ List<User> list = userMapper.queryByTableName("tb_user_hi"); for (User user : list) { System.out.println(user); } }
運行:
org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.sql.SQLException: ORA-00903: 表名無效 ### The error may exist in cn/org/kingdom/mapper/UserMapper.xml ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### SQL: select * from ? ### Cause: java.sql.SQLException: ORA-00903: 表名無效 at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:26) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:111) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102) at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:119) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) at com.sun.proxy.$Proxy4.queryByTableName(Unknown Source) at cn.org.kingdom.test.MyBatisTest01.testQuerybyTableName(MyBatisTest01.java:120) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4Cla***unner.runChild(BlockJUnit4Cla***unner.java:70) at org.junit.runners.BlockJUnit4Cla***unner.runChild(BlockJUnit4Cla***unner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
發現有問題,實際上#{}方式經過?形式進行傳遞參數的,?它不支持tableName
將#{}換成${}
<select id= "queryByTableName" resultMap="UserMap"> select * from ${tableName} </select>
再次運行
DEBUG - Opening JDBC Connection DEBUG - Created connection 1891119713. DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@70b83261] DEBUG - ==> Preparing: select * from tb_user_hi DEBUG - ==> Parameters: DEBUG - <== Total: 2 User [userid=2, userName=張三, pwd=123456, age=10, sex=男, birthday=Mon Aug 13 10:07:55 CST 2018] User [userid=3, userName=李四, pwd=123456, age=10, sex=男, birthday=Mon Aug 13 10:07:55 CST 2018] DEBUG - Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@70b83261] DEBUG - Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@70b83261] DEBUG - Returned connection 1891119713 to pool.
總結:
#{} :表示sql中的參數部分,實際上底層使用的是PreparedStatement
${}:表示字符串拼接,實際上底層採用的Statement對象
能使用#{}的地方均可以使用${}代替,可是能使用${}的地方不必定可以用#{}來替代