• 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(DAOs)。
      MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
                                                                                          ---------------百度百科

    二、Mybatis与Hibernate区别

      两个都是持久层框架,操作数据库,但是两者还是有区别的 

      hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
      优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.
      缺点:sql语句无法优化
      应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
      总的来说,在用于量不大,并发量小的时候使用.
      mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
      优点:学习成本低, sql语句可以优化, 执行效率高,速度快
      缺点:编码量较大,会拖慢开发周期
      应用场景: 互联网项目,比如电商,P2p等
      总的来说是用户量较大,并发高的项目。

    三、体验原始的jdbc开发

      1、导入jar包

       此时操作数据库,需要引入数据库驱动,这里我使用的是mysql驱动

      

      2、编写jdbc程序

      

    public static void main(String[] args) {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            
            try {
                //加载数据库驱动
                Class.forName("com.mysql.jdbc.Driver");
                
                //通过驱动管理类获取数据库链接
                connection =  DriverManager.getConnection("jdbc:mysql://192.168.174.130:3306/SSM", "root", "root");
                //定义sql语句 ?表示占位符
            String sql = "select * from myUser 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();
                    }
                }
    
            }
    
        }

      缺点:频繁创建释放资源降低性能;代码耦合性强,不易维护;传参与所获结果集编码不够灵活(存在硬编码)

      综上:mybatis解决了以上问题

      1、SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接,大大减少了不断创建释放资源。

      2、Sql语句配置在XXXXmapper.xml文件中与java代码分离。

      3、Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。解决了条件查询中笨重问题

    四、快速部署环境

      1、下载jar包

      mybatis官网:   http://www.mybatis.org/mybatis-3/

      jar包下载地址:  https://github.com/mybatis/mybatis-3/releases

      2、新建工程,导入相关jar包

      

      3、在工程(不是src)下建立一个源码包,用于存放配置文件

      4、在源码中配置一个日志文件,用于打印日志

    # 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

      5、配置核心配置文件

      配置文件中主要是配置连接数据库和事务管理的内容,文件名可以自定义,默认SqlMapConfig.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration 
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 和spring整合后 environments配置将废除-->
        <environments default="development">
            <environment id="development">
            <!-- 使用jdbc事务管理-->
                <transactionManager type="JDBC" />
            <!-- 数据库连接池-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSM" />
                    <!--注意:这里必须是username,一定要规范-->
                    <property name="username" value="root" /> 
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
    </configuration>

      6、配置sql映射文件,文件名自定义,这里默认为User.xml,

      与hibernate想区别的是:hibernate是通过操作映射文件对象来操作数据库,与sql无太大关系;mybatis的映射文件是用来写sql语句的

      注意:此文件放在源码包下

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!-- namespace命名空间,做sql隔离,防止命名重复 -->
    <mapper namespace="test">
       
    </mapper>

      7、在核心配置文件中引入映射文件

    <mappers>
      <mapper resource="User.xml"/> </mappers>

      此时环境差不多就部署好了

    五、需求开发

      1、根据id查询一个客户

      1)建立客户表

      2)定义pojo类

    package com.clj.pojo;
    
    import java.util.Date;
    import java.util.List;
    
    public class User {
        private int id;
        private String username;// 用户姓名
        private String sex;// 性别
        private Date birthday;// 生日
        private String address;// 地址
        private List<Orders> ordersList;
        
        public List<Orders> getOrdersList() {
            return ordersList;
        }
        public void setOrdersList(List<Orders> ordersList) {
            this.ordersList = ordersList;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public Date getBirthday() {
            return birthday;
        }
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", sex=" + sex
                    + ", birthday=" + birthday + ", address=" + address + "]";
        }
        
    }

      3)在User.xml文件中配置sql语句

      注意:当传入参数类型时原始型时,占位符中的括号中的值可以随意设置,但最好可读性较强(占位符能自动进行java类型和jdbc类型转换,可以有效防止sql注入。

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!-- namespace命名空间,做sql隔离 -->
    <mapper namespace="test">
        <!-- 
            id:sql语句唯一标识
            parameterType:指定传入参数类型(对应javaBean类型,写原始型会自动包装为包装类)
            resultType:返回结果类型
            #{}:占位符号,起到占位作用,如果传入的是原始型,那么括号中的变量名称可以随意定义
         -->
        <select id="findUserById" parameterType="int" resultType="com.clj.pojo.User">
            select * from user where id=#{id}
        </select>
    </mapper>

      3)测试

      值得注意的是,这里调用sql的写法

      @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+‘.’+SqlID
            //第二个参数:传入的参数
            User user=openSession.selectOne("test.findUserById",1);
            System.out.println(user);
            openSession.close();
        }

      这里调用的是selectOne方法,旨在查询一条指定的数据,如果用它查询多条数据,会报异常(查询多条要用selectList)

      

      2、根据用户名查询客户

      1)在User.xml文件中配置sql语句

      注意:当传入的参数是非引用型时,拼接符要用"value"(拼接符不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value)

         这里返回值为List集合,配置为该集合的泛型

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!-- namespace命名空间,做sql隔离 -->
    <mapper namespace="test">
        <!-- 如果返回结果为集合,可以调用selectList方法。这个方法返回结果就有个集合 ,
        所以映射文件应该配置成集合的泛型
        ${}拼接符:字符串原样拼接,如果传入的参数是基本类型,括号中的值必须为“value”
        注意:拼接符有sql注入的风险,所以慎用(=号用占位符,like用拼接符)-->
        <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.clj.pojo.User">
            <!--select * from user where username like #{name}  -->
            select * from user where username like '%${value}%'
        </select>
    </mapper>

      2)测试

      @Test
        public void testFindUSerByUserName() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
            //List<User> list=openSession.selectList("test.findUserByUserName","%王%");
            List<User> list=openSession.selectList("test.findUserByUserName","王");
            System.out.println(list);
            openSession.close();
        }

      3、插入数据

      1)配置sql

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!-- namespace命名空间,做sql隔离 -->
    <mapper namespace="test">
        <!-- 
            #{}:如果传入的是pojo类型,那么#{}中变量的名称必须是pojo中对应的属性
            如果要返回数据库自增主键,可以使用select LAST_INSERT_ID()
         -->
        <insert id="insertUser" parameterType="com.clj.pojo.User">
        <!-- 执行 LAST_INSERT_ID,返回自增的主键
            keyProperty:将返回的主键放入传入参数的ID中保存
            order:相当于insert语句的执行顺序,在insert前执行时before,之后是after
            resultType:keyProperty中属性的类型,
            -->
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                select LAST_INSERT_ID()
            </selectKey>
            insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
        </insert>
    </mapper>

      注意:这里添加selectKey实现将主键返回,因为是先插入数据,才能获得主键,所以其属性值order="AFTER"

      如果是uuid(随机字符串),属性值order="Before"

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

      2) 测试

      @Test
        public void testInsertUser() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
            User user=new User();
            user.setUsername("赵四");
            user.setBirthday(new Date());
            user.setSex("1");
            user.setAddress("长沙市");
            System.out.println("======"+user.getId());
            openSession.insert("test.insertUser",user);
            //提交事务(mybatis会自动提交事务,但是不知道何时手动提交事务)
            openSession.commit();
            System.out.println("========"+user.getId());
            openSession.close();
        }

      4、删除更新数据

      1)配置sql语句

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!-- namespace命名空间,做sql隔离 -->
    <mapper namespace="test">
        <delete id="delUserById" parameterType="int">
            delete from user where id=#{id}
        </delete>
        <update id="updateUserById" parameterType="com.clj.pojo.User">
            update user set username=#{username} where id=#{id}
        </update>
    </mapper>

      2)测试

    @Test
        public void testDelUserById() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
            openSession.delete("test.delUserById",29);
            openSession.commit();
            openSession.close();
        }
        @Test
        public void testUpdateUserById()throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
            User user=new User();
            user.setId(28);
            user.setUsername("佳先森");
            openSession.update("test.updateUserById",user);
            openSession.commit();
            openSession.close();
        }

       扩展:将连接数据库中的属性封装到数据库配置文件中

      1、在源码包中配置db.properties

    jdbc.driver=com.mysql.jdbc.Driver	
    jdbc.url=jdbc:mysql://192.168.174.130:3306/SSM
    jdbc.username=root
    jdbc.password=root

      2、修改核心配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration 
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 引入链接数据库配置文件 -->
        <properties resource="db.properties"/>
        <!-- 和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}" />
                    <!--注意:这里必须是username,一定要规范-->
                    <property name="username" value="${jdbc.username}" /> 
                    <property name="password" value="${jdbc.password}" />
                </dataSource>
            </environment>
        </environments>
        <mappers><mapper resource="User.xml"/>
        </mappers>
    </configuration>

    六、mybatis支持别名

      在核心配置文件中第一个类的别名,后面可以直接引用别名,无需配置全路径

    <typeAliases>
        <!-- 定义单个pojo类别名
            type:类的全路径名称
            alias:别名
         -->
            <typeAlias type="com.clj.pojo.User" alias="user"/>
        <!-- 使用包扫描的方式批量定义别名,定义后别名等于类名
        ,不区分大小写 ,但最好按照驼峰命名法书写-->
        <package name="com.clj.pojo"/>
        </typeAliases>

    七、mybatis引入映射文件写法

      有两种写法:一种是单个引入,另一种是包扫描的方式

        <mappers>
            <!-- 两种引入方式 
            方式一:单个引入
            
            <mapper resource="User.xml"/>-->
            <!-- 使用class属性引入接口的全路径名称:
                使用规则:1.接口名称和映射文件名称除扩展名之外要完全相同
                        2.接口和映射文件要放在同一个目录下
             
            <mapper class="com.clj.UserMapper.UserMapper"/>-->
            <!-- 方式二:使用包扫描的方式批量引入Mapper
            使用包扫描规则和上个一样
             -->
             <package name="com.clj.UserMapper"/>
        </mappers>

    八、MyBatis之Dao层的开发方式

      MyBatis之Dao层的开发方式有两种:原始Dao开发和Mapper接口开发

      1、Dao开发方式一:原始Dao开发

        1)配置user.xml中的sql语句

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!-- namespace命名空间,做sql隔离 -->
    <mapper namespace="test">
      <select id="findUserById" parameterType="int" resultType="com.clj.pojo.User">
            select * from user where id=#{id}
        </select>
      <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.clj.pojo.User">

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

    </mapper>

        2)定义接口和实现类

    package com.clj.dao;
    
    import java.util.List;
    
    import com.clj.pojo.User;
    
    public interface UserDao {
        public User findUserById(Integer id);
        public List<User> findUserByUserName(String username);
    }
    package com.clj.dao;
    
    import java.util.List;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    
    import com.clj.pojo.User;
    
    public class UserDaoImpl implements UserDao{
        private SqlSessionFactory sqlSessionFactory;
        //通过构造方法注入
        public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
            super();
            this.sqlSessionFactory = sqlSessionFactory;
        }
        @Override
        public User findUserById(Integer id) {
            //SqlSession是线程不安全的,所以他的最佳使用的范围在方法体内
            SqlSession opeanSession=sqlSessionFactory.openSession();
            User user=opeanSession.selectOne("test.findUserById",id);
            return user;
        }
        @Override
        public List<User> findUserByUserName(String username) {
            SqlSession opeanSession=sqlSessionFactory.openSession();
            List<User> list=opeanSession.selectList("test.findUserByUserName",username);
            return list;
        }
        
    }

      3)在核心配置文件SqlMapConfig.xml中引入user.xml

        <mappers>
        <mapper resource="User.xml"/> </mappers>

      4)定义测试类进行测试

    package com.clj.Test;
    
    import java.io.InputStream;
    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 com.clj.dao.UserDao;
    import com.clj.dao.UserDaoImpl;
    import com.clj.pojo.User;
    
    public class UserDaoTest {
        private SqlSessionFactory factory;
        
        //@Before作用在测试方法之前执行这个方法
        @Before
        public void setUp() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
        }
        @Test
        public void testFindUserById() throws Exception{
            //将初始化的工厂注入到实现类中
            UserDao userDao=new UserDaoImpl(factory);
            User user=userDao.findUserById(1);
            System.out.println(user);
        }
        @Test
        public void testFindUserByUserName() throws Exception{
            UserDao userDao=new UserDaoImpl(factory);
            List<User> list=userDao.findUserByUserName("王");
            System.out.println(list);
        }
    }    

      总结:原始Dao还是存在一些不好的因素:1.代码有重复 2.sqlSession调用sql时需要指定id值,存在硬编码

      2、Dao开发方式二:Mapper动态代理的方式

      Mapper动态代理的方式需要严格遵守一些规范

      需求一:通过主键查找用户;通过用户名查找用户;插入用户数据

      1)定义接口

    package com.clj.UserMapper;
    
    import java.util.List;
    
    import com.clj.pojo.CustomerOrders;
    import com.clj.pojo.Orders;
    import com.clj.pojo.QueryVo;
    import com.clj.pojo.User;
    
    //与之关乎的配置文件要在同一个目录包下
    public interface UserMapper {
        public User findUserById(Integer id);
        //注意:这里是模糊查询,配置文件虽然写的是User,实际返回的是List集合
        //动态代理形式中,如果返回结果集List,那么mybatis会在生成实现类的时候会自动调用selectList方法
        public List<User> findUserByUserName(String userName);
        public  void insertUser(User user);
        
    }

      2)定义其映射文件,最好是在同目录下

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!--mapper接口代理实现编写轨则
        1.映射文件中namespace要等于接口的全路径名
        2.映射文件中sql语句id要等于接口的方法名称
        3.映射文件中传入参数类型要等于接口方法的传入参数类型
        4.映射文件中返回结果集类型等于接口方法的返回值类型
     -->
    <mapper namespace="com.clj.UserMapper.UserMapper">
        <select id="findUserById" parameterType="int" resultType="com.clj.pojo.User">
            select * from user where id=#{id}
        </select>
        <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.clj.pojo.User">
            <!--select * from user where username like #{name}  -->
            select * from user where username like '%${value}%'
        </select>
        <!-- 这里返回值使用的别名 -->
        <insert id="insertUser" parameterType="user">
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                select LAST_INSERT_ID()
            </selectKey>
            insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
        </insert>
    </mapper>

       两文件的目录关系

       

      3)在核心配置文件中引入Mapper的配置文件

    <mappers>
            <!-- 两种引入方式 
            方式一:单个引入
            
            <mapper resource="User.xml"/>-->
            <!-- 方式二:使用包扫描的方式批量引入Mapper
            使用包扫描规则和上个一样
             -->
             <package name="com.clj.UserMapper"/>
        </mappers>

      ·4)测试类

      

    package com.clj.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    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 com.clj.UserMapper.UserMapper;
    import com.clj.pojo.CustomerOrders;
    import com.clj.pojo.Orders;
    import com.clj.pojo.QueryVo;
    import com.clj.pojo.User;
    
    public class UserMapperTest {
    private static SqlSessionFactory factory;
        
        //@Before作用在测试方法之前执行这个方法
        @Before
        public void setUp() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
        }
        @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);
        }
     
    }

       另外:删除用户和更新用户sql配置文件方式为,具体步骤如上

        <delete id="delUserById" parameterType="int">
            delete from user where id=#{id}
        </delete>
        <update id="updateUserById" parameterType="com.clj.pojo.User">
            update user set username=#{username} where id=#{id}
        </update>

      需求二:根据用户名查询,利用高级查询Vo类

      1)创建Vo类封装用户属性,并提供set/get方法

    package com.clj.pojo;
    
    import java.util.List;
    
    //用于高级查询
    public class QueryVo {
        private User user;
        private List<Integer> ids;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        public List<Integer> getIds() {
            return ids;
        }
    
        public void setIds(List<Integer> ids) {
            this.ids = ids;
        } 
    }

      2)在UserMapper.xml文件中配置查询语句

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!--mapper接口代理实现编写轨则
        1.映射文件中namespace要等于接口的全路径名
        2.映射文件中sql语句id要等于接口的方法名称
        3.映射文件中传入参数类型要等于接口方法的传入参数类型
        4.映射文件中返回结果集类型等于接口方法的返回值类型
     -->
    <mapper namespace="com.clj.UserMapper.UserMapper">
        <select id="findUserbyVo" parameterType="com.clj.pojo.QueryVo" resultType="com.clj.pojo.User">
            select * from user where username like '%${user.username}%' and sex=#{user.sex}
        </select>
    </mapper>

      3)定义接口

    public List<User> findUserbyVo(QueryVo vo);

      4)测试类

    public class UserMapperTest {
    private static SqlSessionFactory factory;
        
        //@Before作用在测试方法之前执行这个方法
        @Before
        public void setUp() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
        }
      @Test
        public void testFindUserByVo() throws Exception{
            SqlSession openSession=factory.openSession();
            //通过getMapper方法实列化接口
            UserMapper mapper=openSession.getMapper(UserMapper.class);
            QueryVo vo=new QueryVo();
            User user=new User();
            user.setUsername("张");
            user.setSex("1");
    vo.setUser(user); List
    <User> list=mapper.findUserbyVo(vo); System.out.println(list); openSession.close(); } }

      需求三:查询数据总数,利用count(*)

      1) 配置sql

    <!-- 只有返回结果为一行一列的时候,那么返回值类型时可以指定类型为基本类型 -->
        <select id="findUserCount" resultType="int">
            select count(*) from user
        </select>

      2) 配置接口

        public Integer findUserCount();

      3)测试

    @Test
        public void testFindUserCount()throws Exception{
            SqlSession opneSession=factory.openSession();
            //通过getMapper方法实例化接口
            UserMapper mapper=opneSession.getMapper(UserMapper.class);
            Integer count=mapper.findUserCount();
            System.out.println("===="+count);
        }

      需求四:动态增加查询条件

      1)配置sql

      方式一:局部配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!--mapper接口代理实现编写轨则
        1.映射文件中namespace要等于接口的全路径名
        2.映射文件中sql语句id要等于接口的方法名称
        3.映射文件中传入参数类型要等于接口方法的传入参数类型
        4.映射文件中返回结果集类型等于接口方法的返回值类型
     -->
    <mapper namespace="com.clj.UserMapper.UserMapper">
    <select id="findUserByUserNameAndSex" parameterType="com.clj.pojo.User" resultType="com.clj.pojo.User">
            select * from  user
            <!-- where标签作用:
                会自动向sql语句中添加where关键字
                会去掉第一个条件的and关键字 -->
            <where>
            <if test="username!=null and username !=''">
                and username like '%${username}%'
            </if>
            <if test="sex !=null and sex!=''">
                and sex=#{sex}
            </if>
            </where>
        </select>
    </mapper>

      方式二:全局配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!--mapper接口代理实现编写轨则
        1.映射文件中namespace要等于接口的全路径名
        2.映射文件中sql语句id要等于接口的方法名称
        3.映射文件中传入参数类型要等于接口方法的传入参数类型
        4.映射文件中返回结果集类型等于接口方法的返回值类型
     -->
    <mapper namespace="com.clj.UserMapper.UserMapper">
        <!-- 封装sql条件,封装后可以重用 
            id:此sql的唯一标识符
        -->
        <sql id="user_where">
            <where>
            <if test="username!=null and username !=''">
                and username like '%${username}%'
            </if>
            <if test="sex !=null and sex!=''">
                and sex=#{sex}
            </if>
            </where>
            
        </sql>    
    <select id="findUserByUserNameAndSex" parameterType="com.clj.pojo.User" resultType="com.clj.pojo.User">
            select * from  user
            <!-- where标签作用:
                会自动向sql语句中添加where关键字
                会去掉第一个条件的and关键字 
            <where>
            <if test="username!=null and username !=''">
                and username like '%${username}%'
            </if>
            <if test="sex !=null and sex!=''">
                and sex=#{sex}
            </if>
            </where>-->
            <!-- 调用全局条件 -->
            <include refid="user_where"/>
        </select>
    </mapper>

      2)接口

    public List<User> findUserByUserNameAndSex(User user);

      3)测试

    @Test
        public void testFindUserbyUserNameAndSex() throws Exception{
            SqlSession opneSession=factory.openSession();
            UserMapper mapper=opneSession.getMapper(UserMapper.class);
            User user=new User();
            user.setUsername("张");
            user.setSex("1");
            List<User> list=mapper.findUserByUserNameAndSex(user);
            System.out.println(list);
        }

      需求五:查询主键在某个范围内(动态添加条件查询之foreach标签)

      1)sql配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!--mapper接口代理实现编写轨则
        1.映射文件中namespace要等于接口的全路径名
        2.映射文件中sql语句id要等于接口的方法名称
        3.映射文件中传入参数类型要等于接口方法的传入参数类型
        4.映射文件中返回结果集类型等于接口方法的返回值类型
     -->
    <mapper namespace="com.clj.UserMapper.UserMapper">
    <select id="findUserByIds" parameterType="com.clj.pojo.QueryVo" resultType="com.clj.pojo.User">
            <!-- select * from user where id in (1,16,28,22) -->
                select * from user
            <where>
                <!-- 这里的id指定是vo中的集合属性 -->
                <if test="ids!=null">
                    <!-- foreach:循环传入的集合参数
                        collection:传入的集合的变量名称
                        item:每次循环将循环的数据放入这个变量中
                        open:循环开始拼接的字符串
                        close:循环结束拼接的字符串
                        separator:循环中拼接的分隔符
                     -->
                    <foreach collection="ids" item="id" open="id in (" close=")" separator=",">
                        #{id}
                    </foreach>
                </if>
            </where>
        </select>
    </mapper>

      2)接口

        public List<User> findUserByIds(QueryVo vo);

      3)测试

    public class UserMapperTest {
    private static SqlSessionFactory factory;
        
        //@Before作用在测试方法之前执行这个方法
        @Before
        public void setUp() throws Exception{
            String resource="SqlMapConfig.xml";
            InputStream inputstream=Resources.getResourceAsStream(resource);
            factory=new SqlSessionFactoryBuilder().build(inputstream);
            SqlSession openSession=factory.openSession();
        }
    @Test
        public void testFindUserbyIds() throws Exception{
            SqlSession opneSession=factory.openSession();
            UserMapper mapper=opneSession.getMapper(UserMapper.class);
            QueryVo vo=new QueryVo();
            List<Integer> ids=new ArrayList<Integer>();
            ids.add(1);
            ids.add(16);
            ids.add(28);
            ids.add(22);
            List<User> list=mapper.findUserByIds(vo);System.out.println(list);
        }
    }

      需求六:关联查询之一对一查询

      环境:一个客户对应多个订单,而一个订单对应一个客户

      方法一:使用resultType,定义订单信息po类,此po类中包括了订单信息和用户信息

      1)预测sql语句写法:SELECT orders.*,user.username,userss.address FROM orders,user WHERE orders.user_id = user.id

      2)定义订单类

    package com.clj.pojo;
    
    import java.util.Date;
    
    public class Orders {
         private Integer id;
    
            private Integer userId;
    
            private String number;
    
            private Date createtime;
    
            private String note;        public Integer getId() {
                return id;
            }
    
            public void setId(Integer id) {
                this.id = id;
            }
    
            public Integer getUserId() {
                return userId;
            }
    
            public void setUserId(Integer userId) {
                this.userId = userId;
            }
    
            public String getNumber() {
                return number;
            }
    
            public void setNumber(String number) {
                this.number = number == null ? null : number.trim();
            }
    
            public Date getCreatetime() {
                return createtime;
            }
    
            public void setCreatetime(Date createtime) {
                this.createtime = createtime;
            }
    
            public String getNote() {
                return note;
            }
    
            public void setNote(String note) {
                this.note = note == null ? null : note.trim();
            }
    }

      3)定义封装客户和订单的pojo类,此类包含上边预测的sql语句字段

    package com.clj.pojo;
    
    import java.util.Date;
    
    //一对一:select a.*,b.id uid,username,birthday,sex,address
    //from order a,user b
    //where a.user_id=b.id
    //注意:不能用实体User代替他属性
    //缺点:java是单继承
    public class CustomerOrders extends Orders{
        private int uid;
        private String username;// 用户姓名
        private String sex;// 性别
        private Date birthday;// 生日
        private String address;// 地址
        public int getUid() {
            return uid;
        }
        public void setUid(int uid) {
            this.uid = uid;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public Date getBirthday() {
            return birthday;
        }
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        
    }

        注意:OrdersCustom类继承Orders类后OrdersCustom类包括了Orders类的所有字段,只需要定义用户的信息字段即可。(注意:这里不能用user来取代这些属性)

      4)配置sql语句

      1)在order类中定义user属性

    package com.clj.pojo;
    
    import java.util.Date;
    
    public class Orders {
         private Integer id;
    
            private Integer userId;
    
            private String number;
    
            private Date createtime;
    
            private String note;
            
            private User user;
            
            public User getUser() {
                return user;
            }
    
            public void setUser(User user) {
                this.user = user;
            }
    
            public Integer getId() {
                return id;
            }
    
            public void setId(Integer id) {
                this.id = id;
            }
    
            public Integer getUserId() {
                return userId;
            }
    
            public void setUserId(Integer userId) {
                this.userId = userId;
            }
    
            public String getNumber() {
                return number;
            }
    
            public void setNumber(String number) {
                this.number = number == null ? null : number.trim();
            }
    
            public Date getCreatetime() {
                return createtime;
            }
    
            public void setCreatetime(Date createtime) {
                this.createtime = createtime;
            }
    
            public String getNote() {
                return note;
            }
    
            public void setNote(String note) {
                this.note = note == null ? null : note.trim();
            }
    }

      2)配置sql语句

      <!-- 关于一对一查询 -->
        <!-- 方式一:自动映射 :利用类中的属性对应表中的字段
        需要提供封装user和order属性的类-->
        <select id="findOrderAndUser1" resultType="com.clj.pojo.CustomerOrders">
            select a.*,b.id uid,username,birthday,sex,address
            from orders a,user b
            where a.user_id=b.id
        </select>

      5)配置接口

        public List<CustomerOrders> findOrderAndUser1();

      6)定义测试类

    @Test
        public void testFindORdersAndUser() throws Exception{
            SqlSession opneSession=factory.openSession();
            UserMapper mapper=opneSession.getMapper(UserMapper.class);
            List<CustomerOrders> list=mapper.findOrderAndUser1();
            System.out.println(list);
        }

      总结:此方法虽然简单,定义专门的pojo类作为输出类型,其中定义了sql查询结果集所有的字段。但是缺点是pojo类只能单继承

      方式二:使用resultMap,定义专门的resultMap用于映射一对一查询结果

      1)配置sql    注意此时不需要CustomerOrders 类

    <!-- 一对一:手动映射:需要在order类中封装User这个属性 -->
        <!--
            id:resultMap的唯一标识
            type:将查询出的数据放入指定的对象中
            注意:手动映射需要指定数据表中的字段名与java中pojo类中的属性名称对应的关系
          -->
        <resultMap type="com.clj.pojo.Orders" id="orderAndUserResultMap">
            <!--id标签指定主键字段对应关系
                column:列,数据库中的字段名称
                property:属性,java中pojo中的属性名称
              -->
            <id column="id" property="id"/>
            <!-- result:指定 非主键对应的关系-->
            <result column="user_id" property="userId"/>
            <result column="number" property="number"/>
            <result column="createtime" property="createtime"/>
            <result column="note" property="note"/>
            <!-- association:表示进行关联查询单条记录
           这个标签指定单个对象的对应关系 property:表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中 javaType:user属性中类型的路径 -->
    <association property="user" javaType="com.clj.pojo.User">
           <!--查询结果的user_id列对应关联对象的id属性,这里是<id />表示user_id是关联查询对象的唯一标识--> <id column="uid" property="id"/>
           <!--查询结果的username列对应关联对象的username属性--> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <result column="address" property="address"/> </association> </resultMap> <select id="findOrderAndUser2" resultMap="orderAndUserResultMap"> select a.*,b.id uid,username,birthday,sex,address from orders a,user b where a.user_id=b.id </select>

      2)配置接口

        public List<Orders> findOrderAndUser2();

      3)测试类

      @Test
        public void findOrderAndUser2() throws Exception{
            SqlSession opneSession=factory.openSession();
            UserMapper mapper=opneSession.getMapper(UserMapper.class);
            List<Orders> list=mapper.findOrderAndUser2();
            for(Orders order:list){
                System.out.println(order.getUserId()+"	"+order.getCreatetime());
            }
        }

      需求七:一对多查询

      1)预测sql语句

      SELECT u.*, o.id oid,o.number,o.createtime,o.note FROM `user` u LEFT JOIN orders o ON u.id = o.user_id

      2)在user pojo类中加上List集合属性

    package com.clj.pojo;
    
    import java.util.Date;
    import java.util.List;
    
    public class User {
        private int id;
        private String username;// 用户姓名
        private String sex;// 性别
        private Date birthday;// 生日
        private String address;// 地址
        private List<Orders> ordersList;
        
        public List<Orders> getOrdersList() {
            return ordersList;
        }
        public void setOrdersList(List<Orders> ordersList) {
            this.ordersList = ordersList;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public Date getBirthday() {
            return birthday;
        }
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", sex=" + sex
                    + ", birthday=" + birthday + ", address=" + address + "]";
        }
        
    }

      3)配置sql

      <!-- 一对多 -->
        <resultMap type="com.clj.pojo.User" id="userAndOrderMap">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
            <!-- 指定对应的集合对象关系映射 
            property:将数据放入User对象中的orderList属性中
            ofType:指定orderList属性泛型类型
            -->
            <collection property="ordersList" ofType="com.clj.pojo.Orders">
                <id column="oid" property="id"/>
                <result column="user_id" property="userId"/>
                <result column="number" property="number"/>
                <result column="createtime" property="createtime"/>
                <result column="note" property="note"/>
                <!-- 注意:这里不需要配置user属性,他是用于一对一时配置的属性,与这里无关 -->
            </collection>
        </resultMap>
        <select id="findUserAndOrders" resultMap="userAndOrderMap">
            select a.*,b.id oid,user_id,number,createtime
            from user a,order b where a.id=b.user_id
        </select>

      4)定义接口

        public List<User> findUserAndOrders();

      5)测试类

         @Test
            public void findUserAndOrders() throws Exception{
                SqlSession opneSession=factory.openSession();
                UserMapper mapper=opneSession.getMapper(UserMapper.class);
                List<User> list=mapper.findUserAndOrders();
                System.out.println(list);
            
        }

    九、Mybatis与Spring整合

      1、整合思路  

      SqlSessionFactory对象应该放到spring容器中作为单例存在。
      传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
      Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
      数据库的连接以及数据库连接池事务管理都交给spring容器来完成。

      2、环境部署

      1)导入所需jar包

       在导入spring包和mybaits包之外还要jar两者的整合包

      

         

             至于maven构建项目,其pom文件的约束为:
             注意:至于jdbc可以用c3p0,也可以用dbcp,但是无论这两个都需要用到spring-jdbc的jar包,否则会报错误

    Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
    PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:121)
        at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1570)
        ... 41 more
                <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.5</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.0.8</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>1.3.1</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aopalliance/com.springsource.org.aopalliance -->
            <dependency>
                <groupId>aopalliance</groupId>
                <artifactId>aopalliance</artifactId>
                <version>1.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.aspectj/org.aspectj.weaver -->
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.7.4</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>4.3.17.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>4.3.17.RELEASE</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.1.2</version>
            </dependency>

      2)在工程项目下(非src)创建一个源码包,用来存放配置文件

       配置连接数据库驱动配置文件db.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://192.168.174.130:3306/SSM
    jdbc.username=root
    jdbc.password=root

      1))配置日志配置文件log4j.properties

    ### direct log messages to stdout ###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.err
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

    ### direct messages to file mylog.log ###
    log4j.appender.file=org.apache.log4j.FileAppender
    log4j.appender.file.File=c:mylog.log
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

    ### set log levels - for more verbose logging change 'info' to 'debug' ###

    log4j.rootLogger=info, stdout

      配置spring的配置文件applicationContext.xml

      1)))配置数据库驱动,加载db.properties文件

        <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:db.properties" />
        <!-- 数据库连接池 -->

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
      <property name="driverClass" value="${jdbc.driver}"/>
      <property name="jdbcUrl" value="${jdbc.url}"/>
      <property name="user" value="${jdbc.password}"/>
      <property name="password" value="${jdbc.password}"/>
    </bean>

      2)))将sqlSessionfactory的创建交给spring管理

    <!-- 整合后会话工厂归spring来管理 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 指定mybatis核心配置文件 -->
            <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
            <!-- 指定会话工厂使用的数据源 -->
            <property name="dataSource" ref="dataSource"/>
        </bean>

      全部代码如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
        <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:db.properties" />
        <!-- 数据库连接池 -->

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
          <property name="driverClass" value="${jdbc.driver}"/>
          <property name="jdbcUrl" value="${jdbc.url}"/>
          <property name="user" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
        </bean>

        <!-- 整合后会话工厂归spring来管理 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 指定mybatis核心配置文件 -->
            <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
            <!-- 指定会话工厂使用的数据源 -->
            <property name="dataSource" ref="dataSource"/>
        </bean>
    </beans>

      其中org.mybatis.spring.SqlSessionFactoryBean的路径配置如下图

      

      2)) 配置mybatis数据sql映射文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration 
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.clj.pojo"/>
        </typeAliases>
     
        <mappers>
             <mapper resource="User.xml"/>
             <package name="com.clj.UserMapper"/>
        </mappers>
    </configuration>

      3、整合之Dao层的开发

       1)开发方式一之传统dao开发

        1))思路:

         想为接口+实现类来完成。需要dao实现类需要继承SqlsessionDaoSupport类

         2))接口定义和javaBean

         这里定义了根据id查询和根据用户名查询两个方法package com.clj.dao;

    import java.util.List;
    
    import com.clj.pojo.User;
    
    public interface UserDao {
        public User findUserById(Integer id);
        public List<User> findUserByUserName(String username);

        public List<UserBean> findUserByUserNameAndMoney(UserBean userBean);
        public List<UserBean> findUserById(QueryVo vo);

    
    }
    @Component
    public class UserBean {
        private Integer id;
        private String username;
        private String age;
        private Integer money;
            //set/get方法
        }
    @Component
    public class QueryVo {
        private List<Integer> ids;
    }

         3))实现类定义

         实现类实现SqlSessionDaoSupport

    package com.clj.dao;
    
    import java.util.List;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    
    import com.clj.pojo.User;
    //此时dao层要继承SqlSessionDaoSupport
    public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
        @Override
        public User findUserById(Integer id) {
            //SqlSession是线程不安全的,所以他的最佳使用的范围在方法体内
            SqlSession opeanSession=this.getSqlSession();
            User user=opeanSession.selectOne("test.findUserById",id);
            //opeanSession.close();
            return user;
            
        }
        @Override
        public List<User> findUserByUserName(String username) {
            SqlSession opeanSession=this.getSqlSession();
            List<User> list=opeanSession.selectList("test.findUserByUserName",username);
            return list;
        }

        public List<UserBean> findUserByUserNameAndMoney(UserBean userBean) {
          SqlSession sqlSession=this.getSqlSession();
          List<UserBean> user=sqlSession.selectList("test.findUserByUserNameAndMoney",userBean);
          return user;
        }

    
    

        @Override
        public List<UserBean> findUserById(QueryVo vo) {
          SqlSession sqlSession=this.getSqlSession();
          List<UserBean> user=sqlSession.selectList("test.findUserById",vo);
          return user;
        }

    
    }

         4)) 注入dao层于sprign配置文件(applicationContext.xml)

         这里为dao层注入了sqlSessionFactory

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
        <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:db.properties" />
        <!-- 数据库连接池 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
            <property name="maxActive" value="10" />
            <property name="maxIdle" value="5" />
        </bean>
     <context:component-scan base-package="com.aliance.entity"/> <!-- 整合后会话工厂归spring来管理 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定mybatis核心配置文件 --> <property name="configLocation" value="classpath:SqlMapConfig.xml"></property> <!-- 指定会话工厂使用的数据源 --> <property name="dataSource" ref="dataSource"/> </bean> <!--配置原生Dao实现 --> <bean id="userDao" class="com.clj.dao.UserDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>

         5))SqlMap.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>
         <typeAliases>
             <typeAlias type="com.aliance.entity.UserBean" alias="userBean"/>
         
         </typeAliases>
           <mappers>
               <mapper resource="User.xml"/>
           </mappers>
    </configuration>

       6))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 namespace="test">
            <sql id="testWhere">
                <where>
                    <if test="username!=null||username!=''">
                    and username like '%${username}%'
                </if>
                <if test="age!=null">
                    and age> #{age}
                </if>
                
                </where>
            </sql>
            <select id="findUserByUserNameAndMoney" parameterType="userBean" resultType="userBean">
                 select * from userinfo
                 <include refid="testWhere"/>
            </select>
            <select id="findUserById" parameterType="com.aliance.entity.QueryVo" resultType="userBean">
                select * from userinfo
                <where>
                    <if test="ids!=null">
                    <foreach collection="ids" item="id" open="and id in (" close=")" separator=",">
                        #{id}
                    </foreach>
                </if>
                </where>
            </select>
       
       </mapper>

        6)) 测试类

        方式一:

    package com.clj.Test;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.clj.dao.UserDao;
    import com.clj.pojo.User;
    
    public class UserDaoTest {
        private ApplicationContext applicationContext;
        @Before
        public void setUp() throws Exception{
            //这里可加classpath,也可不加
            String configLocation="classpath:applicationContext.xml";
            applicationContext=new ClassPathXmlApplicationContext(configLocation);
        }
        @Test
        public void testFindUserById() throws Exception{
            //获取UserDao对象,getBean中的字符串是在applcationContext.xml中神明的 
            UserDao userDao=(UserDao)applicationContext.getBean("userDao");
            User user=userDao.findUserById(1);
            System.out.println(user);
        }
    }

      方式二:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:ApplicationContext.xml")
    public class TestDemo1 {
        @Resource
        private ApplicationContext application;
        @Resource
        private UserBean userBean;
        @Resource
        private UserDao userDao;
        @Resource
        private QueryVo vo;
        @Test
        public void run2(){
            userDao=(UserDao) application.getBean("userDao");
            userBean.setUsername("李");
            userBean.setAge("11");
            List<UserBean> list=userDao.findUserByUserNameAndMoney(userBean);
            System.out.println(list);
        }
        @Test
        public void run3(){
            userDao=(UserDao) application.getBean("userDao");
            List<Integer> list=new ArrayList();
            list.add(1);
            list.add(3);
            list.add(6);
            vo.setIds(list);
            List<UserBean> temp=userDao.findUserById(vo);
            System.out.println(temp);
            
            
        }
    }

      注意:这里由于sqlSessionFactory归spring管理,所以其关闭也是有spring管理,如果在测试中手动关闭session,会报错

      

      2)开发方式二:Mapper代理形式开发dao

      1))新建一个mapper包,用来配置mapper的接口和配置文件

      mapper接口:这里和整合前mybatis中动态mapper代理接口代码一致

    package com.clj.UserMapper;
    
    import java.util.List;
    
    import com.clj.pojo.CustomerOrders;
    import com.clj.pojo.Orders;
    import com.clj.pojo.QueryVo;
    import com.clj.pojo.User;
    
    //与之关乎的配置文件要在同一个目录包下
    public interface UserMapper {
        public User findUserById(Integer id);
        //注意:这里是模糊查询,配置文件虽然写的是User,实际返回的是List集合
        //动态代理形式中,如果返回结果集List,那么mybatis会在生成实现类的时候会自动调用selectList方法
        public List<User> findUserByUserName(String userName);
        public  void insertUser(User user);
        public List<User> findUserbyVo(QueryVo vo);
        public Integer findUserCount();
        public List<User> findUserByUserNameAndSex(User user);
        public List<User> findUserByIds(QueryVo vo);
        public List<CustomerOrders> findOrderAndUser1();
        public List<Orders> findOrderAndUser2();
        public List<User> findUserAndOrders();
    }

         2))配置sql映射文件:这里和整合前mybatis中动态mapper代理接口代码一致

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
    <!--mapper接口代理实现编写轨则
        1.映射文件中namespace要等于接口的全路径名
        2.映射文件中sql语句id要等于接口的方法名称
        3.映射文件中传入参数类型要等于接口方法的传入参数类型
        4.映射文件中返回结果集类型等于接口方法的返回值类型
     -->
    <mapper namespace="com.clj.UserMapper.UserMapper">
        <!-- 封装sql条件,封装后可以重用 
            id:此sql的唯一标识符
        -->
        <sql id="user_where">
            <where>
            <if test="username!=null and username !=''">
                and username like '%${username}%'
            </if>
            <if test="sex !=null and sex!=''">
                and sex=#{sex}
            </if>
            </where>
            
        </sql>    
    
    
    
        <select id="findUserById" parameterType="int" resultType="com.clj.pojo.User">
            select * from user where id=#{id}
        </select>
        <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.clj.pojo.User">
            <!--select * from user where username like #{name}  -->
            select * from user where username like '%${value}%'
        </select>
        <!-- 这里返回值使用的别名 -->
        <insert id="insertUser" parameterType="user">
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                select LAST_INSERT_ID()
            </selectKey>
            insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
        </insert>
        <delete id="delUserById" parameterType="int">
            delete from user where id=#{id}
        </delete>
        <update id="updateUserById" parameterType="com.clj.pojo.User">
            update user set username=#{username} where id=#{id}
        </update>
        <select id="findUserbyVo" parameterType="com.clj.pojo.QueryVo" resultType="com.clj.pojo.User">
            select * from user where username like '%${user.username}%' and sex=#{user.sex}
        </select>
        <!-- 只有返回结果为一行一列的时候,那么返回值类型时可以指定类型为基本类型 -->
        <select id="findUserCount" resultType="int">
            select count(*) from user
        </select>
        <select id="findUserByUserNameAndSex" parameterType="com.clj.pojo.User" resultType="com.clj.pojo.User">
            select * from  user
            <!-- where标签作用:
                会自动向sql语句中添加where关键字
                会去掉第一个条件的and关键字 
            <where>
            <if test="username!=null and username !=''">
                and username like '%${username}%'
            </if>
            <if test="sex !=null and sex!=''">
                and sex=#{sex}
            </if>
            </where>-->
            <!-- 调用全局条件 -->
            <include refid="user_where"/>
        </select>
        <select id="findUserByIds" parameterType="com.clj.pojo.QueryVo" resultType="com.clj.pojo.User">
            <!-- select * from user where id in (1,16,28,22) -->
                select * from user
            <where>
                <!-- 这里的id指定是vo中的集合属性 -->
                <if test="ids!=null">
                    <!-- foreach:循环传入的集合参数
                        collection:传入的集合的变量名称
                        item:每次循环将循环的数据放入这个变量中
                        open:循环开始拼接的字符串
                        close:循环结束拼接的字符串
                        separator:循环中拼接的分隔符
                     -->
                    <foreach collection="ids" item="id" open="id in (" close=")" separator=",">
                        #{id}
                    </foreach>
                </if>
            </where>
        </select>
        <!-- 关于一对一查询 -->
        <!-- 方式一:自动映射 :利用类中的属性对应表中的字段
        需要提供封装user和order属性的类-->
        <select id="findOrderAndUser1" resultType="com.clj.pojo.CustomerOrders">
            select a.*,b.id uid,username,birthday,sex,address
            from orders a,user b
            where a.user_id=b.id
        </select>
        <!-- 一对以:手动映射:需要在order类中封装User这个属性 -->
        <!--
            id:resultMap的唯一标识
            type:将查询出的数据放入指定的对象中
            注意:手动映射需要指定数据表中的字段名与java中pojo类中的属性名称对应的关系
          -->
        <resultMap type="com.clj.pojo.Orders" id="orderAndUserResultMap">
            <!--id标签指定主键字段对应关系
                column:列,数据库中的字段名称
                property:属性,java中pojo中的属性名称
              -->
            <id column="id" property="id"/>
            <!-- result:指定 非主键对应的关系-->
            <result column="user_id" property="userId"/>
            <result column="number" property="number"/>
            <result column="createtime" property="createtime"/>
            <result column="note" property="note"/>
            <!-- 这个标签指定单个对象的对应关系 
                property:指定将数据放入Orders中的user属性中
                javaType:user属性中类型的路径
            -->
            <association property="user" javaType="com.clj.pojo.User">
                <id column="uid" property="id"/>
                <result column="username" property="username"/>
                <result column="sex" property="sex"/>
                <result column="birthday" property="birthday"/>
                <result column="address" property="address"/>
            </association>
        </resultMap>
        <select id="findOrderAndUser2" resultMap="orderAndUserResultMap">
            select a.*,b.id uid,username,birthday,sex,address
            from orders a,user b
            where a.user_id=b.id
        </select>
        <!-- 一对多 -->
        <resultMap type="com.clj.pojo.User" id="userAndOrderMap">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
            <!-- 指定对应的集合对象关系映射 
            property:将数据放入User对象中的orderList属性中
            ofType:指定orderList属性泛型类型
            -->
            <collection property="ordersList" ofType="com.clj.pojo.Orders">
                <id column="oid" property="id"/>
                <result column="user_id" property="userId"/>
                <result column="number" property="number"/>
                <result column="createtime" property="createtime"/>
                <result column="note" property="note"/>
                <!-- 注意:这里不需要配置user属性,他是用于一对一时配置的属性,与这里无关 -->
            </collection>
        </resultMap>
        <select id="findUserAndOrders" resultMap="userAndOrderMap">
            select a.*,b.id oid,user_id,number,createtime
            from user a,order b where a.id=b.user_id
        </select>
    </mapper>

        3))在applicationContext.xml映射文件中注入mapper接口

         方式一:手动配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
        <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:db.properties" />
        <!-- 数据库连接池 -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
            <property name="maxActive" value="10" />
            <property name="maxIdle" value="5" />
        </bean>
        <!-- 整合后会话工厂归spring来管理 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 指定mybatis核心配置文件 -->
            <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
            <!-- 指定会话工厂使用的数据源 -->
            <property name="dataSource" ref="dataSource"/>
        </bean>
        <!--配置原生Dao实现 -->
        <bean id="userDao" class="com.clj.dao.UserDaoImpl">
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
        <!-- 动态代理方式:Mappper接口代理实现-->
        <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
            配置Mapper接口的全路径名称,其中property name="mapperInterface"是根据主类来配置的
            <property name="mapperInterface" value="com.clj.UserMapper.UserMapper"/>
            <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean> 
    </beans>
    public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
    
      private Class<T> mapperInterface;
    }

      其中MapperScannerConfigurer的路径为

      

        方式二:采用包扫描的方式

    <!--使用包扫描的方式批量引入Mapper
            扫描后引用时可以使用类名,首字母小写
        -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <!-- 指定要扫描的包的全路径名称 ,如果有多个,用逗号','隔开-->
            <!-- 此时可以关掉SqlMapConfig.xml文件中对Mapper的扫描-->
            <property name="basePackage" value="com.clj.UserMapper"/>
        </bean>

         其中MapperScannerConfigurer的路径为

      

        如果采用包扫描的方式,他与mybatis中的sqlMapConfig.xml文件中扫描有冲突,需要屏蔽sqlMapConfig.xml的代码

      

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration 
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <package name="com.clj.pojo"/>
        </typeAliases>
     
        <mappers>
             <mapper resource="User.xml"/>
                <!-- <package name="com.clj.UserMapper"/> -->
        </mappers>
    </configuration>

        4))测试类

    package com.clj.Test;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.clj.UserMapper.UserMapper;
    import com.clj.pojo.User;
    
    public class UserMapperTest {
        private ApplicationContext applicationContext;
        @Before
        public void setUp() throws Exception{
            //这里可加classpath,也可不加
            String configLocation="classpath:applicationContext.xml";
            applicationContext=new ClassPathXmlApplicationContext(configLocation);
        }
        @Test
        public void testFindUserById()throws Exception{
         //方式一:手动配置:通过bean中id获取 UserMapper userMapper
    =(UserMapper) applicationContext.getBean("userMapper");
         //方式二:扫描方式:通过mapper接口名进行获取,注意,getBean()中的值是通过类名第一个字母小写得到 User user
    =userMapper.findUserById(1); System.out.println(user); } }

     十、MyBatis之逆向工程

      1、逆向工程作用

      自动生成Pojo类,还可以自动生成Mapper接口和映射文件,注意:生成的方式是追加而不是覆盖,所以不可以重复生成,重复生成的文件有问题,如果想重复生成将原来生 成的文件删除

      2、快速部署环境

       1)下载核心jar包mybatis-generator-core-1.3.2

       

      2)在项目工程(非src下)构建源码包,用来存放配置文件

      3)创建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

      4)配置generatorConfig.xml文件

       此文件用来配置Mapper中的信息(注意几点:1. 添加要生成的数据库表 2.pojo文件所在包路径 3.mapper文件所在包路径)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
      PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
      "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
        <context id="testTables" targetRuntime="MyBatis3">
            <commentGenerator>
                <!-- 是否去除自动生成的注释 true:是 : false:否 -->
                <property name="suppressAllComments" value="true" />
            </commentGenerator>
            <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                connectionURL="jdbc:mysql://192.168.174.130:3306/SSM" userId="root"
                password="root">
            </jdbcConnection>
            <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
                connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
                userId="yycg"
                password="yycg">
            </jdbcConnection> -->
    
            <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
                NUMERIC 类型解析为java.math.BigDecimal -->
            <javaTypeResolver>
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
    
            <!-- targetProject:生成PO类的位置 -->
            <javaModelGenerator targetPackage="cn.clj.pojo"
                targetProject=".src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
                <!-- 从数据库返回的值被清理前后的空格 -->
                <property name="trimStrings" value="true" />
            </javaModelGenerator>
            <!-- targetProject:mapper映射文件生成的位置 -->
            <sqlMapGenerator targetPackage="cn.clj.mapper" 
                targetProject=".src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </sqlMapGenerator>
            <!-- targetPackage:mapper接口生成的位置 -->
            <javaClientGenerator type="XMLMAPPER"
                targetPackage="cn.clj.mapper" 
                targetProject=".src">
                <!-- enableSubPackages:是否让schema作为包的后缀 -->
                <property name="enableSubPackages" value="false" />
            </javaClientGenerator>
            <!-- 指定数据库表 -->
            <table tableName="orders"></table>
            <table tableName="user"></table>
            <!-- <table schema="" tableName="sys_user"></table>
            <table schema="" tableName="sys_role"></table>
            <table schema="" tableName="sys_permission"></table>
            <table schema="" tableName="sys_user_role"></table>
            <table schema="" tableName="sys_role_permission"></table> -->
            
            <!-- 有些表的字段需要指定java类型
             <table schema="" tableName="">
                <columnOverride column="" javaType="" />
            </table> -->
        </context>
    </generatorConfiguration>

      5)根据指定的路径创建文件包

        这里要创建cn.clj.mapper与cn.clj.pojo包,逆向工程不会自动帮你键包,所有要提前创建

      

       6)创建启动类

        注意:这里的要配置generatorConfig.xml文件位置

    package com.clj.Test;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.mybatis.generator.api.MyBatisGenerator;
    import org.mybatis.generator.config.Configuration;
    import org.mybatis.generator.config.xml.ConfigurationParser;
    import org.mybatis.generator.internal.DefaultShellCallback;
    
    public class StartService {
        public void generator() throws Exception{
            List<String> warnings = new ArrayList<String>();
            boolean overwrite = true;
            File configFile = new File("config/generatorConfig.xml"); 
            ConfigurationParser cp = new ConfigurationParser(warnings);
            Configuration config = cp.parseConfiguration(configFile);
            DefaultShellCallback callback = new DefaultShellCallback(overwrite);
            MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
                    callback, warnings);
            myBatisGenerator.generate(null);
        }
        public static void main(String[] args) throws Exception {
            try {
                StartService startService = new StartService();
                startService.generator();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
    }

     

     

     

      

  • 相关阅读:
    内网穿透教程
    深入浅出 TCP/IP 协议栈
    STM32CUBEMX配置RTC闹钟
    RT-Thread STM32 系列 BSP 制作教程
    RT-Thread 在stm小内存系列产品的nano+msh完整移植教程
    C语言字符串与数字相互转换
    SD卡 TF卡 接口引脚定义
    定位数据格式
    安信可ESP-12F连接阿里云教程
    电脑使用网络调试助手连接阿里云步骤
  • 原文地址:https://www.cnblogs.com/cailijia52o/p/8725850.html
Copyright © 2020-2023  润新知