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

  

  1. public static void main(String[] args) {
  2. Connection connection = null;
  3. PreparedStatement preparedStatement = null;
  4. ResultSet resultSet = null;
  5.  
  6. try {
  7. //加载数据库驱动
  8. Class.forName("com.mysql.jdbc.Driver");
  9.  
  10. //通过驱动管理类获取数据库链接
  11. connection = DriverManager.getConnection("jdbc:mysql://192.168.174.130:3306/SSM", "root", "root");
  12. //定义sql语句 ?表示占位符
  13. String sql = "select * from myUser where username = ?";
  14. //获取预处理statement
  15. preparedStatement = connection.prepareStatement(sql);
  16. //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
  17. preparedStatement.setString(1, "王五");
  18. //向数据库发出sql执行查询,查询出结果集
  19. resultSet = preparedStatement.executeQuery();
  20. //遍历查询结果集
  21. while(resultSet.next()){
  22. System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
  23. }
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. }finally{
  27. //释放资源
  28. if(resultSet!=null){
  29. try {
  30. resultSet.close();
  31. } catch (SQLException e) {
  32. // TODO Auto-generated catch block
  33. e.printStackTrace();
  34. }
  35. }
  36. if(preparedStatement!=null){
  37. try {
  38. preparedStatement.close();
  39. } catch (SQLException e) {
  40. // TODO Auto-generated catch block
  41. e.printStackTrace();
  42. }
  43. }
  44. if(connection!=null){
  45. try {
  46. connection.close();
  47. } catch (SQLException e) {
  48. // TODO Auto-generated catch block
  49. e.printStackTrace();
  50. }
  51. }
  52.  
  53. }
  54.  
  55. }

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

  综上: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、在源码中配置一个日志文件,用于打印日志

  1. # Global logging configuration
  2. log4j.rootLogger=DEBUG, stdout
  3. # Console output...
  4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  6. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

  5、配置核心配置文件

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

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

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

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

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

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

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

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

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

五、需求开发

  1、根据id查询一个客户

  1)建立客户表

  2)定义pojo类

  1. package com.clj.pojo;
  2.  
  3. import java.util.Date;
  4. import java.util.List;
  5.  
  6. public class User {
  7. private int id;
  8. private String username;// 用户姓名
  9. private String sex;// 性别
  10. private Date birthday;// 生日
  11. private String address;// 地址
  12. private List<Orders> ordersList;
  13.  
  14. public List<Orders> getOrdersList() {
  15. return ordersList;
  16. }
  17. public void setOrdersList(List<Orders> ordersList) {
  18. this.ordersList = ordersList;
  19. }
  20. public int getId() {
  21. return id;
  22. }
  23. public void setId(int id) {
  24. this.id = id;
  25. }
  26. public String getUsername() {
  27. return username;
  28. }
  29. public void setUsername(String username) {
  30. this.username = username;
  31. }
  32. public String getSex() {
  33. return sex;
  34. }
  35. public void setSex(String sex) {
  36. this.sex = sex;
  37. }
  38. public Date getBirthday() {
  39. return birthday;
  40. }
  41. public void setBirthday(Date birthday) {
  42. this.birthday = birthday;
  43. }
  44. public String getAddress() {
  45. return address;
  46. }
  47. public void setAddress(String address) {
  48. this.address = address;
  49. }
  50. @Override
  51. public String toString() {
  52. return "User [id=" + id + ", username=" + username + ", sex=" + sex
  53. + ", birthday=" + birthday + ", address=" + address + "]";
  54. }
  55.  
  56. }

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

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

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

  3)测试

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

  1.   @Test
  2. public void testFindUserById() throws Exception{
  3. String resource="SqlMapConfig.xml";
  4. InputStream inputStream=Resources.getResourceAsStream(resource);
  5. //创建工厂
  6. SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
  7. //通过工厂创建会话
  8. SqlSession openSession=factory.openSession();
  9. //第一个参数:所调用的sql语句:namespace+‘.’+SqlID
  10. //第二个参数:传入的参数
  11. User user=openSession.selectOne("test.findUserById",1);
  12. System.out.println(user);
  13. openSession.close();
  14. }

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

  

  2、根据用户名查询客户

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

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

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

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

  2)测试

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

  3、插入数据

  1)配置sql

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

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

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

  1. <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
  2. <selectKey resultType="java.lang.String" order="BEFORE"
  3. keyProperty="id">
  4. select uuid()
  5. </selectKey>
  6. insert into user(id,username,birthday,sex,address)
  7. values(#{id},#{username},#{birthday},#{sex},#{address})
  8. </insert>

  2) 测试

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

  4、删除更新数据

  1)配置sql语句

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

  2)测试

  1. @Test
  2. public void testDelUserById() throws Exception{
  3. String resource="SqlMapConfig.xml";
  4. InputStream inputstream=Resources.getResourceAsStream(resource);
  5. SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
  6. SqlSession openSession=factory.openSession();
  7. openSession.delete("test.delUserById",29);
  8. openSession.commit();
  9. openSession.close();
  10. }
  11. @Test
  12. public void testUpdateUserById()throws Exception{
  13. String resource="SqlMapConfig.xml";
  14. InputStream inputstream=Resources.getResourceAsStream(resource);
  15. SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
  16. SqlSession openSession=factory.openSession();
  17. User user=new User();
  18. user.setId(28);
  19. user.setUsername("佳先森");
  20. openSession.update("test.updateUserById",user);
  21. openSession.commit();
  22. openSession.close();
  23. }

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

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

  1. jdbc.driver=com.mysql.jdbc.Driver\t
  2. jdbc.url=jdbc:mysql://192.168.174.130:3306/SSM
  3. jdbc.username=root
  4. jdbc.password=root

  2、修改核心配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 引入链接数据库配置文件 -->
  7. <properties resource="db.properties"/>
  8. <!-- 和spring整合后 environments配置将废除-->
  9. <environments default="development">
  10. <environment id="development">
  11. <!-- 使用jdbc事务管理-->
  12. <transactionManager type="JDBC" />
  13. <!-- 数据库连接池-->
  14. <dataSource type="POOLED">
  15. <property name="driver" value="${jdbc.driver}" />
  16. <property name="url" value="${jdbc.url}" />
  17. <!--注意:这里必须是username,一定要规范-->
  18. <property name="username" value="${jdbc.username}" />
  19. <property name="password" value="${jdbc.password}" />
  20. </dataSource>
  21. </environment>
  22. </environments>
  23. <mappers><mapper resource="User.xml"/>
  24. </mappers>
  25. </configuration>

六、mybatis支持别名

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

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

七、mybatis引入映射文件写法

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

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

八、MyBatis之Dao层的开发方式

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

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

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

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

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

  1. </mapper>

    2)定义接口和实现类

  1. package com.clj.dao;
  2.  
  3. import java.util.List;
  4.  
  5. import com.clj.pojo.User;
  6.  
  7. public interface UserDao {
  8. public User findUserById(Integer id);
  9. public List<User> findUserByUserName(String username);
  10. }
  1. package com.clj.dao;
  2.  
  3. import java.util.List;
  4.  
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7.  
  8. import com.clj.pojo.User;
  9.  
  10. public class UserDaoImpl implements UserDao{
  11. private SqlSessionFactory sqlSessionFactory;
  12. //通过构造方法注入
  13. public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
  14. super();
  15. this.sqlSessionFactory = sqlSessionFactory;
  16. }
  17. @Override
  18. public User findUserById(Integer id) {
  19. //SqlSession是线程不安全的,所以他的最佳使用的范围在方法体内
  20. SqlSession opeanSession=sqlSessionFactory.openSession();
  21. User user=opeanSession.selectOne("test.findUserById",id);
  22. return user;
  23. }
  24. @Override
  25. public List<User> findUserByUserName(String username) {
  26. SqlSession opeanSession=sqlSessionFactory.openSession();
  27. List<User> list=opeanSession.selectList("test.findUserByUserName",username);
  28. return list;
  29. }
  30.  
  31. }

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

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

  4)定义测试类进行测试

  1. package com.clj.Test;
  2.  
  3. import java.io.InputStream;
  4. import java.util.List;
  5.  
  6. import org.apache.ibatis.io.Resources;
  7. import org.apache.ibatis.session.SqlSession;
  8. import org.apache.ibatis.session.SqlSessionFactory;
  9. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  10. import org.junit.Before;
  11. import org.junit.Test;
  12.  
  13. import com.clj.dao.UserDao;
  14. import com.clj.dao.UserDaoImpl;
  15. import com.clj.pojo.User;
  16.  
  17. public class UserDaoTest {
  18. private SqlSessionFactory factory;
  19.  
  20. //@Before作用在测试方法之前执行这个方法
  21. @Before
  22. public void setUp() throws Exception{
  23. String resource="SqlMapConfig.xml";
  24. InputStream inputstream=Resources.getResourceAsStream(resource);
  25. factory=new SqlSessionFactoryBuilder().build(inputstream);
  26. SqlSession openSession=factory.openSession();
  27. }
  28. @Test
  29. public void testFindUserById() throws Exception{
  30. //将初始化的工厂注入到实现类中
  31. UserDao userDao=new UserDaoImpl(factory);
  32. User user=userDao.findUserById(1);
  33. System.out.println(user);
  34. }
  35. @Test
  36. public void testFindUserByUserName() throws Exception{
  37. UserDao userDao=new UserDaoImpl(factory);
  38. List<User> list=userDao.findUserByUserName("王");
  39. System.out.println(list);
  40. }
  41. }

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

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

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

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

  1)定义接口

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

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

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

   两文件的目录关系

   

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

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

  ·4)测试类

  

  1. package com.clj.Test;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.ArrayList;
  6. import java.util.Date;
  7. import java.util.List;
  8.  
  9. import org.apache.ibatis.io.Resources;
  10. import org.apache.ibatis.session.SqlSession;
  11. import org.apache.ibatis.session.SqlSessionFactory;
  12. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  13. import org.junit.Before;
  14. import org.junit.Test;
  15.  
  16. import com.clj.UserMapper.UserMapper;
  17. import com.clj.pojo.CustomerOrders;
  18. import com.clj.pojo.Orders;
  19. import com.clj.pojo.QueryVo;
  20. import com.clj.pojo.User;
  21.  
  22. public class UserMapperTest {
  23. private static SqlSessionFactory factory;
  24.  
  25. //@Before作用在测试方法之前执行这个方法
  26. @Before
  27. public void setUp() throws Exception{
  28. String resource="SqlMapConfig.xml";
  29. InputStream inputstream=Resources.getResourceAsStream(resource);
  30. factory=new SqlSessionFactoryBuilder().build(inputstream);
  31. SqlSession openSession=factory.openSession();
  32. }
  33. @Test
  34. public void testFindUserById() throws Exception{
  35. SqlSession openSession=factory.openSession();
  36. //通过getMapper方法实列化接口
  37. UserMapper mapper=openSession.getMapper(UserMapper.class);
  38. User user=mapper.findUserById(1);
  39. System.out.println(user);
  40. }
  41.  
  42. }

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

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

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

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

  1. package com.clj.pojo;
  2.  
  3. import java.util.List;
  4.  
  5. //用于高级查询
  6. public class QueryVo {
  7. private User user;
  8. private List<Integer> ids;
  9.  
  10. public User getUser() {
  11. return user;
  12. }
  13.  
  14. public void setUser(User user) {
  15. this.user = user;
  16. }
  17.  
  18. public List<Integer> getIds() {
  19. return ids;
  20. }
  21.  
  22. public void setIds(List<Integer> ids) {
  23. this.ids = ids;
  24. }
  25. }

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

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

  3)定义接口

  1. public List<User> findUserbyVo(QueryVo vo);

  4)测试类

  1. public class UserMapperTest {
  2. private static SqlSessionFactory factory;
  3.  
  4. //@Before作用在测试方法之前执行这个方法
  5. @Before
  6. public void setUp() throws Exception{
  7. String resource="SqlMapConfig.xml";
  8. InputStream inputstream=Resources.getResourceAsStream(resource);
  9. factory=new SqlSessionFactoryBuilder().build(inputstream);
  10. SqlSession openSession=factory.openSession();
  11. }
  12.   @Test
  13. public void testFindUserByVo() throws Exception{
  14. SqlSession openSession=factory.openSession();
  15. //通过getMapper方法实列化接口
  16. UserMapper mapper=openSession.getMapper(UserMapper.class);
  17. QueryVo vo=new QueryVo();
  18. User user=new User();
  19. user.setUsername("张");
  20. user.setSex("1");
    vo.setUser(user);
  21. List<User> list=mapper.findUserbyVo(vo);
  22. System.out.println(list);
  23. openSession.close();
  24. }
  25. }

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

  1) 配置sql

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

  2) 配置接口

  1. public Integer findUserCount();

  3)测试

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

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

  1)配置sql

  方式一:局部配置

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

  方式二:全局配置

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
  5. <!--mapper接口代理实现编写轨则
  6. 1.映射文件中namespace要等于接口的全路径名
  7. 2.映射文件中sql语句id要等于接口的方法名称
  8. 3.映射文件中传入参数类型要等于接口方法的传入参数类型
  9. 4.映射文件中返回结果集类型等于接口方法的返回值类型
  10. -->
  11. <mapper namespace="com.clj.UserMapper.UserMapper">
  12. <!-- 封装sql条件,封装后可以重用
  13. id:此sql的唯一标识符
  14. -->
  15. <sql id="user_where">
  16. <where>
  17. <if test="username!=null and username !=''">
  18. and username like '%${username}%'
  19. </if>
  20. <if test="sex !=null and sex!=''">
  21. and sex=#{sex}
  22. </if>
  23. </where>
  24.  
  25. </sql>
  26. <select id="findUserByUserNameAndSex" parameterType="com.clj.pojo.User" resultType="com.clj.pojo.User">
  27. select * from user
  28. <!-- where标签作用:
  29. 会自动向sql语句中添加where关键字
  30. 会去掉第一个条件的and关键字
  31. <where>
  32. <if test="username!=null and username !=''">
  33. and username like '%${username}%'
  34. </if>
  35. <if test="sex !=null and sex!=''">
  36. and sex=#{sex}
  37. </if>
  38. </where>-->
  39. <!-- 调用全局条件 -->
  40. <include refid="user_where"/>
  41. </select>
  42. </mapper>

  2)接口

  1. public List<User> findUserByUserNameAndSex(User user);

  3)测试

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

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

  1)sql配置文件

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

  2)接口

  1. public List<User> findUserByIds(QueryVo vo);

  3)测试

  1. public class UserMapperTest {
  2. private static SqlSessionFactory factory;
  3.  
  4. //@Before作用在测试方法之前执行这个方法
  5. @Before
  6. public void setUp() throws Exception{
  7. String resource="SqlMapConfig.xml";
  8. InputStream inputstream=Resources.getResourceAsStream(resource);
  9. factory=new SqlSessionFactoryBuilder().build(inputstream);
  10. SqlSession openSession=factory.openSession();
  11. }
  12. @Test
  13. public void testFindUserbyIds() throws Exception{
  14. SqlSession opneSession=factory.openSession();
  15. UserMapper mapper=opneSession.getMapper(UserMapper.class);
  16. QueryVo vo=new QueryVo();
  17. List<Integer> ids=new ArrayList<Integer>();
  18. ids.add(1);
  19. ids.add(16);
  20. ids.add(28);
  21. ids.add(22);
  22. List<User> list=mapper.findUserByIds(vo);System.out.println(list);
  23. }
  24. }

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

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

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

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

  2)定义订单类

  1. package com.clj.pojo;
  2.  
  3. import java.util.Date;
  4.  
  5. public class Orders {
  6. private Integer id;
  7.  
  8. private Integer userId;
  9.  
  10. private String number;
  11.  
  12. private Date createtime;
  13.  
  14. private String note; public Integer getId() {
  15. return id;
  16. }
  17.  
  18. public void setId(Integer id) {
  19. this.id = id;
  20. }
  21.  
  22. public Integer getUserId() {
  23. return userId;
  24. }
  25.  
  26. public void setUserId(Integer userId) {
  27. this.userId = userId;
  28. }
  29.  
  30. public String getNumber() {
  31. return number;
  32. }
  33.  
  34. public void setNumber(String number) {
  35. this.number = number == null ? null : number.trim();
  36. }
  37.  
  38. public Date getCreatetime() {
  39. return createtime;
  40. }
  41.  
  42. public void setCreatetime(Date createtime) {
  43. this.createtime = createtime;
  44. }
  45.  
  46. public String getNote() {
  47. return note;
  48. }
  49.  
  50. public void setNote(String note) {
  51. this.note = note == null ? null : note.trim();
  52. }
  53. }

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

  1. package com.clj.pojo;
  2.  
  3. import java.util.Date;
  4.  
  5. //一对一:select a.*,b.id uid,username,birthday,sex,address
  6. //from order a,user b
  7. //where a.user_id=b.id
  8. //注意:不能用实体User代替他属性
  9. //缺点:java是单继承
  10. public class CustomerOrders extends Orders{
  11. private int uid;
  12. private String username;// 用户姓名
  13. private String sex;// 性别
  14. private Date birthday;// 生日
  15. private String address;// 地址
  16. public int getUid() {
  17. return uid;
  18. }
  19. public void setUid(int uid) {
  20. this.uid = uid;
  21. }
  22. public String getUsername() {
  23. return username;
  24. }
  25. public void setUsername(String username) {
  26. this.username = username;
  27. }
  28. public String getSex() {
  29. return sex;
  30. }
  31. public void setSex(String sex) {
  32. this.sex = sex;
  33. }
  34. public Date getBirthday() {
  35. return birthday;
  36. }
  37. public void setBirthday(Date birthday) {
  38. this.birthday = birthday;
  39. }
  40. public String getAddress() {
  41. return address;
  42. }
  43. public void setAddress(String address) {
  44. this.address = address;
  45. }
  46.  
  47. }

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

  4)配置sql语句

  1)在order类中定义user属性

  1. package com.clj.pojo;
  2.  
  3. import java.util.Date;
  4.  
  5. public class Orders {
  6. private Integer id;
  7.  
  8. private Integer userId;
  9.  
  10. private String number;
  11.  
  12. private Date createtime;
  13.  
  14. private String note;
  15.  
  16. private User user;
  17.  
  18. public User getUser() {
  19. return user;
  20. }
  21.  
  22. public void setUser(User user) {
  23. this.user = user;
  24. }
  25.  
  26. public Integer getId() {
  27. return id;
  28. }
  29.  
  30. public void setId(Integer id) {
  31. this.id = id;
  32. }
  33.  
  34. public Integer getUserId() {
  35. return userId;
  36. }
  37.  
  38. public void setUserId(Integer userId) {
  39. this.userId = userId;
  40. }
  41.  
  42. public String getNumber() {
  43. return number;
  44. }
  45.  
  46. public void setNumber(String number) {
  47. this.number = number == null ? null : number.trim();
  48. }
  49.  
  50. public Date getCreatetime() {
  51. return createtime;
  52. }
  53.  
  54. public void setCreatetime(Date createtime) {
  55. this.createtime = createtime;
  56. }
  57.  
  58. public String getNote() {
  59. return note;
  60. }
  61.  
  62. public void setNote(String note) {
  63. this.note = note == null ? null : note.trim();
  64. }
  65. }

  2)配置sql语句

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

  5)配置接口

  1. public List<CustomerOrders> findOrderAndUser1();

  6)定义测试类

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

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

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

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

  1. <!-- 一对一:手动映射:需要在order类中封装User这个属性 -->
  2. <!--
  3. id:resultMap的唯一标识
  4. type:将查询出的数据放入指定的对象中
  5. 注意:手动映射需要指定数据表中的字段名与java中pojo类中的属性名称对应的关系
  6. -->
  7. <resultMap type="com.clj.pojo.Orders" id="orderAndUserResultMap">
  8. <!--id标签指定主键字段对应关系
  9. column:列,数据库中的字段名称
  10. property:属性,java中pojo中的属性名称
  11. -->
  12. <id column="id" property="id"/>
  13. <!-- result:指定 非主键对应的关系-->
  14. <result column="user_id" property="userId"/>
  15. <result column="number" property="number"/>
  16. <result column="createtime" property="createtime"/>
  17. <result column="note" property="note"/>
  18. <!-- association:表示进行关联查询单条记录
           这个标签指定单个对象的对应关系
  19. property:表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中
  20. javaType:user属性中类型的路径
  21. -->
  22. <association property="user" javaType="com.clj.pojo.User">
           <!--查询结果的user_id列对应关联对象的id属性,这里是<id />表示user_id是关联查询对象的唯一标识-->
  23. <id column="uid" property="id"/>
           <!--查询结果的username列对应关联对象的username属性-->
  24. <result column="username" property="username"/>
  25. <result column="sex" property="sex"/>
  26. <result column="birthday" property="birthday"/>
  27. <result column="address" property="address"/>
  28. </association>
  29. </resultMap>
  30. <select id="findOrderAndUser2" resultMap="orderAndUserResultMap">
  31. select a.*,b.id uid,username,birthday,sex,address
  32. from orders a,user b
  33. where a.user_id=b.id
  34. </select>

  2)配置接口

  1. public List<Orders> findOrderAndUser2();

  3)测试类

  1.   @Test
  2. public void findOrderAndUser2() throws Exception{
  3. SqlSession opneSession=factory.openSession();
  4. UserMapper mapper=opneSession.getMapper(UserMapper.class);
  5. List<Orders> list=mapper.findOrderAndUser2();
  6. for(Orders order:list){
  7. System.out.println(order.getUserId()+"\t"+order.getCreatetime());
  8. }
  9. }

  需求七:一对多查询

  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集合属性

  1. package com.clj.pojo;
  2.  
  3. import java.util.Date;
  4. import java.util.List;
  5.  
  6. public class User {
  7. private int id;
  8. private String username;// 用户姓名
  9. private String sex;// 性别
  10. private Date birthday;// 生日
  11. private String address;// 地址
  12. private List<Orders> ordersList;
  13.  
  14. public List<Orders> getOrdersList() {
  15. return ordersList;
  16. }
  17. public void setOrdersList(List<Orders> ordersList) {
  18. this.ordersList = ordersList;
  19. }
  20. public int getId() {
  21. return id;
  22. }
  23. public void setId(int id) {
  24. this.id = id;
  25. }
  26. public String getUsername() {
  27. return username;
  28. }
  29. public void setUsername(String username) {
  30. this.username = username;
  31. }
  32. public String getSex() {
  33. return sex;
  34. }
  35. public void setSex(String sex) {
  36. this.sex = sex;
  37. }
  38. public Date getBirthday() {
  39. return birthday;
  40. }
  41. public void setBirthday(Date birthday) {
  42. this.birthday = birthday;
  43. }
  44. public String getAddress() {
  45. return address;
  46. }
  47. public void setAddress(String address) {
  48. this.address = address;
  49. }
  50. @Override
  51. public String toString() {
  52. return "User [id=" + id + ", username=" + username + ", sex=" + sex
  53. + ", birthday=" + birthday + ", address=" + address + "]";
  54. }
  55.  
  56. }

  3)配置sql

  1.   <!-- 一对多 -->
  2. <resultMap type="com.clj.pojo.User" id="userAndOrderMap">
  3. <id column="id" property="id"/>
  4. <result column="username" property="username"/>
  5. <result column="sex" property="sex"/>
  6. <result column="birthday" property="birthday"/>
  7. <result column="address" property="address"/>
  8. <!-- 指定对应的集合对象关系映射
  9. property:将数据放入User对象中的orderList属性中
  10. ofType:指定orderList属性泛型类型
  11. -->
  12. <collection property="ordersList" ofType="com.clj.pojo.Orders">
  13. <id column="oid" property="id"/>
  14. <result column="user_id" property="userId"/>
  15. <result column="number" property="number"/>
  16. <result column="createtime" property="createtime"/>
  17. <result column="note" property="note"/>
  18. <!-- 注意:这里不需要配置user属性,他是用于一对一时配置的属性,与这里无关 -->
  19. </collection>
  20. </resultMap>
  21. <select id="findUserAndOrders" resultMap="userAndOrderMap">
  22. select a.*,b.id oid,user_id,number,createtime
  23. from user a,order b where a.id=b.user_id
  24. </select>

  4)定义接口

  1. public List<User> findUserAndOrders();

  5)测试类

  1.      @Test
  2. public void findUserAndOrders() throws Exception{
  3. SqlSession opneSession=factory.openSession();
  4. UserMapper mapper=opneSession.getMapper(UserMapper.class);
  5. List<User> list=mapper.findUserAndOrders();
  6. System.out.println(list);
  7.  
  8. }

九、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包,否则会报错误

  1. Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
  2. PropertyAccessException : org.springframework.beans.MethodInvocationException: Property 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy
  3. at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:121)
  4. at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
  5. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1570)
  6. ... 41 more
  1. <dependency>
  2. <groupId>org.springframework</groupId>
  3. <artifactId>spring-jdbc</artifactId>
  4. <version>4.3..RELEASE</version>
  5. </dependency>
  6. <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
  7. <dependency>
  8. <groupId>org.mybatis</groupId>
  9. <artifactId>mybatis</artifactId>
  10. <version>3.4.</version>
  11. </dependency>
  12. <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
  13. <dependency>
  14. <groupId>commons-logging</groupId>
  15. <artifactId>commons-logging</artifactId>
  16. <version>1.2</version>
  17. </dependency>
  18. <!-- https://mvnrepository.com/artifact/log4j/log4j -->
  19.  
  20. <dependency>
  21. <groupId>log4j</groupId>
  22. <artifactId>log4j</artifactId>
  23. <version>1.2.</version>
  24. </dependency>
  25.  
  26. <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  27. <dependency>
  28. <groupId>mysql</groupId>
  29. <artifactId>mysql-connector-java</artifactId>
  30. <version>5.0.</version>
  31. </dependency>
  32. <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
  33. <dependency>
  34. <groupId>org.mybatis</groupId>
  35. <artifactId>mybatis-spring</artifactId>
  36. <version>1.3.</version>
  37. </dependency>
  38. <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
  39. <dependency>
  40. <groupId>org.springframework</groupId>
  41. <artifactId>spring-beans</artifactId>
  42. <version>4.3..RELEASE</version>
  43. </dependency>
  44. <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
  45. <dependency>
  46. <groupId>org.springframework</groupId>
  47. <artifactId>spring-context</artifactId>
  48. <version>4.3..RELEASE</version>
  49. </dependency>
  50. <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
  51. <dependency>
  52. <groupId>org.springframework</groupId>
  53. <artifactId>spring-core</artifactId>
  54. <version>4.3..RELEASE</version>
  55. </dependency>
  56. <!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
  57. <dependency>
  58. <groupId>org.springframework</groupId>
  59. <artifactId>spring-expression</artifactId>
  60. <version>4.3..RELEASE</version>
  61. </dependency>
  62. <!-- https://mvnrepository.com/artifact/org.aopalliance/com.springsource.org.aopalliance -->
  63. <dependency>
  64. <groupId>aopalliance</groupId>
  65. <artifactId>aopalliance</artifactId>
  66. <version>1.0</version>
  67. </dependency>
  68. <!-- https://mvnrepository.com/artifact/org.aspectj/org.aspectj.weaver -->
  69. <dependency>
  70. <groupId>org.aspectj</groupId>
  71. <artifactId>aspectjweaver</artifactId>
  72. <version>1.7.</version>
  73. </dependency>
  74. <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
  75. <dependency>
  76. <groupId>org.springframework</groupId>
  77. <artifactId>spring-aspects</artifactId>
  78. <version>4.3..RELEASE</version>
  79. </dependency>
  80. <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
  81. <dependency>
  82. <groupId>org.springframework</groupId>
  83. <artifactId>spring-tx</artifactId>
  84. <version>4.3..RELEASE</version>
  85. </dependency>
  86. <!-- https://mvnrepository.com/artifact/junit/junit -->
  87. <dependency>
  88. <groupId>junit</groupId>
  89. <artifactId>junit</artifactId>
  90. <version>4.12</version>
  91. <scope>test</scope>
  92. </dependency>
  93.  
  94. <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
  95. <dependency>
  96. <groupId>org.springframework</groupId>
  97. <artifactId>spring-test</artifactId>
  98. <version>4.3..RELEASE</version>
  99. <scope>test</scope>
  100. </dependency>
  101. <dependency>
  102. <groupId>c3p0</groupId>
  103. <artifactId>c3p0</artifactId>
  104. <version>0.9.1.2</version>
  105. </dependency>

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

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

  1. jdbc.driver=com.mysql.jdbc.Driver
  2. jdbc.url=jdbc:mysql://192.168.174.130:3306/SSM
  3. jdbc.username=root
  4. 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文件

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

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

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

  全部代码如下

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
  4. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
  8. 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
  9. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
  10.  
  11. <!-- 加载配置文件 -->
  12. <context:property-placeholder location="classpath:db.properties" />
  13. <!-- 数据库连接池 -->

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

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

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

  

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <typeAliases>
  7. <package name="com.clj.pojo"/>
  8. </typeAliases>
  9.  
  10. <mappers>
  11. <mapper resource="User.xml"/>
  12. <package name="com.clj.UserMapper"/>
  13. </mappers>
  14. </configuration>

  3、整合之Dao层的开发

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

    1))思路:

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

     2))接口定义和javaBean

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

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

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

  1. }
  1. @Component
  2. public class UserBean {
  3. private Integer id;
  4. private String username;
  5. private String age;
  6. private Integer money;
  7. //set/get方法
  8. }
  1. @Component
  2. public class QueryVo {
  3. private List<Integer> ids;
  4. }

     3))实现类定义

     实现类实现SqlSessionDaoSupport

  1. package com.clj.dao;
  2.  
  3. import java.util.List;
  4.  
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7. import org.mybatis.spring.support.SqlSessionDaoSupport;
  8.  
  9. import com.clj.pojo.User;
  10. //此时dao层要继承SqlSessionDaoSupport
  11. public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
  12. @Override
  13. public User findUserById(Integer id) {
  14. //SqlSession是线程不安全的,所以他的最佳使用的范围在方法体内
  15. SqlSession opeanSession=this.getSqlSession();
  16. User user=opeanSession.selectOne("test.findUserById",id);
  17. //opeanSession.close();
  18. return user;
  19.  
  20. }
  21. @Override
  22. public List<User> findUserByUserName(String username) {
  23. SqlSession opeanSession=this.getSqlSession();
  24. List<User> list=opeanSession.selectList("test.findUserByUserName",username);
  25. return list;
  26. }

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

  1.  

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

  1. }

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

     这里为dao层注入了sqlSessionFactory

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
  4. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
  8. 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
  9. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
  10.  
  11. <!-- 加载配置文件 -->
  12. <context:property-placeholder location="classpath:db.properties" />
  13. <!-- 数据库连接池 -->
  14. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  15. destroy-method="close">
  16. <property name="driverClassName" value="${jdbc.driver}" />
  17. <property name="url" value="${jdbc.url}" />
  18. <property name="username" value="${jdbc.username}" />
  19. <property name="password" value="${jdbc.password}" />
  20. <property name="maxActive" value="10" />
  21. <property name="maxIdle" value="5" />
  22. </bean>
     <context:component-scan base-package="com.aliance.entity"/>
  23. <!-- 整合后会话工厂归spring来管理 -->
  24. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  25. <!-- 指定mybatis核心配置文件 -->
  26. <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
  27. <!-- 指定会话工厂使用的数据源 -->
  28. <property name="dataSource" ref="dataSource"/>
  29. </bean>
  30. <!--配置原生Dao实现 -->
  31. <bean id="userDao" class="com.clj.dao.UserDaoImpl">
  32. <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
  33. </bean>
  34. </beans>

     5))SqlMap.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <typeAliases>
  7. <typeAlias type="com.aliance.entity.UserBean" alias="userBean"/>
  8.  
  9. </typeAliases>
  10. <mappers>
  11. <mapper resource="User.xml"/>
  12. </mappers>
  13. </configuration>

   6))User.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="test">
  6. <sql id="testWhere">
  7. <where>
  8. <if test="username!=null||username!=''">
  9. and username like '%${username}%'
  10. </if>
  11. <if test="age!=null">
  12. and age> #{age}
  13. </if>
  14.  
  15. </where>
  16. </sql>
  17. <select id="findUserByUserNameAndMoney" parameterType="userBean" resultType="userBean">
  18. select * from userinfo
  19. <include refid="testWhere"/>
  20. </select>
  21. <select id="findUserById" parameterType="com.aliance.entity.QueryVo" resultType="userBean">
  22. select * from userinfo
  23. <where>
  24. <if test="ids!=null">
  25. <foreach collection="ids" item="id" open="and id in (" close=")" separator=",">
  26. #{id}
  27. </foreach>
  28. </if>
  29. </where>
  30. </select>
  31.  
  32. </mapper>

    6)) 测试类

    方式一:

  1. package com.clj.Test;
  2.  
  3. import org.junit.Before;
  4. import org.junit.Test;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;
  7.  
  8. import com.clj.dao.UserDao;
  9. import com.clj.pojo.User;
  10.  
  11. public class UserDaoTest {
  12. private ApplicationContext applicationContext;
  13. @Before
  14. public void setUp() throws Exception{
  15. //这里可加classpath,也可不加
  16. String configLocation="classpath:applicationContext.xml";
  17. applicationContext=new ClassPathXmlApplicationContext(configLocation);
  18. }
  19. @Test
  20. public void testFindUserById() throws Exception{
  21. //获取UserDao对象,getBean中的字符串是在applcationContext.xml中神明的
  22. UserDao userDao=(UserDao)applicationContext.getBean("userDao");
  23. User user=userDao.findUserById(1);
  24. System.out.println(user);
  25. }
  26. }

  方式二:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration("classpath:ApplicationContext.xml")
  3. public class TestDemo1 {
  4. @Resource
  5. private ApplicationContext application;
  6. @Resource
  7. private UserBean userBean;
  8. @Resource
  9. private UserDao userDao;
  10. @Resource
  11. private QueryVo vo;
  12. @Test
  13. public void run2(){
  14. userDao=(UserDao) application.getBean("userDao");
  15. userBean.setUsername("李");
  16. userBean.setAge("11");
  17. List<UserBean> list=userDao.findUserByUserNameAndMoney(userBean);
  18. System.out.println(list);
  19. }
  20. @Test
  21. public void run3(){
  22. userDao=(UserDao) application.getBean("userDao");
  23. List<Integer> list=new ArrayList();
  24. list.add(1);
  25. list.add(3);
  26. list.add(6);
  27. vo.setIds(list);
  28. List<UserBean> temp=userDao.findUserById(vo);
  29. System.out.println(temp);
  30.  
  31. }
  32. }

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

  

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

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

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

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

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

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://www.mybatis.org/dtd/mybatis-3.0-mapper.dtd">
  5. <!--mapper接口代理实现编写轨则
  6. 1.映射文件中namespace要等于接口的全路径名
  7. 2.映射文件中sql语句id要等于接口的方法名称
  8. 3.映射文件中传入参数类型要等于接口方法的传入参数类型
  9. 4.映射文件中返回结果集类型等于接口方法的返回值类型
  10. -->
  11. <mapper namespace="com.clj.UserMapper.UserMapper">
  12. <!-- 封装sql条件,封装后可以重用
  13. id:此sql的唯一标识符
  14. -->
  15. <sql id="user_where">
  16. <where>
  17. <if test="username!=null and username !=''">
  18. and username like '%${username}%'
  19. </if>
  20. <if test="sex !=null and sex!=''">
  21. and sex=#{sex}
  22. </if>
  23. </where>
  24.  
  25. </sql>
  26.  
  27. <select id="findUserById" parameterType="int" resultType="com.clj.pojo.User">
  28. select * from user where id=#{id}
  29. </select>
  30. <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.clj.pojo.User">
  31. <!--select * from user where username like #{name} -->
  32. select * from user where username like '%${value}%'
  33. </select>
  34. <!-- 这里返回值使用的别名 -->
  35. <insert id="insertUser" parameterType="user">
  36. <selectKey keyProperty="id" order="AFTER" resultType="int">
  37. select LAST_INSERT_ID()
  38. </selectKey>
  39. insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
  40. </insert>
  41. <delete id="delUserById" parameterType="int">
  42. delete from user where id=#{id}
  43. </delete>
  44. <update id="updateUserById" parameterType="com.clj.pojo.User">
  45. update user set username=#{username} where id=#{id}
  46. </update>
  47. <select id="findUserbyVo" parameterType="com.clj.pojo.QueryVo" resultType="com.clj.pojo.User">
  48. select * from user where username like '%${user.username}%' and sex=#{user.sex}
  49. </select>
  50. <!-- 只有返回结果为一行一列的时候,那么返回值类型时可以指定类型为基本类型 -->
  51. <select id="findUserCount" resultType="int">
  52. select count(*) from user
  53. </select>
  54. <select id="findUserByUserNameAndSex" parameterType="com.clj.pojo.User" resultType="com.clj.pojo.User">
  55. select * from user
  56. <!-- where标签作用:
  57. 会自动向sql语句中添加where关键字
  58. 会去掉第一个条件的and关键字
  59. <where>
  60. <if test="username!=null and username !=''">
  61. and username like '%${username}%'
  62. </if>
  63. <if test="sex !=null and sex!=''">
  64. and sex=#{sex}
  65. </if>
  66. </where>-->
  67. <!-- 调用全局条件 -->
  68. <include refid="user_where"/>
  69. </select>
  70. <select id="findUserByIds" parameterType="com.clj.pojo.QueryVo" resultType="com.clj.pojo.User">
  71. <!-- select * from user where id in (1,16,28,22) -->
  72. select * from user
  73. <where>
  74. <!-- 这里的id指定是vo中的集合属性 -->
  75. <if test="ids!=null">
  76. <!-- foreach:循环传入的集合参数
  77. collection:传入的集合的变量名称
  78. item:每次循环将循环的数据放入这个变量中
  79. open:循环开始拼接的字符串
  80. close:循环结束拼接的字符串
  81. separator:循环中拼接的分隔符
  82. -->
  83. <foreach collection="ids" item="id" open="id in (" close=")" separator=",">
  84. #{id}
  85. </foreach>
  86. </if>
  87. </where>
  88. </select>
  89. <!-- 关于一对一查询 -->
  90. <!-- 方式一:自动映射 :利用类中的属性对应表中的字段
  91. 需要提供封装user和order属性的类-->
  92. <select id="findOrderAndUser1" resultType="com.clj.pojo.CustomerOrders">
  93. select a.*,b.id uid,username,birthday,sex,address
  94. from orders a,user b
  95. where a.user_id=b.id
  96. </select>
  97. <!-- 一对以:手动映射:需要在order类中封装User这个属性 -->
  98. <!--
  99. id:resultMap的唯一标识
  100. type:将查询出的数据放入指定的对象中
  101. 注意:手动映射需要指定数据表中的字段名与java中pojo类中的属性名称对应的关系
  102. -->
  103. <resultMap type="com.clj.pojo.Orders" id="orderAndUserResultMap">
  104. <!--id标签指定主键字段对应关系
  105. column:列,数据库中的字段名称
  106. property:属性,java中pojo中的属性名称
  107. -->
  108. <id column="id" property="id"/>
  109. <!-- result:指定 非主键对应的关系-->
  110. <result column="user_id" property="userId"/>
  111. <result column="number" property="number"/>
  112. <result column="createtime" property="createtime"/>
  113. <result column="note" property="note"/>
  114. <!-- 这个标签指定单个对象的对应关系
  115. property:指定将数据放入Orders中的user属性中
  116. javaType:user属性中类型的路径
  117. -->
  118. <association property="user" javaType="com.clj.pojo.User">
  119. <id column="uid" property="id"/>
  120. <result column="username" property="username"/>
  121. <result column="sex" property="sex"/>
  122. <result column="birthday" property="birthday"/>
  123. <result column="address" property="address"/>
  124. </association>
  125. </resultMap>
  126. <select id="findOrderAndUser2" resultMap="orderAndUserResultMap">
  127. select a.*,b.id uid,username,birthday,sex,address
  128. from orders a,user b
  129. where a.user_id=b.id
  130. </select>
  131. <!-- 一对多 -->
  132. <resultMap type="com.clj.pojo.User" id="userAndOrderMap">
  133. <id column="id" property="id"/>
  134. <result column="username" property="username"/>
  135. <result column="sex" property="sex"/>
  136. <result column="birthday" property="birthday"/>
  137. <result column="address" property="address"/>
  138. <!-- 指定对应的集合对象关系映射
  139. property:将数据放入User对象中的orderList属性中
  140. ofType:指定orderList属性泛型类型
  141. -->
  142. <collection property="ordersList" ofType="com.clj.pojo.Orders">
  143. <id column="oid" property="id"/>
  144. <result column="user_id" property="userId"/>
  145. <result column="number" property="number"/>
  146. <result column="createtime" property="createtime"/>
  147. <result column="note" property="note"/>
  148. <!-- 注意:这里不需要配置user属性,他是用于一对一时配置的属性,与这里无关 -->
  149. </collection>
  150. </resultMap>
  151. <select id="findUserAndOrders" resultMap="userAndOrderMap">
  152. select a.*,b.id oid,user_id,number,createtime
  153. from user a,order b where a.id=b.user_id
  154. </select>
  155. </mapper>

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

     方式一:手动配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
  4. xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
  8. 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
  9. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
  10.  
  11. <!-- 加载配置文件 -->
  12. <context:property-placeholder location="classpath:db.properties" />
  13. <!-- 数据库连接池 -->
  14. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  15. destroy-method="close">
  16. <property name="driverClassName" value="${jdbc.driver}" />
  17. <property name="url" value="${jdbc.url}" />
  18. <property name="username" value="${jdbc.username}" />
  19. <property name="password" value="${jdbc.password}" />
  20. <property name="maxActive" value="10" />
  21. <property name="maxIdle" value="5" />
  22. </bean>
  23. <!-- 整合后会话工厂归spring来管理 -->
  24. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  25. <!-- 指定mybatis核心配置文件 -->
  26. <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
  27. <!-- 指定会话工厂使用的数据源 -->
  28. <property name="dataSource" ref="dataSource"/>
  29. </bean>
  30. <!--配置原生Dao实现 -->
  31. <bean id="userDao" class="com.clj.dao.UserDaoImpl">
  32. <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
  33. </bean>
  34. <!-- 动态代理方式:Mappper接口代理实现-->
  35. <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  36. 配置Mapper接口的全路径名称,其中property name="mapperInterface"是根据主类来配置的
  37. <property name="mapperInterface" value="com.clj.UserMapper.UserMapper"/>
  38. <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
  39. </bean>
  40. </beans>
  1. public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
  2.  
  3. private Class<T> mapperInterface;
  4. }

  其中MapperScannerConfigurer的路径为

  

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

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

     其中MapperScannerConfigurer的路径为

  

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

  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "https://www.mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <typeAliases>
  7. <package name="com.clj.pojo"/>
  8. </typeAliases>
  9.  
  10. <mappers>
  11. <mapper resource="User.xml"/>
  12. <!-- <package name="com.clj.UserMapper"/> -->
  13. </mappers>
  14. </configuration>

    4))测试类

  1. package com.clj.Test;
  2.  
  3. import org.junit.Before;
  4. import org.junit.Test;
  5. import org.springframework.context.ApplicationContext;
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;
  7.  
  8. import com.clj.UserMapper.UserMapper;
  9. import com.clj.pojo.User;
  10.  
  11. public class UserMapperTest {
  12. private ApplicationContext applicationContext;
  13. @Before
  14. public void setUp() throws Exception{
  15. //这里可加classpath,也可不加
  16. String configLocation="classpath:applicationContext.xml";
  17. applicationContext=new ClassPathXmlApplicationContext(configLocation);
  18. }
  19. @Test
  20. public void testFindUserById()throws Exception{
         //方式一:手动配置:通过bean中id获取
  21. UserMapper userMapper=(UserMapper) applicationContext.getBean("userMapper");
         //方式二:扫描方式:通过mapper接口名进行获取,注意,getBean()中的值是通过类名第一个字母小写得到
  22. User user=userMapper.findUserById(1);
  23. System.out.println(user);
  24.  
  25. }
  26. }

十、MyBatis之逆向工程

  1、逆向工程作用

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

  2、快速部署环境

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

   

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

  3)创建log4j.properties文件(只是打印日志,可以不配置)

  1. # Global logging configuration
  2. log4j.rootLogger=DEBUG, stdout
  3. # Console output...
  4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  6. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

  4)配置generatorConfig.xml文件

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE generatorConfiguration
  3. PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  4. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
  5.  
  6. <generatorConfiguration>
  7. <context id="testTables" targetRuntime="MyBatis3">
  8. <commentGenerator>
  9. <!-- 是否去除自动生成的注释 true:是 : false:否 -->
  10. <property name="suppressAllComments" value="true" />
  11. </commentGenerator>
  12. <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
  13. <jdbcConnection driverClass="com.mysql.jdbc.Driver"
  14. connectionURL="jdbc:mysql://192.168.174.130:3306/SSM" userId="root"
  15. password="root">
  16. </jdbcConnection>
  17. <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
  18. connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"
  19. userId="yycg"
  20. password="yycg">
  21. </jdbcConnection> -->
  22.  
  23. <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
  24. NUMERIC 类型解析为java.math.BigDecimal -->
  25. <javaTypeResolver>
  26. <property name="forceBigDecimals" value="false" />
  27. </javaTypeResolver>
  28.  
  29. <!-- targetProject:生成PO类的位置 -->
  30. <javaModelGenerator targetPackage="cn.clj.pojo"
  31. targetProject=".\src">
  32. <!-- enableSubPackages:是否让schema作为包的后缀 -->
  33. <property name="enableSubPackages" value="false" />
  34. <!-- 从数据库返回的值被清理前后的空格 -->
  35. <property name="trimStrings" value="true" />
  36. </javaModelGenerator>
  37. <!-- targetProject:mapper映射文件生成的位置 -->
  38. <sqlMapGenerator targetPackage="cn.clj.mapper"
  39. targetProject=".\src">
  40. <!-- enableSubPackages:是否让schema作为包的后缀 -->
  41. <property name="enableSubPackages" value="false" />
  42. </sqlMapGenerator>
  43. <!-- targetPackage:mapper接口生成的位置 -->
  44. <javaClientGenerator type="XMLMAPPER"
  45. targetPackage="cn.clj.mapper"
  46. targetProject=".\src">
  47. <!-- enableSubPackages:是否让schema作为包的后缀 -->
  48. <property name="enableSubPackages" value="false" />
  49. </javaClientGenerator>
  50. <!-- 指定数据库表 -->
  51. <table tableName="orders"></table>
  52. <table tableName="user"></table>
  53. <!-- <table schema="" tableName="sys_user"></table>
  54. <table schema="" tableName="sys_role"></table>
  55. <table schema="" tableName="sys_permission"></table>
  56. <table schema="" tableName="sys_user_role"></table>
  57. <table schema="" tableName="sys_role_permission"></table> -->
  58.  
  59. <!-- 有些表的字段需要指定java类型
  60. <table schema="" tableName="">
  61. <columnOverride column="" javaType="" />
  62. </table> -->
  63. </context>
  64. </generatorConfiguration>

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

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

  

   6)创建启动类

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

  1. package com.clj.Test;
  2.  
  3. import java.io.File;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6.  
  7. import org.mybatis.generator.api.MyBatisGenerator;
  8. import org.mybatis.generator.config.Configuration;
  9. import org.mybatis.generator.config.xml.ConfigurationParser;
  10. import org.mybatis.generator.internal.DefaultShellCallback;
  11.  
  12. public class StartService {
  13. public void generator() throws Exception{
  14. List<String> warnings = new ArrayList<String>();
  15. boolean overwrite = true;
  16. File configFile = new File("config/generatorConfig.xml");
  17. ConfigurationParser cp = new ConfigurationParser(warnings);
  18. Configuration config = cp.parseConfiguration(configFile);
  19. DefaultShellCallback callback = new DefaultShellCallback(overwrite);
  20. MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
  21. callback, warnings);
  22. myBatisGenerator.generate(null);
  23. }
  24. public static void main(String[] args) throws Exception {
  25. try {
  26. StartService startService = new StartService();
  27. startService.generator();
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. }

 

 

 

  

Mybatis框架入门的更多相关文章

  1. 一看就懂的Mybatis框架入门笔记

    本篇为初学Mybatis框架时的入门笔记,整理发出 Spring集成Mybatis https://www.cnblogs.com/yueshutong/p/9381590.html SpringBo ...

  2. MyBatis框架入门之(二)

    在本篇文章中,没有对细节进行处理的很好,有很多晓得细节的遗漏,本文只是一个简单的快速的入门 MyBatis的快速入门 导入MyBatis框架jar包 配置文件 SqlSessionFactoryBui ...

  3. mybatis框架入门程序:演示通过mybatis实现数据库的查询操作

    我们现在工程基于的数据库见“https://www.cnblogs.com/wyhluckdog/p/10147754.html”这篇博文. 1.mybatis下载 mybatis的代码由githua ...

  4. Java Mybatis 框架入门教程

    一.Mybatis介绍 MyBatis是一款一流的支持自定义SQL.存储过程和高级映射的持久化框架.MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去 设置参数和获取检索结果.MyBati ...

  5. 优于jdbc的mybatis框架入门

    1.什么是mybatis? MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架. MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及对结果集的检索. MyB ...

  6. mybatis框架入门程序:演示通过mybatis实现数据库的修改操作

    1.mybatis的基本配置工作可以在我的这篇博客中查看:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2.修改用户的配置文件: <upd ...

  7. mybatis框架入门程序:演示通过mybatis实现数据库的删除操作

    1.mybatis的基本配置工作可以在我的这篇博客中查看:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2.删除用户的映射文件: <!-- ...

  8. mybatis框架入门程序:演示通过mybatis实现数据库的插入操作中实现返回结果的获取

    1.mybatis实现数据库的插入操作可以查看https://www.cnblogs.com/wyhluckdog/p/10149895.html这篇博文,这里面的插入操作没有返回结果,所以这篇博文就 ...

  9. mybatis框架入门程序:演示通过mybatis实现数据库的添加操作

    1.mybatis的基本配置准备在我的这篇博文中可以找到:https://www.cnblogs.com/wyhluckdog/p/10149480.html 2. 映射文件: 在User.xml中添 ...

随机推荐

  1. java volatile关键字解析

    volatile是什么 volatile在java语言中是一个关键字,用于修饰变量.被volatile修饰的变量后,表示这个变量在不同线程中是共享,编译器与运行时都会注意到这个变量是共享的,因此不会对 ...

  2. 使用Ant打包Java后台程序

    概述 本文通过一个简单的Java Application例子描述如何用ANT完成基本的程序打包工作.包含文件拷贝.编译.打包三部分:完成这三部就可以得到一个可运行的程序包了. ANT的安装,环境变量的 ...

  3. NOI2001炮兵阵地

    题目传送门 PS:本道题目建议在对状压dp有一定了解的基础下学习,如有不懂可以先去学一下状压dp入门 题目大意:给你n*m个格子,有些格子可以用来部署军队,用P表示,有些则不能,用H表示,如果在一个格 ...

  4. MongoDB系列一(查询).

    一.简述 MongoDB中使用find来进行查询.查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合.默认情况下,"_id"这个键总是被返回,即便是没有指定要返回这 ...

  5. windows下 python3.5+tensorflow 安装

    个人随笔,备忘参考 首先最近的tensorflow 对python3.5.x友好,我先装了Python3.6,查其他的一些博客说出现问题,后来重装3.5.0.下载用迅雷,超快. 安装比较简单,官网下载 ...

  6. 搭建maven

    1. 下载安装包 打开网址https://maven.apache.org/download.cgi,找到下面这个文件进行下载 2. 解压安装 解压刚下载地文件到自己想要得目录下 3. 配置环境变量 ...

  7. 如何关闭常见浏览器的 HSTS 功能

    在安装配置 SSL 证书时,可以使用一种能使数据传输更加安全的Web安全协议,即在服务器端上开启HSTS (HTTP Strict Transport Security).它告诉浏览器只能通过HTTP ...

  8. 5分钟学习spark streaming之 轻松在浏览器运行和修改Word Counts

    方案一:根据官方实例,下载预编译好的版本,执行以下步骤: nc -lk 9999 作为实时数据源 ./bin/run-example org.apache.spark.examples.sql.str ...

  9. 聊聊Docker

    为什么是Docker 进入21世纪,继互联网之后,云计算开始大放异彩.云计算是互联网发展后期的必然方向,反过来,云计算也进一步推动了互联网的发展.云计算模式最关键的突破就是资源使用方式的改变. 云计算 ...

  10. 以太坊挖矿源码:ethash算法

    本文具体分析以太坊的共识算法之一:实现了POW的以太坊共识引擎ethash. 关键字:ethash,共识算法,pow,Dagger Hashimoto,ASIC,struct{},nonce,FNV ...