java框架之MyBatis(2)-进阶&整合Spring&逆向工程

进阶内容

准备

jdbc.url=jdbc:mysql://192.168.208.192:3306/test?characterEncoding=utf-8
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root
jdbc.properties
log4j.rootLogger = debug,stdout,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
log4j.properties
<?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="jdbc.properties"/>

    <!--别名扫描-->
    <typeAliases>
        <package name="com.zze.mybatis.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>
        <package name="com.zze.mybatis.mapper"/>
    </mappers>
</configuration>
mybatis/SqlMapConfig.xml
package com.zze.mybatis.pojo;

import java.util.Date;

public class User {
    private Integer id;
    private String name;
    private Date birthday;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}
com.zze.mybatis.pojo.User
package com.zze.mybatis.util;

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 java.io.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        // 建立 SqlSessionFactoryBuilder 对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // 建立核心配置文件的输入流
        InputStream resourceAsStream = null;
        try {
            resourceAsStream = Resources.getResourceAsStream("mybatis/SqlMapConfig.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 建立 Session 工厂
        sqlSessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
    }

    /**
     * 打开一个 Session
     *
     * @return SqlSession 实例
     */
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }

    /**
     * 打开一个 Session
     *
     * @param autoCommit 是否自动提交事务
     * @return SqlSession 实例
     */
    public static SqlSession openSession(Boolean autoCommit) {
        return sqlSessionFactory.openSession(autoCommit);
    }
}
com.zze.mybatis.util.SqlSessionFactoryUtil
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zze.mybatis</groupId>
    <artifactId>mybatis_test2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.11.0.GA</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
pom.xml

传递被包装的pojo

package com.zze.mybatis.pojo;

public class QueryVO {
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}
com.zze.mybatis.pojo.QueryVO
<?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="com.zze.mybatis.mapper.UserMapper">
    <select id="getByQueryVO" parameterType="queryvo" resultType="user">
        select id,name,birthday from user where name like '%${user.name}%'
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml
package com.zze.mybatis.mapper;

import com.zze.mybatis.pojo.QueryVO;
import com.zze.mybatis.pojo.User;

public interface UserMapper {
    User getByQueryVO(QueryVO queryVO);
}
com.zze.mybatis.mapper.UserMapper
@Test
public void test() {
    SqlSession sqlSession = SqlSessionFactoryUtil.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    QueryVO queryVO = new QueryVO();
    User user = new User();
    user.setName("张");
    queryVO.setUser(user);
    User user1 = mapper.getByQueryVO(queryVO);
    System.out.println(user1);
  /*
  ==>  Preparing: select name,age,birthday,uuid from user where name like '%张%'
   */
}
test

标签使用

字段映射-resultMap

若是表字段名与 pojo 属性名不一致,则可经过 resultMap 标签配置表字段与 pojo 属性的映射关系:java

<?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="com.zze.mybatis.mapper.UserMapper">
    <resultMap id="userMap" type="user">
        <!--
        id 配置对应主键字段
            property:属性名
            column:字段名
        -->
        <id property="id" column="uid"/>
        <!--
        result 配置普通属性字段
            property:属性名
            column:字段名
        -->
        <result property="name" column="username"/>
        <!--
        非关联查询时
        属性名与字段名相同的 result 映射能够省略不写
        -->
        <!--<result property="birthday" column="birthday"/>-->
    </resultMap>

    <select id="getAll" resultMap="userMap">
        select id uid,name username,birthday from user;
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml
package com.zze.mybatis.mapper;

import com.zze.mybatis.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> getAll();
}
com.zze.mybatis.mapper.UserMapper
package com.zze.mybatis.test;

import com.zze.mybatis.mapper.UserMapper;
import com.zze.mybatis.pojo.User;
import com.zze.mybatis.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class MyBatisTest {
    private UserMapper userMapper;

    @Before
    public void init() {
        SqlSession sqlSession = SqlSessionFactoryUtil.openSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void test() {
        List<User> all = userMapper.getAll();
        for (User user : all) {
            System.out.println(user);
        }
        /*
        ==>  Preparing: select id uid,name username,birthday from user;
         */
    }
}
test

动态sql-where&if

当 sql 条件须要动态拼接时,可使用 where 和 if 标签:mysql

<?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="com.zze.mybatis.mapper.UserMapper">
    <select id="getByUser" resultType="user" parameterType="user">
        select id,name,birthday from user
        <where>
            <if test="name!=null and name!=''">
                name like '%${name}%'
            </if>
        </where>
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml
package com.zze.mybatis.mapper;

import com.zze.mybatis.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> getByUser(User user);
}
com.zze.mybatis.mapper.UserMapper
package com.zze.mybatis.test;

import com.zze.mybatis.mapper.UserMapper;
import com.zze.mybatis.pojo.User;
import com.zze.mybatis.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class MyBatisTest {
    private UserMapper userMapper;

    @Before
    public void init() {
        SqlSession sqlSession = SqlSessionFactoryUtil.openSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void test() {
        User user = new User();
        user.setName("张");
        List<User> userList1 = userMapper.getByUser(user);
        userList1.forEach(u-> System.out.println(u));
        /*
        ==>  Preparing: select id,name,birthday from user WHERE name like '%张%'
         */
        user.setName(null);
        List<User> userList2 = userMapper.getByUser(user);
        userList2.forEach(u-> System.out.println(u));
        /*
        ==>  Preparing: select id,name,birthday from user
         */
    }
}
test

sql片断-sql&include

当一段 sql 要被频繁在多处使用时,能够将这段 sql 单独抽取出来:spring

<?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="com.zze.mybatis.mapper.UserMapper">
    <sql id="userAllField">
      id,name,birthday
    </sql>
    <select id="getAll" resultType="user">
        select
        <include refid="userAllField"/>
        from user
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml
package com.zze.mybatis.mapper;

import com.zze.mybatis.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> getAll();
}
com.zze.mybatis.mapper.UserMapper
package com.zze.mybatis.test;

import com.zze.mybatis.mapper.UserMapper;
import com.zze.mybatis.pojo.User;
import com.zze.mybatis.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class MyBatisTest {
    private UserMapper userMapper;

    @Before
    public void init() {
        SqlSession sqlSession = SqlSessionFactoryUtil.openSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void test() {
        List<User> userList = userMapper.getAll();
        userList.forEach(u-> System.out.println(u));
        /*
        ==>  Preparing: select id,name,birthday from user
         */
    }
}
test

循环-foreach

编写 sql 时也能够经过传入集合来动态拼装条件:sql

package com.zze.mybatis.pojo;

import java.util.List;

public class QueryVO {
    private List<Integer> idList;

    public List<Integer> getIdList() {
        return idList;
    }

    public void setIdList(List<Integer> idList) {
        this.idList = idList;
    }
}
com.zze.mybatis.pojo.QueryVO
<?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="com.zze.mybatis.mapper.UserMapper">
    <select id="getByIdList" resultType="user" parameterType="queryvo">
        select * from user
        <where>
            <foreach collection="idList" open="id in (" close=")" separator="," item="id">
              #{id}
            </foreach>
        </where>
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml
package com.zze.mybatis.mapper;

import com.zze.mybatis.pojo.QueryVO;
import com.zze.mybatis.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> getByIdList(QueryVO queryVO);
}
com.zze.mybatis.mapper.UserMapper
package com.zze.mybatis.test;

import com.zze.mybatis.mapper.UserMapper;
import com.zze.mybatis.pojo.QueryVO;
import com.zze.mybatis.pojo.User;
import com.zze.mybatis.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class MyBatisTest {
    private UserMapper userMapper;

    @Before
    public void init() {
        SqlSession sqlSession = SqlSessionFactoryUtil.openSession();
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void test() {
        QueryVO queryVO = new QueryVO();
        queryVO.setIdList(Arrays.asList(1, 2, 3));
        List<User> userList = userMapper.getByIdList(queryVO);
        userList.forEach(u-> System.out.println(u));
        /*
        ==>  Preparing: select * from user WHERE id in ( ? , ? , ? )
        ==> Parameters: 1(Integer), 2(Integer), 3(Integer)
         */
    }
}
test

要注意的是 mybatis 不支持直接传入集合,但咱们能够如上示例将它放在包装类中传入。数据库

关联查询

一对一

新建与用户关联的订单表和 pojo,配置映射文件:apache

package com.zze.mybatis.pojo;

import java.util.Date;

public class Order {
    private Integer id;
    private Integer uId;
    private Double totalPrice;
    private Date createDate;
    /*
    Order 一对一关联 User
     */
    private User user;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getuId() {
        return uId;
    }

    public void setuId(Integer uId) {
        this.uId = uId;
    }

    public Double getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(Double totalPrice) {
        this.totalPrice = totalPrice;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", uId=" + uId +
                ", TotalPrice=" + totalPrice +
                ", createDate=" + createDate +
                ", user=" + user +
                '}';
    }
}
com.zze.mybatis.pojo.Order
<?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="com.zze.mybatis.mapper.OrderMapper">
    <resultMap id="orderMap" type="order">
        <!--
        注意:
                在关联查询时,每一个映射字段都需配置,不可省略。
        -->
        <id property="id" column="oid"/>
        <result property="uId" column="uid"/>
        <result property="totalPrice" column="totalPrice"/>
        <result property="createDate" column="createdate"/>
        <!--
        经过 association 配置一对一关系
        -->
        <association property="user" javaType="user">
            <id property="id" column="uid"/>
            <result property="name" column="name"/>
            <result property="birthday" column="birthday"/>
        </association>
    </resultMap>

    <select id="getAll" resultMap="orderMap">
      select o1.id oid,o1.uid,totalPrice,createdate,name,birthday from `order` o1 left join `user` u1 on o1.uid = u1.id;
    </select>
</mapper>
com/zze/mybatis/mapper/OrderMapper.xml
package com.zze.mybatis.test;

import com.zze.mybatis.mapper.OrderMapper;
import com.zze.mybatis.pojo.Order;
import com.zze.mybatis.util.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class OrderTest {

    private OrderMapper orderMapper;

    @Before
    public void init() {
        SqlSession sqlSession = SqlSessionFactoryUtil.openSession();
        orderMapper = sqlSession.getMapper(OrderMapper.class);
    }

    @Test
    public void test() {
        List<Order> orderList = orderMapper.getAll();
        orderList.forEach(o -> System.out.println(o));

        /*
        ==>  Preparing: select o1.id oid,o1.uid,totalPrice,createdate,name,birthday from `order` o1 left join `user` u1 on o1.uid = u1.id;

        Order{id=1, uId=1, TotalPrice=324.0, createDate=Thu Mar 21 11:10:20 CST 2019, user=User{id=1, name='张三', birthday=Thu Jan 01 00:00:00 CST 1998}}
        Order{id=3, uId=1, TotalPrice=543.0, createDate=Mon Mar 18 11:11:05 CST 2019, user=User{id=1, name='张三', birthday=Thu Jan 01 00:00:00 CST 1998}}
        Order{id=2, uId=3, TotalPrice=23.0, createDate=Fri Mar 01 06:04:07 CST 2019, user=User{id=3, name='李四', birthday=Thu Jan 01 00:00:00 CST 1998}}
         */
    }
}
test

一对多

修改用户的 pojo 关联订单,配置映射文件:api

package com.zze.mybatis.pojo;

import java.util.Date;
import java.util.List;

public class User {
    private Integer id;
    private String name;
    private Date birthday;

    /*
    User 一对多关联 Order
     */
    private List<Order> orders;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}
com.zze.mybatis.pojo.User
<?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="com.zze.mybatis.mapper.UserMapper">
    <resultMap id="userMap" type="user">
        <id property="id" column="uId"/>
        <result property="name" column="name"/>
        <result property="birthday" column="birthday"/>
        <!--
        使用 collection 标签创建一对多关系
            注意,这里使用的是 ofType,而一对一关联时使用的是 javaType
        -->
        <collection property="orders" ofType="order">
            <id property="id" column="oId"/>
            <result property="totalPrice" column="totalPrice"/>
            <result property="createDate" column="createDate"/>
            <result property="uId" column="uId"/>
        </collection>
    </resultMap>

    <select id="getAll" resultMap="userMap">
        select u1.id uId,o1.id oId,totalPrice,createdate,name,birthday from `user` u1 left join `order` o1 on u1.id=o1.uid;
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml

MyBatis与Spring整合

整合思路

  1. SqlSessionFactory 对象应该交给 Spring 管理并做为单例存在。
  2. 传统 dao 的开发方式中,应该从 Spring 容器中获取 SqlSession 对象。
  3. Mapper 动态代理开发方式中,应该从 Spring 容器中直接得到 Mapper 对象。
  4. 数据库的链接及链接池、事务都交给 Spring 管理。

准备

一、建立一个 maven java 工程,引入相关依赖:session

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zze.mybatis</groupId>
    <artifactId>mybatis_spring</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!--spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <!--mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.8</version>
        </dependency>
        <!--mybatis 整合 spring-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--mysql 驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <!--阿里巴巴数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.18</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!--日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
pom.xml

二、引入 mybatis 核心配置文件:mybatis

<?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>
   
</configuration>
config/SqlMapConfig.xml

三、引入 jdbc 链接信息属性文件:app

jdbc.url=jdbc:mysql://192.168.208.192:3306/test?characterEncoding=utf-8
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=root
config/jdbc.properties

四、引入 log4j 属性文件:

log4j.rootLogger = debug,stdout,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
log4j.properties

五、引入 spring 核心配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <!--读取属性文件-->
    <context:property-placeholder location="classpath:config/jdbc.properties"/>
    <!--链接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <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="20"/>
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="1"/>
        <!-- 配置获取链接等待超时的时间 -->
        <property name="maxWait" value="60000"/>
        <!-- 配置间隔多久才进行一次检测,检测须要关闭的空闲链接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <!-- 配置一个链接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>
    </bean>
    <!--配置 SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置核心配置文件路径-->
        <property name="configLocation" value="classpath:config/SqlMapConfig.xml"/>
        <!--配置别名扫描包-->
        <property name="typeAliasesPackage" value="com.zze.mybatis.pojo"/>
    </bean>
</beans>
config/applicationContext.xml

六、建立测试用 pojo 及其映射文件:

package com.zze.mybatis.pojo;

import java.util.Date;

public class User {
    private Integer id;
    private String name;
    private String gender;
    private Date birthday;
    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    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 +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", birthday=" + birthday +
                ", address='" + address + '\'' +
                '}';
    }
}
com.zze.mybatis.pojo.User
<?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>
    <mappers>
        <mapper resource="config/mapper/UserMapper.xml"/>
    </mappers>
</configuration>
config/mapper/UserMapper.xml

七、建立 dao 接口:

package com.zze.mybatis.dao;

import com.zze.mybatis.pojo.User;

import java.util.List;

public interface UserDao {
    List<User> getAll();
}
com.zze.mybatis.dao.UserDao

传统dao开发

一、在 mybatis 核心配置文件中引入映射文件:

<?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>
    <mappers>
        <mapper resource="config/mapper/UserMapper.xml"/>
    </mappers>
</configuration>
config/SqlMapConfig.xml

二、编写 dao 接口实现类:

package com.zze.mybatis.dao.impl;

import com.zze.mybatis.dao.UserDao;
import com.zze.mybatis.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    @Override
    public List<User> getAll() {
        SqlSession sqlSession = super.getSqlSession();
        List<User> userList = sqlSession.selectList("user.getAll");
        // 注意,这里 SqlSession 的实例的建立与销毁已经交给 Spring 管理,不用手动关闭,不然会异常
        return userList;
    }
}
com.zze.mybatis.dao.impl.UserDaoImpl

三、修改 Spring 配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <!--读取属性文件-->
    <context:property-placeholder location="classpath:config/jdbc.properties"/>
    <!--链接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <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="20"/>
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="1"/>
        <!-- 配置获取链接等待超时的时间 -->
        <property name="maxWait" value="60000"/>
        <!-- 配置间隔多久才进行一次检测,检测须要关闭的空闲链接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <!-- 配置一个链接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>
    </bean>
    <!--配置 SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置核心配置文件路径-->
        <property name="configLocation" value="classpath:config/SqlMapConfig.xml"/>
        <!--配置别名扫描包-->
        <property name="typeAliasesPackage" value="com.zze.mybatis.pojo"/>
    </bean>

    <bean id="userDao" class="com.zze.mybatis.dao.impl.UserDaoImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>
config/applicationContext.xml

四、测试:

package com.zze.mybatis.test;

import com.zze.mybatis.dao.UserDao;
import com.zze.mybatis.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class UserDaoTest {

    private ApplicationContext applicationContext;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("classpath:config/applicationContext.xml");
    }
    @Test
    public void test(){
        UserDao userDao = applicationContext.getBean(UserDao.class);
        List<User> userList = userDao.getAll();
        userList.forEach(u-> System.out.println(u));
        /*
        ==>  Preparing: select id,name,gender,birthday,address from user;
         */
    }
}
com.zze.mybatis.test.UserDaoTest

动态代理开发

一、修改 UserDao 为 UserMapper:

package com.zze.mybatis.mapper;

import com.zze.mybatis.pojo.User;

import java.util.List;

public interface UserMapper {
    List<User> getAll();
}
com.zze.mybatis.mapper.UserMapper

二、将映射文件放入 mapper 同一目录,并指定 namespace 为 mapper 类全路径:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zze.mybatis.mapper.UserMapper">
    <select id="getAll" resultType="user">
        select id,name,gender,birthday,address from user;
    </select>
</mapper>
com/zze/mybatis/mapper/UserMapper.xml

三、修改 Spring 配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    <!--读取属性文件-->
    <context:property-placeholder location="classpath:config/jdbc.properties"/>
    <!--链接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 基本属性 url、user、password -->
        <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="20"/>
        <property name="initialSize" value="1"/>
        <property name="minIdle" value="1"/>
        <!-- 配置获取链接等待超时的时间 -->
        <property name="maxWait" value="60000"/>
        <!-- 配置间隔多久才进行一次检测,检测须要关闭的空闲链接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000"/>
        <!-- 配置一个链接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000"/>
    </bean>
    <!--配置 SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置核心配置文件路径-->
        <property name="configLocation" value="classpath:config/SqlMapConfig.xml"/>
        <!--配置别名扫描包-->
        <property name="typeAliasesPackage" value="com.zze.mybatis.pojo"/>
    </bean>

    <!--动态代理配置方式一:配置单个接口-->
    <!--
    <bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    <bean parent="baseMapper">
        <property name="mapperInterface" value="com.zze.mybatis.mapper.UserMapper"/>
    </bean>
    -->
    <!--动态代理配置方式二:配置 mapper 包扫描-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zze.mybatis.mapper"/>
    </bean>
</beans>
config/applicationContext.xml

四、测试:

package com.zze.mybatis.test;

import com.zze.mybatis.dao.UserDao;
import com.zze.mybatis.mapper.UserMapper;
import com.zze.mybatis.pojo.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class UserMapperTest {

    private ApplicationContext applicationContext;
    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("classpath:config/applicationContext.xml");
    }
    @Test
    public void test(){
        UserMapper userMapper = applicationContext.getBean(UserMapper.class);
        List<User> userList = userMapper.getAll();
        userList.forEach(u-> System.out.println(u));
        /*
        ==>  Preparing: select id,name,gender,birthday,address from user;
         */
    }
}
com.zze.mybatis.test.UserMapperTest

逆向工程

建立maven逆向工程

一、建立 maven java 工程,引入以下依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zze</groupId>
    <artifactId>mybaits_generator</artifactId>
    <version>Lasted</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.0-rc1</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
    </dependencies>
</project>
pom.xml

二、引入逆向生成配置文件:

<?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>
    <!-- 能够用于加载配置项或者配置文件,在整个配置文件中就可使用${propertyKey}的方式来引用配置项
    resource:配置资源加载地址,使用resource,MBG从classpath开始找,好比com/myproject/generatorConfig.properties
    url:配置资源加载地质,使用URL的方式,好比file:///C:/myfolder/generatorConfig.properties.
    注意,两个属性只能选址一个;

    另外,若是使用了mybatis-generator-maven-plugin,那么在pom.xml中定义的properties均可以直接在generatorConfig.xml中使用
    <properties resource="" url="" />
    -->

    <!-- 在MBG工做的时候,须要额外加载的依赖包
       location属性指明加载jar/zip包的全路径
   <classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />
     -->

    <!--
        context:生成一组对象的环境
        id:必选,上下文id,用于在生成错误时提示
        defaultModelType:指定生成对象的样式
            1,conditional:相似hierarchical;
            2,flat:全部内容(主键,blob)等所有生成在一个对象中;
            3,hierarchical:主键生成一个XXKey对象(key class),Blob等单独生成一个对象,其余简单属性在一个对象中(record class)
        targetRuntime:
            1,MyBatis3:默认的值,生成基于MyBatis3.x以上版本的内容,包括XXXBySample;
            2,MyBatis3Simple:相似MyBatis3,只是不生成XXXBySample;
        introspectedColumnImpl:类全限定名,用于扩展MBG
    -->
    <context id="mybatisGenerator">
        <!--
            自动识别数据库关键字,默认false,若是设置为true,根据SqlReservedWords中定义的关键字列表;
            通常保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
        -->
        <property name="autoDelimitKeywords" value="false"/>
        <!-- 生成的Java文件的编码 -->
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 格式化java代码 -->
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <!-- 格式化XML代码 -->
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>

        <!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,好比ORACLE就是双引号,MYSQL默认是`反引号; -->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>


        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库链接的信息:驱动类、链接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/test?
                                serverTimezone=CTT&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;allowMultiQueries=true"
                        userId="root"
                        password="root">
        </jdbcConnection>

        <!-- java类型处理器
        用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl;
        注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和 NUMERIC数据类型;
        -->
        <javaTypeResolver type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
            <!--
                true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型
                false:默认,
                    scale>0;length>18:使用BigDecimal;
                    scale=0;length[10,18]:使用Long;
                    scale=0;length[5,9]:使用Integer;
                    scale=0;length<5:使用Short;
             -->
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- java模型建立器,是必需要的元素
        负责:1,key类(见context的defaultModelType);2,java类;3,查询类
        targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制;
        targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,若是目录不存在,MBG不会自动建目录
        -->
        <javaModelGenerator targetPackage="com.zze.mybatis.pojo"
                            targetProject="mybatis_spring/src/main/java">
            <!--  for MyBatis3/MyBatis3Simple
            自动为每个生成的类建立一个构造方法,构造方法包含了全部的field;而不是使用setter;
            -->
            <property name="constructorBased" value="false"/>

            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
            <property name="enableSubPackages" value="true"/>

            <!-- for MyBatis3 / MyBatis3Simple
                是否建立一个不可变的类,若是为true,
                那么MBG会建立一个没有setter方法的类,取而代之的是相似constructorBased的类
             -->
            <property name="immutable" value="false"/>

            <!-- 设置一个根对象,
                若是设置了这个根对象,那么生成的keyClass或者recordClass会继承这个类;在Table的rootClass属性中能够覆盖该选项
                注意:若是在key class或者record class中有root class相同的属性,MBG就不会从新生成这些属性了,包括:
                    1,属性名相同,类型相同,有相同的getter/setter方法;
             -->
            <!-- <property name="rootClass" value="com.zze.mybatis.pojo.BaseDomain"/>-->

            <!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- 生成SQL map的XML文件生成器,
             注意,在Mybatis3以后,咱们可使用mapper.xml文件+Mapper接口(或者不用mapper接口),
                 或者只使用Mapper接口+Annotation,因此,若是 javaClientGenerator配置中配置了须要生成XML的话,这个元素就必须配置
             targetPackage/targetProject:同javaModelGenerator
        -->
        <sqlMapGenerator targetPackage="com.zze.mybatis.mapper"
                         targetProject="mybatis_spring/src/main/resources">
            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- 对于mybatis来讲,即生成Mapper接口,注意,若是没有配置该元素,那么默认不会生成Mapper接口
            targetPackage/targetProject:同javaModelGenerator
            type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下):
                1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式建立(SQL生成在annotation中),不会生成对应的XML;
                2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,可是XML会生成在XML中;
                3,XMLMAPPER:会生成Mapper接口,接口彻底依赖XML;
            注意,若是context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER
        -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.zze.mybatis.mapper"
                             targetProject="mybatis_spring/src/main/java">
            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
            <property name="enableSubPackages" value="true"/>

            <!-- 能够为全部生成的接口添加一个父接口,可是MBG只负责生成,不负责检查-->
            <!--<property name="rootInterface" value=""/>-->

        </javaClientGenerator>
        <!-- 选择一个table来生成相关文件,能够有一个或多个table,必需要有table元素
            选择的table会生成一下文件:
            1,SQL map文件
            2,生成一个主键类;
            3,除了BLOB和主键的其余字段的类;
            4,包含BLOB的类;
            5,一个用户生成动态查询的条件类(selectByExample, deleteByExample),可选;
            6,Mapper接口(可选)

            tableName(必要):要生成对象的表名;
            注意:大小写敏感问题。正常状况下,MBG会自动的去识别数据库标识符的大小写敏感度,在通常状况下,MBG会
                根据设置的schema,catalog或tablename去查询数据表,按照下面的流程:
                1,若是schema,catalog或tablename中有空格,那么设置的是什么格式,就精确的使用指定的大小写格式去查询;
                2,不然,若是数据库的标识符使用大写的,那么MBG自动把表名变成大写再查找;
                3,不然,若是数据库的标识符使用小写的,那么MBG自动把表名变成小写再查找;
                4,不然,使用指定的大小写格式查询;
            另外的,若是在建立表的时候,使用的""把数据库对象规定大小写,就算数据库标识符是使用的大写,在这种状况下也会使用给定的大小写来建立表名;
            这个时候,请设置delimitIdentifiers="true"便可保留大小写格式;

            可选:
            1,schema:数据库的schema;
            2,catalog:数据库的catalog;
            3,alias:为数据表设置的别名,若是设置了alias,那么生成的全部的SELECT SQL语句中,列名会变成:alias_actualColumnName
            4,domainObjectName:生成的domain类的名字,若是不设置,直接使用表名做为domain类的名字;能够设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面;
            5,enableInsert(默认true):指定是否生成insert语句;
            6,enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get);
            7,enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句;
            8,enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update);
            9,enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete);
            10,enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句;
            11,enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询);
            12,enableUpdateByExample(默认true):MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性);
            13,modelType:参考context元素的defaultModelType,至关于覆盖;
            14,delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,若是相似MYSQL这样的数据库,使用的是`(反引号,那么还须要设置context的beginningDelimiter和endingDelimiter属性)
            15,delimitAllColumns:设置是否全部生成的SQL中的列名都使用标识符引发来。默认为false,delimitIdentifiers参考context的属性

            注意,table里面不少参数都是对javaModelGenerator,context等元素的默认属性的一个复写;
         -->
        <table tableName="user" domainObjectName="User">
            <!-- 参考 javaModelGenerator 的 constructorBased属性-->
            <property name="constructorBased" value="false"/>

            <!-- 默认为false,若是设置为true,在生成的SQL中,table名字不会加上catalog或schema; -->
            <property name="ignoreQualifiersAtRuntime" value="false"/>

            <!-- 参考 javaModelGenerator 的 immutable 属性 -->
            <property name="immutable" value="false"/>
            <!-- 指定是否只生成domain类,若是设置为true,只生成domain类,若是还配置了sqlMapGenerator,那么在mapper XML文件中,只生成resultMap元素 -->
            <property name="modelOnly" value="false"/>

            <!-- 参考 javaModelGenerator 的 rootClass 属性
            <property name="rootClass" value=""/>
             -->

            <!-- 参考javaClientGenerator 的  rootInterface 属性
            <property name="rootInterface" value=""/>
            -->

            <!-- 若是设置了runtimeCatalog,那么在生成的SQL中,使用该指定的catalog,而不是table元素上的catalog
            <property name="runtimeCatalog" value=""/>
            -->

            <!-- 若是设置了runtimeSchema,那么在生成的SQL中,使用该指定的schema,而不是table元素上的schema
            <property name="runtimeSchema" value=""/>
            -->

            <!-- 若是设置了runtimeTableName,那么在生成的SQL中,使用该指定的tablename,而不是table元素上的tablename
            <property name="runtimeTableName" value=""/>
            -->

            <!-- 注意,该属性只针对MyBatis3Simple有用;
                若是选择的runtime是MyBatis3Simple,那么会生成一个SelectAll方法,若是指定了selectAllOrderByClause,那么会在该SQL中添加指定的这个order条件;
             -->
            <property name="selectAllOrderByClause" value="age desc,username asc"/>

            <!-- 若是设置为true,生成的model类会直接使用column自己的名字,而不会再使用驼峰命名方法,好比BORN_DATE,生成的属性名字就是BORN_DATE,而不会是bornDate -->
            <property name="useActualColumnNames" value="false"/>


            <!-- generatedKey用于生成生成主键的方法,
                若是设置了该元素,MBG会在生成的<insert>元素中生成一条正确的<selectKey>元素,该元素可选
                column:主键的列名;
                sqlStatement:要生成的selectKey语句,有如下可选项:
                    Cloudscape:至关于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
                    DB2       :至关于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
                    DB2_MF    :至关于selectKey的SQL为:SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
                    Derby     :至关于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
                    HSQLDB    :至关于selectKey的SQL为:CALL IDENTITY()
                    Informix  :至关于selectKey的SQL为:select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
                    MySql     :至关于selectKey的SQL为:SELECT LAST_INSERT_ID()
                    SqlServer :至关于selectKey的SQL为:SELECT SCOPE_IDENTITY()
                    SYBASE    :至关于selectKey的SQL为:SELECT @@IDENTITY
                    JDBC      :至关于在生成的insert元素上添加useGeneratedKeys="true"和keyProperty属性
            <generatedKey column="" sqlStatement=""/>
             -->

            <!--
                该元素会在根据表中列名计算对象属性名以前先重命名列名,很是适合用于表中的列都有公用的前缀字符串的时候,
                好比列名为:CUST_ID,CUST_NAME,CUST_EMAIL,CUST_ADDRESS等;
                那么就能够设置searchString为"^CUST_",并使用空白替换,那么生成的Customer对象中的属性名称就不是
                custId,custName等,而是先被替换为ID,NAME,EMAIL,而后变成属性:id,name,email;

                注意,MBG是使用java.util.regex.Matcher.replaceAll来替换searchString和replaceString的,
                若是使用了columnOverride元素,该属性无效;

            <columnRenamingRule searchString="" replaceString=""/>
             -->


            <!-- 用来修改表中某个列的属性,MBG会使用修改后的列来生成domain的属性;
                column:要从新设置的列名;
                注意,一个table元素中能够有多个columnOverride元素
                property : 使用property属性来指定列要生成的属性名称
                javaType : 用于指定生成的domain的属性类型,使用类型的全限定名
                jdbcType : 用于指定该列的JDBC类型
                typeHandler : 用于指定该列使用到的TypeHandler,若是要指定,配置类型处理器的全限定名
                delimitedColumnName : 参考table元素的delimitAllColumns配置,默认为false
                注意,mybatis中,不会生成到mybatis-config.xml中的typeHandler
                只会生成相似:where id = #{id,jdbcType=BIGINT,typeHandler=com._520it.mybatis.MyTypeHandler}的参数描述
             -->
            <columnOverride column="name" property="name"/>

            <!-- ignoreColumn设置一个MGB忽略的列,若是设置了改列,那么在生成的domain中,生成的SQL中,都不会有该列出现
               column:指定要忽略的列的名字;
               delimitedColumnName:参考table元素的delimitAllColumns配置,默认为false

               注意,一个table元素中能够有多个ignoreColumn元素
            <ignoreColumn column="deptId" delimitedColumnName=""/>
            -->
        </table>

    </context>
</generatorConfiguration>
generatorConfig.xml

三、引入日志文件:

log4j.rootLogger = debug,stdout

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
log4j.properties

四、引入可执行 java 类:

import org.apache.ibatis.io.Resources;
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;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("all")
public class Generator {
    public void generator() throws Exception {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        /**指向逆向工程配置文件*/
        File configFile = Resources.getResourceAsFile("generatorConfig.xml");
        ConfigurationParser parser = new ConfigurationParser(warnings);
        Configuration config = parser.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 {
            Generator generatorSqlmap = new Generator();
            generatorSqlmap.generator();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Generator

五、在‘generatorConfig.xml’中完成相关配置,执行 Generator 便可。

使用

package com.zze.mybaits.test;

import com.zze.mybatis.mapper.UserMapper;
import com.zze.mybatis.pojo.User;
import com.zze.mybatis.pojo.UserExample;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

public class UserMapperTest {

    private ApplicationContext applicationContext;
    private UserMapper userMapper;

    @Before
    public void init() {
        applicationContext = new ClassPathXmlApplicationContext("classpath:config/applicationContext.xml");
        userMapper = applicationContext.getBean(UserMapper.class);
    }

    @Test
    public void testSelectByPrimaryKey() {
        User user = userMapper.selectByPrimaryKey(2);
        System.out.println(user);
        /*
        ==>  Preparing: select id, name, gender, birthday, address from user where id = ?
        ==>  Parameters: 2(Integer)
         */
    }

    /**
     * 指定条件查询返回列表
     */
    @Test
    public void testSelectByExample() {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andNameLike("%郭%");
        List<User> userList = userMapper.selectByExample(userExample);
        userList.forEach(u -> System.out.println(u));
        /*
        ==>  Preparing: select id, name, gender, birthday, address from user WHERE ( name like ? )
        ==>  Parameters: %郭%(String)
         */
    }

    /**
     * 新增非空字段
     */
    @Test
    public void testInsertSelective() throws ParseException {
        userMapper.insertSelective(new User(null, "郭德纲", "男", new SimpleDateFormat("yyyy-MM-dd").parse("1997-1-1"), null));
        /*
        ==>  Preparing: insert into user ( name, gender, birthday ) values ( ?, ?, ? )
        ==>  Parameters: 郭德纲(String), 男(String), 1997-01-01(Date)
         */
    }

    /**
     * 新增所有
     */
    @Test
    public void testInsert() throws ParseException {
        userMapper.insert(new User(null, "郭德纲", "男", new SimpleDateFormat("yyyy-MM-dd").parse("1997-1-1"), null));
        /*
        ==>  Preparing: insert into user (id, name, gender, birthday, address) values (?, ?, ?, ?, ?)
        ==>  Parameters: null, 郭德纲(String), 男(String), 1997-01-01(Date), null
         */
    }

    /**
     * 修改非空字段
     */
    @Test
    public void testUpdateByPrimaryKeySelective() {
        userMapper.updateByPrimaryKeySelective(new User(1, "周华健", "男", null, null));
        /*
        ==>  Preparing: update user SET name = ?, gender = ? where id = ?
        ==>  Parameters: 周华健(String), 男(String), 1(Integer)
         */
    }

    /**
     * 修改所有
     */
    @Test
    public void testUpdateByPrimaryKey() {
        userMapper.updateByPrimaryKey(new User(1, "周华健", "男", null, null));
        /*
        ==>  Preparing: update user set name = ?, gender = ?, birthday = ?, address = ? where id = ?
        ==>  Parameters: 周华健(String), 男(String), null, null, 1(Integer)
         */
    }

    /**
     * 指定条件批量删除
     */
    @Test
    public void testDeleteByExample() {
        UserExample userExample = new UserExample();
        // 删除名字中包含郭字的记录
        userExample.createCriteria().andNameLike("%郭%");
        userMapper.deleteByExample(userExample);
        /*
        ==>  Preparing: delete from user WHERE ( name like ? )
        ==>  Parameters: %郭%(String)
         */
    }

    /**
     * 根据主键删除
     */
    @Test
    public void testDeleteByPrimaryKey() {
        userMapper.deleteByPrimaryKey(10);
        /*
        ==>  Preparing: delete from user where id = ?
        ==>  Parameters: 10(Integer)
         */
    }

    /**
     * 条件查询记录条数
     */
    @Test
    public void testCountByExample() {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andNameLike("%周%");
        long l = userMapper.countByExample(userExample);
        System.out.println(l);
        /*
        ==>  Preparing: select count(*) from user WHERE ( name like ? )
        ==>  Parameters: %周%(String)
         */
    }
}
相关文章
相关标签/搜索