Mybatis第一天

第一天:java

  1. mybatis的介紹
  2. Mybatis的入門
    1. 使用jdbc操做數據庫存在的問題
    2. Mybatis的架構
    3. Mybatis的入門程序
  3. Dao的開發方法
    1. 原始dao的開發方法
    2. 動態代理方式
  4. SqlMapConfig.xml文件說明
    1. 介紹

MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,而且更名爲MyBatis 201311月遷移到Github    MyBatis是一個優秀的持久層框架,它對jdbc的操做數據庫的過程進行封裝,使開發者只須要關注 SQL 自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼mysql

Mybatis經過xml或註解的方式將要執行的各類statementstatementpreparedStatemntCallableStatement)配置起來,並經過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。程序員

mybatis-3.2.7.jar----mybatis的核心包spring

lib----mybatis的依賴包sql

mybatis-3.2.7.pdf----mybatis使用手冊數據庫

 

使用jdbc編程問題總結:

JDBC程序:( jdbc的原始方法(未經封裝)實現了查詢數據庫表記錄的操做。)apache

publicstaticvoid main(String[] args) { 編程

            Connection connection = null; 緩存

            PreparedStatement preparedStatement = null; 安全

            ResultSet resultSet = null;

            

            try {

                //加載數據庫驅動

                Class.forName("com.mysql.jdbc.Driver");

                

                //經過驅動管理類獲取數據庫連接

                connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");

                //定義sql語句 ?表示佔位符

            String sql = "select * from user where username = ?";

                //獲取預處理statement

                preparedStatement = connection.prepareStatement(sql);

                //設置參數,第一個參數爲sql語句中參數的序號(從1開始),第二個參數爲設置的參數值

                preparedStatement.setString(1, "");

                //向數據庫發出sql執行查詢,查詢出結果集

                resultSet = preparedStatement.executeQuery();

                //遍歷查詢結果集

                while(resultSet.next()){

                    System.out.println(resultSet.getString("id")+""+resultSet.getString("username"));

                }

            } catch (Exception e) {

                e.printStackTrace();

            }finally{

                //釋放資源

                if(resultSet!=null){

                    try {

                        resultSet.close();

                    } catch (SQLException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }

                if(preparedStatement!=null){

                    try {

                        preparedStatement.close();

                    } catch (SQLException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }

                if(connection!=null){

                    try {

                        connection.close();

                    } catch (SQLException e) {

                        // TODO Auto-generated catch block

                        e.printStackTrace();

                    }

                }

 

            }

 

        }

jdbc問題總結以下:

  1. 數據庫連接建立、釋放頻繁形成系統資源浪費從而影響系統性能,若是使用數據庫連接池可解決此問題。
  2. Sql語句在代碼中硬編碼(sql語句被寫死了),形成代碼不易維護,實際應用sql變化的可能較大,sql變更須要改變java代碼。
  3. 使用preparedStatement向佔有位符號傳參數存在硬編碼,由於sql語句的where條件不必定,可能多也可能少,修改sql還要修改代碼,系統不易維護。
  4. 對結果集解析存在硬編碼(查詢列名),sql變化致使解析代碼變化,系統不易維護,若是能將數據庫記錄封裝成pojo對象解析比較方便

    Mybatis架構

 

 

  1. mybatis配置

SqlMapConfig.xml,此文件做爲mybatis的全局配置文件,配置了mybatis的運行環境等信息。

mapper.xml文件即sql映射文件,文件中配置了操做數據庫的sql語句。此文件須要在SqlMapConfig.xml中加載。

  1. 經過mybatis環境等配置信息構造SqlSessionFactory即會話工廠
  2. 由會話工廠建立sqlSession即會話,操做數據庫須要經過sqlSession進行。
  3. mybatis底層自定義了Executor執行器接口操做數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。
  4. Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id便是Mapped statement的id。
  5. Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。
  6. Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor經過Mapped Statement在執行sql後將輸出結果映射至java對象中,輸出結果映射過程至關於jdbc編程中對結果的解析處理過程。
    1. Mybatis入門程序:

需求:

實現如下功能:

根據用戶id查詢一個用戶信息

根據用戶名稱模糊查詢用戶信息列表

添加用戶

更新用戶

刪除用戶

先新建數據庫mybatis再導入sql數據

DROP TABLE IF EXISTS `orders`;

CREATE TABLE `orders` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`user_id` int(11) NOT NULL COMMENT '下單用戶id',

`number` varchar(32) NOT NULL COMMENT '訂單號',

`createtime` datetime NOT NULL COMMENT '建立訂單時間',

`note` varchar(100) DEFAULT NULL COMMENT '備註',

PRIMARY KEY (`id`),

KEY `FK_orders_1` (`user_id`),

CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION

) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

 

INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);

INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);

INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);

 

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`username` varchar(32) NOT NULL COMMENT '用戶名稱',

`birthday` date DEFAULT NULL COMMENT '生日',

`sex` char(1) DEFAULT NULL COMMENT '性別',

`address` varchar(256) DEFAULT NULL COMMENT '地址',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;

 

INSERT INTO `user` VALUES ('1', '王五', null, '2', null);

INSERT INTO `user` VALUES ('10', '張三', '2014-07-10', '1', '北京市');

INSERT INTO `user` VALUES ('16', '張小明', null, '1', '河南鄭州');

INSERT INTO `user` VALUES ('22', '陳小明', null, '1', '河南鄭州');

INSERT INTO `user` VALUES ('24', '張三丰', null, '1', '河南鄭州');

INSERT INTO `user` VALUES ('25', '陳小明', null, '1', '河南鄭州');

INSERT INTO `user` VALUES ('26', '王五', null, null, null);

再創建項目,搭建相應項目結構,導入jar包:

 

User.java:

package cn.itheima.pojo;

 

import java.util.Date;

 

public class User {

    private int id;

    private String username;// 用戶姓名

    private String sex;// 性別

    private Date birthday;// 生日

    private String address;// 地址

 

…get,set方法

 

    @Override

    public String toString() {

        return "User [id=" + id + ", username=" + username + ", sex=" + sex

                + ", birthday=" + birthday + ", address=" + address + "]";

    }

}

SqlMapConfig.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>

    <properties resource="db.properties"></properties>

    

    <typeAliases>

        <!-- 定義單個pojo類別名

        type:類的全路勁名稱

        alias:別名

         -->

<!--         <typeAlias type="cn.itheima.pojo.User" alias="user"/> -->

        

        <!-- 使用包掃描的方式批量定義別名

        定之後別名等於類名,不區分大小寫,可是建議按照java命名規則來,首字母小寫,之後每一個單詞的首字母大寫

        -->

        <package name="cn.itheima.pojo"/>

    </typeAliases>

 

    <!-- spring整合後 environments配置將廢除-->

    <environments default="development">

        <environment id="development">

        <!-- 使用jdbc事務管理-->

        <transactionManager type="JDBC" />

        <!-- 數據庫鏈接池-->

        <dataSource type="POOLED">

            <property name="driver" value="${jdbc.driver}" />

            <property name="url" value="${jdbc.url}" />

            <property name="username" value="${jdbc.username}" />

            <property name="password" value="${jdbc.password}" />

        </dataSource>

        </environment>

    </environments>

    

    <mappers>

        <mapper resource="User.xml"/>

        

        <!--

        使用class屬性引入接口的全路徑名稱:

        使用規則:

            1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

            2. 接口和映射文件要放在同一個目錄下

         -->

<!--         <mapper class="cn.itheima.mapper.UserMapper"/> -->

        

        <!-- 使用包掃描的方式批量引入Mapper接口

                使用規則:

                1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

                2. 接口和映射文件要放在同一個目錄下

        -->

        <package name="cn.itheima.mapper"/>

    </mappers>

</configuration>

log4j.properties:

# Global logging configuration

log4j.rootLogger=DEBUG, stdout

# Console output...

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

db.properties:

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8

jdbc.username=root

jdbc.password=root

User.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:命名空間,sql隔離 -->

<mapper namespace="test">

    <!--

    id:sql語句惟一標識

    parameterType:指定傳入參數類型

    resultType:返回結果集類型

    #{}佔位符:起到佔位做用,若是傳入的是基本類型(string,long,double,int,boolean,float),那麼#{}中的變量名稱能夠隨意寫.

     -->

    <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itheima.pojo.User">

        SELECT * FROM USER WHERE id = #{id}

    </select>

    

    <!--

    若是返回結果爲集合,能夠調用selectList方法,這個方法返回的結果就是一個集合,因此映射文件中應該配置成集合泛型的類型

    ${}拼接符:字符串原樣拼接,若是傳入的參數是基本類型(string,long,double,int,boolean,float),那麼${}中的變量名稱必須是value

    注意:拼接符有sql注入的風險,因此慎重使用.通常等於號後寫佔位符,like後寫拼接符.

     -->

    <select id="findUserByUserName" parameterType="java.lang.String" resultType="cn.itheima.pojo.User">

        SELECT * FROM USER WHERE username LIKE '%${value}%'

    </select>

    

    <!--

    #{}:若是傳入的是pojo類型,那麼#{}中的變量名稱必須是pojo中對應的屬性.屬性.屬性.....

    若是要返回數據庫自增主鍵:可使用select LAST_INSERT_ID()

     -->

    <insert id="insertUser" parameterType="cn.itheima.pojo.User">

        <!-- 執行 select LAST_INSERT_ID()數據庫函數,返回自增的主鍵

        keyProperty:將返回的主鍵放入傳入參數的Id中保存.

        order:當前函數相對於insert語句的執行順序,insert前執行是before,insert後執行是AFTER

由於這裏Userid是自增的(數據庫管理的),因此在只有插入以後,id纔有值,沒插入以前是默認值0.

        resultType:id的類型,也就是keyproperties中屬性的類型

        -->

        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">

            SELECT LAST_INSERT_ID()

        </selectKey>

        insert into user (username,birthday,sex,address) values(#{username}, #{birthday}, #{sex}, #{address})

    </insert>

    

    <delete id="delUserById" parameterType="java.lang.Integer">

        DELETE FROM USER WHERE id=#{id}

    </delete>

    

    <update id="updateUserById" parameterType="cn.itheima.pojo.User">

        UPDATE USER SET     username=#{username} WHERE id = #{id}

    </update>

    

</mapper>

UserTest.java:

package cn.itheima.test;

 

import java.io.InputStream;

import java.util.Date;

import java.util.List;

 

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.Test;

 

import cn.itheima.pojo.User;

 

public class UserTest {

 

 

    @Test

    public void testFindUserById() throws Exception{

        String resource = "SqlMapConfig.xml";

        //經過流將核心配置文件讀取進來

        InputStream inputStream = Resources.getResourceAsStream(resource);

        //經過核心配置文件輸入流來建立會話工廠

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        //經過工廠建立會話

        SqlSession openSession = factory.openSession();

        //第一個參數:所調用的sql語句= namespace+.+sql的ID

        User user = openSession.selectOne("test.findUserById", 1);

        System.out.println(user);

        openSession.close();

    }

    

    @Test

    public void testFindUserByUserName() throws Exception{

        String resource = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = factory.openSession();

        List<User> list = session.selectList("test.findUserByUserName", "王");

        System.out.println(list);

    }

    

    @Test

    public void testInsertUser() throws Exception{

        String config = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(config);

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = factory.openSession();

        

        User user = new User();

        user.setUsername("王子");

        user.setBirthday(new Date());

        user.setSex("男");

        user.setAddress("廣州");

        

        System.out.println("=============="+user.getId());

        session.insert("test.insertUser", user);

        //提交事務(mybatis會自動開啓事務,可是它不知道什麼時候提交,因此須要手動提交事務)

        session.commit();

        System.out.println("=============="+user.getId());

        

    }

    

    @Test

    public void testDelUserById() throws Exception{

        String resource = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = factory.openSession();

        

        session.delete("test.delUserById", 22);

        session.commit();

    }

    

    @Test

    public void testUpdateUserById() throws Exception{

        String config = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(config);

        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = factory.openSession();

        

        User user = new User();

        user.setUsername("張大千");

        user.setId(25);

        session.update("test.updateUserById", user);

        session.commit();

        

    }

}

  • Tips:步驟是先在SQLyog中寫出正確的sql語句,再把sql語句複製到User.xml中,寫好User.xml後再去寫UserTest.java.

若是Mysql使用 uuid實現主鍵

 

須要增長經過select uuid()獲得uuid值

 

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">

<selectKey resultType="java.lang.String" order="BEFORE"

keyProperty="id">

select uuid()

</selectKey>

insert into user(id,username,birthday,sex,address)

         values(#{id},#{username},#{birthday},#{sex},#{address})

</insert>

注意這裏使用的order是"BEFORE".由於select uuid()就是數據庫中的操做語句,用來給id賦予隨機的字符串.在插入數據以前就得先給id賦值,否則會報錯.

 

三.Mybatis原生Dao實現:

先新建Dao和test:

UserDao:

package cn.itheima.dao;

 

import java.util.List;

 

import cn.itheima.pojo.User;

 

public interface UserDao {

    

    public User findById(Integer id);

    

    public List<User> findByUserName(String userName);

    

}

UserDaoImpl:

package cn.itheima.dao;

 

import java.util.List;

 

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

 

import cn.itheima.pojo.User;

 

public class UserDaoImpl implements UserDao{

 

    private SqlSessionFactory sqlSessionFactory;

    //經過構造方法注入

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {

        this.sqlSessionFactory = sqlSessionFactory;

    }

 

    @Override

    public User findById(Integer id) {

        //sessionFactory是線程不安全的,因此他應該在方法體內注入

        SqlSession session = sqlSessionFactory.openSession();

        User user = session.selectOne("test.findUserById", id);

        return user;

    }

 

    @Override

    public List<User> findByUserName(String userName) {

        SqlSession session = sqlSessionFactory.openSession();

        List<User> list = session.selectList("test.findUserByUserName", userName);

        return list;

    }

}

UserDaoTest:

package cn.itheima.test;

 

import java.io.InputStream;

import java.util.List;

 

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.Before;

import org.junit.Test;

 

import cn.itheima.dao.UserDao;

import cn.itheima.dao.UserDaoImpl;

import cn.itheima.pojo.User;

 

public class UserDaoTest {

 

    private SqlSessionFactory factory;

    

    @Before

    public void setUp() throws Exception{

        String config = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(config);

        factory = new SqlSessionFactoryBuilder().build(inputStream);

    }

    

    @Test

    public void findById() throws Exception{

        //將初始化好的工廠注入到實現類中

        UserDao userDao = new UserDaoImpl(factory);

        

        System.out.println(userDao.findById(25));

    }

    

    @Test

    public void findByUserName() throws Exception{

        UserDao userDao = new UserDaoImpl(factory);

        System.out.println(userDao.findByUserName(""));

    }

}

  1. Mybatis動態代理Dao實現:

開發規範

    Mapper接口開發方法只須要程序員編寫Mapper接口(至關於Dao接口),由Mybatis框架根據接口定義建立接口的動態代理對象,代理對象的方法體同上邊Dao接口實現類方法。

Mapper接口開發須要遵循如下規範:

  1. Mapper.xml文件中的namespace與mapper接口的類路徑相同。
  2. Mapper接口方法名和Mapper.xml中定義的每一個statement的id相同
  3. Mapper接口方法的輸入參數類型和mapper.xml中定義的每一個sql 的parameterType的類型相同
  4. Mapper接口方法的輸出參數類型和mapper.xml中定義的每一個sql的resultType的類型相同

 

先新建mapper包,包下新建UserMapper.java和UserMapper.xml,再來個測試類:

UserMapper.xml:(和以前的User.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接口代理實現編寫規則:

    1. 映射文件中namespace要等於接口的全路徑名稱

    2. 映射文件中sql語句id要等於接口的方法名稱

    3. 映射文件中傳入參數類型要等於接口方法的傳入參數類型

    4. 映射文件中返回結果集類型要等於接口方法的返回值類型

-->

<mapper namespace="cn.itheima.mapper.UserMapper">

 

    <!--

    id:sql語句惟一標識

    parameterType:指定傳入參數類型

    resultType:返回結果集類型

    #{}佔位符:起到佔位做用,若是傳入的是基本類型(string,long,double,int,boolean,float),那麼#{}中的變量名稱能夠隨意寫.

     -->

    <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.itheima.pojo.User">

        select * from user where id=#{id}

    </select>

    

    <!--

    若是返回結果爲集合,能夠調用selectList方法,這個方法返回的結果就是一個集合,因此映射文件中應該配置成集合泛型的類型

    ${}拼接符:字符串原樣拼接,若是傳入的參數是基本類型(string,long,double,int,boolean,float),那麼${}中的變量名稱必須是value

    注意:拼接符有sql注入的風險,因此慎重使用

     -->

    <select id="findUserByUserName" parameterType="java.lang.String" resultType="user">

        select * from user where username like '%${value}%'

    </select>

    

    <!--

    #{}:若是傳入的是pojo類型,那麼#{}中的變量名稱必須是pojo中對應的屬性.屬性.屬性.....

    若是要返回數據庫自增主鍵:可使用select LAST_INSERT_ID()

     -->

    <insert id="insertUser" parameterType="cn.itheima.pojo.User" >

        <!-- 執行 select LAST_INSERT_ID()數據庫函數,返回自增的主鍵

        keyProperty:將返回的主鍵放入傳入參數的Id中保存.

        order:當前函數相對於insert語句的執行順序,insert前執行是before,insert後執行是AFTER

        resultType:id的類型,也就是keyproperties中屬性的類型

        -->

        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">

            select LAST_INSERT_ID()

        </selectKey>

        insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})

    </insert>

</mapper>

UserMapper.java:

package cn.itheima.mapper;

 

import java.util.List;

 

import cn.itheima.pojo.User;

 

public interface UserMapper {

    

    public User findUserById(Integer id);

    

    public List<User> findUserByUserName(String userName);

    

    public void insertUser(User user);

}

接着要在SqlMapConfig.xml中引入UserMapper.xml:

<mappers>

        <mapper resource="User.xml"/>

        

        <!--

        使用class屬性引入接口的全路徑名稱:

        使用規則:

            1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

            2. 接口和映射文件要放在同一個目錄下

         -->

        <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->

</mappers>

UserMapperTest.java:

package cn.itheima.test;

import java.io.InputStream;

import java.util.Date;

import java.util.List;

 

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import org.junit.Before;

import org.junit.Test;

 

import cn.itheima.mapper.UserMapper;

import cn.itheima.pojo.User;

 

public class UserMapperTest {

    private SqlSessionFactory factory;

    

    //做用:在測試方法前執行這個方法

    @Before

    public void setUp() throws Exception{

        String resource = "SqlMapConfig.xml";

        //經過流將核心配置文件讀取進來

        InputStream inputStream = Resources.getResourceAsStream(resource);

        //經過核心配置文件輸入流來建立會話工廠

        factory = new SqlSessionFactoryBuilder().build(inputStream);

    }

    

    @Test

    public void testFindUserById() throws Exception{

        SqlSession openSession = factory.openSession();

        //經過getMapper方法來實例化接口

        UserMapper mapper = openSession.getMapper(UserMapper.class);

        

        User user = mapper.findUserById(1);

        System.out.println(user);

    }

    

    @Test

    public void testFindUserByUserName() throws Exception{

        SqlSession openSession = factory.openSession();

        //經過getMapper方法來實例化接口

        UserMapper mapper = openSession.getMapper(UserMapper.class);

        

        List<User> list = mapper.findUserByUserName("");

        

        System.out.println(list);

    }

    

    @Test

    public void testInsertUser() throws Exception{

        SqlSession openSession = factory.openSession();

        //經過getMapper方法來實例化接口

        UserMapper mapper = openSession.getMapper(UserMapper.class);

        

        User user = new User();

        user.setUsername("老王");

        user.setSex("1");

        user.setBirthday(new Date());

        user.setAddress("北京昌平");

        

        mapper.insertUser(user);

        

        openSession.commit();

    }

}

小結:

  • selectOne和selectList

動態代理對象調用sqlSession.selectOne()和sqlSession.selectList()是根據mapper接口方法的返回值決定,若是返回list則調用selectList方法,若是返回單個對象則調用selectOne方法。

  • namespace

mybatis官方推薦使用mapper代理方法開發mapper接口,程序員不用編寫mapper接口實現類,使用mapper代理方法時,輸入參數可使用pojo包裝對象或map對象,保證dao的通用性。

五. SqlMapConfig.xml配置文件

配置內容

SqlMapConfig.xml中配置的內容和順序以下:

 

properties(屬性)

settings(全局配置參數)

typeAliases(類型別名)

typeHandlers(類型處理器)

objectFactory(對象工廠)

plugins(插件)

environments(環境集合屬性對象)

environment(環境子屬性對象)

transactionManager(事務管理)

dataSource(數據源)

mappers(映射器)

 

  • 1.properties(屬性)

SqlMapConfig.xml能夠引用java屬性文件中的配置信息以下:

 

在classpath下定義db.properties文件,

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8

jdbc.username=root

jdbc.password=root

 

 

SqlMapConfig.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>

    <properties resource="db.properties"></properties>

    

    <typeAliases>

        <!-- 定義單個pojo類別名

        type:類的全路勁名稱

        alias:別名

         -->

        <!--<typeAlias type="cn.itheima.pojo.User" alias="user"/> -->

        

        <!-- 使用包掃描的方式批量定義別名

        定之後別名等於類名,不區分大小寫,可是建議按照java命名規則來,首字母小寫,之後每一個單詞的首字母大寫

        -->

        <package name="cn.itheima.pojo"/>

    </typeAliases>

 

    <!-- spring整合後 environments配置將廢除-->

    <environments default="development">

        <environment id="development">

        <!-- 使用jdbc事務管理-->

        <transactionManager type="JDBC" />

        <!-- 數據庫鏈接池-->

        <dataSource type="POOLED">

            <property name="driver" value="${jdbc.driver}" />

            <property name="url" value="${jdbc.url}" />

            <property name="username" value="${jdbc.username}" />

            <property name="password" value="${jdbc.password}" />

        </dataSource>

        </environment>

    </environments>

    

    <mappers>

        <mapper resource="User.xml"/>

        

        <!--

        使用class屬性引入接口的全路徑名稱:

        使用規則:

            1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

            2. 接口和映射文件要放在同一個目錄下

         -->

        <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->

        

        <!-- 使用包掃描的方式批量引入Mapper接口

                使用規則:

                1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

                2. 接口和映射文件要放在同一個目錄下

        -->

        <package name="cn.itheima.mapper"/>

    </mappers>

</configuration>

 

注意: MyBatis 將按照下面的順序來加載屬性:

properties 元素體內定義的屬性首先被讀取。

而後會讀取properties 元素中resource或 url 加載的屬性,它會覆蓋已讀取的同名屬性。

  • 2.typeAliases(類型別名)

mybatis支持別名:

別名

映射的類型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

map

Map

 

自定義別名:

在SqlMapConfig.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>

    <properties resource="db.properties"></properties>

    

    <typeAliases>

        <!-- 定義單個pojo類別名

        type:類的全路勁名稱

        alias:別名

         -->

        <!--<typeAlias type="cn.itheima.pojo.User" alias="user"/> -->

        

        <!-- 使用包掃描的方式批量定義別名

        之後別名等於類名,不區分大小寫,可是建議按照java命名規則來,首字母小寫,之後每一個單詞的首字母大寫

        -->

        <package name="cn.itheima.pojo"/>

    </typeAliases>

 

    <!-- spring整合後 environments配置將廢除-->

    <environments default="development">

        <environment id="development">

        <!-- 使用jdbc事務管理-->

        <transactionManager type="JDBC" />

        <!-- 數據庫鏈接池-->

        <dataSource type="POOLED">

            <property name="driver" value="${jdbc.driver}" />

            <property name="url" value="${jdbc.url}" />

            <property name="username" value="${jdbc.username}" />

            <property name="password" value="${jdbc.password}" />

        </dataSource>

        </environment>

    </environments>

    

    <mappers>

        <mapper resource="User.xml"/>

        

        <!--

        使用class屬性引入接口的全路徑名稱:

        使用規則:

            1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

            2. 接口和映射文件要放在同一個目錄下

         -->

        <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->

        

        <!-- 使用包掃描的方式批量引入Mapper接口

                使用規則:

                1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

                2. 接口和映射文件要放在同一個目錄下

        -->

        <package name="cn.itheima.mapper"/>

    </mappers>

</configuration>

這樣批量定義後,在UserMapper.xml中可直接寫類名了,如:

<select id="findUserByUserName" parameterType="java.lang.String" resultType="user">

        select * from user where username like '%${value}%'

</select>

  • 3.mappers(映射器,將UserMapper.xml或UserMapper.java載入SqlMapConfig.xml中)

Mapper配置的幾種方法:

<mapper resource="" />

使用相對於類路徑的資源

如:<mapper resource="sqlmap/User.xml" />

 

<mapper class="" />

使用mapper接口類路徑

如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

 

注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。

 

<package name=""/>

註冊指定包下的全部mapper接口

如:<package name="cn.itcast.mybatis.mapper"/>

注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中。

SqlMapConfig.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>

    <properties resource="db.properties"></properties>

    

    <typeAliases>

        <!-- 定義單個pojo類別名

        type:類的全路勁名稱

        alias:別名

         -->

        <!--<typeAlias type="cn.itheima.pojo.User" alias="user"/> -->

        

        <!-- 使用包掃描的方式批量定義別名

        定之後別名等於類名,不區分大小寫,可是建議按照java命名規則來,首字母小寫,之後每一個單詞的首字母大寫

        -->

        <package name="cn.itheima.pojo"/>

    </typeAliases>

 

    <!-- spring整合後 environments配置將廢除-->

    <environments default="development">

        <environment id="development">

        <!-- 使用jdbc事務管理-->

        <transactionManager type="JDBC" />

        <!-- 數據庫鏈接池-->

        <dataSource type="POOLED">

            <property name="driver" value="${jdbc.driver}" />

            <property name="url" value="${jdbc.url}" />

            <property name="username" value="${jdbc.username}" />

            <property name="password" value="${jdbc.password}" />

        </dataSource>

        </environment>

    </environments>

    

    <mappers>

        <mapper resource="User.xml"/>

        

        <!--

        使用class屬性引入接口的全路徑名稱:

        使用規則:

            1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

            2. 接口和映射文件要放在同一個目錄下

         -->

        <!--<mapper class="cn.itheima.mapper.UserMapper"/>-->

        

        <!-- 使用包掃描的方式批量引入Mapper接口

                使用規則:

                1. 接口的名稱和映射文件名稱除擴展名外要徹底相同

                2. 接口和映射文件要放在同一個目錄下

        -->

        <package name="cn.itheima.mapper"/>

    </mappers>

</configuration>

 

  • 總結:

pojo: 不按mvc分層,只是java bean有一些屬性,還有get set方法

domain: 不按mvc分層,只是java bean有一些屬性,還有get set方法

po: 用在持久層,還能夠再增長或者修改的時候,從頁面直接傳入action中,它裏面的java bean 類名等於表名,

    屬性名等於表的字段名,還有對應的get set方法

vo: view object表現層對象,主要用於在高級查詢中從頁面接收傳過來的各類參數.好處是擴展性強

bo: 用在servie層,如今企業基本不用.

這些po,vo, bo,pojo能夠用在各類層面嗎?

能夠,也就是po用在表現層,vo用在持久層不報錯,由於都是普通的java bean沒有語法錯誤.

可是在企業最好不要混着用,由於這些都是設計的原則,混着用比較亂.不利於代碼維護.

 

自學方法論: 理論 -> 實踐 -> 理論 -> 實踐 反覆迭代三遍

 

1. mybatis是一個持久層框架, 做用是跟數據庫交互完成增刪改查

2.原生Dao實現(須要接口和實現類)

4.動態代理方式(只須要接口)

    mapper接口代理實現編寫規則:

    1) 映射文件中namespace要等於接口的全路徑名稱

    2) 映射文件中sql語句id要等於接口的方法名稱

    3) 映射文件中傳入參數類型要等於接口方法的傳入參數類型

    4) 映射文件中返回結果集類型要等於接口方法的返回值類型

 

5. #{}佔位符:佔位

    若是傳入的是基本類型,那麼#{}中的變量名稱能夠隨意寫

    若是傳入的參數是pojo類型,那麼#{}中的變量名稱必須是pojo中的屬性.屬性.屬性...

 

6. ${}拼接符:字符串原樣拼接

    若是傳入的是基本類型,那麼${}中的變量名必須是value

    若是傳入的參數是pojo類型,那麼${}中的變量名稱必須是pojo中的屬性.屬性.屬性...

    注意:使用拼接符有可能形成sql注入,在頁面輸入的時候能夠加入校驗,不可輸入sql關鍵字,不可輸入空格

7. 映射文件:

    1)傳入參數類型經過parameterType屬性指定

    2)返回結果集類型經過resultType屬性指定

8. hibernate和mybatis區別:

    hibernate:它是一個標準的orm框架,比較重量級,學習成本高.

        優勢:高度封裝,使用起來不用寫sql,開發的時候,會減低開發週期.

        缺點:sql語句沒法優化

        應用場景:oa(辦公自動化系統), erp(企業的流程系統)等,還有一些政府項目,

            總的來講是在用戶量不大,併發量小的時候使用.

    mybatis:它不是一個orm框架, 它是對jdbc的輕量級封裝, 學習成本低,比較簡單

        有點:學習成本低, sql語句能夠優化, 執行效率高,速度快

        缺點:編碼量較大,會拖慢開發週期

        應用場景: 互聯網項目,好比電商,P2p等

         總的來講是在用戶量較大,併發高的時候使用.

相關文章
相關標籤/搜索