Mybatis----(1)

主要内容
1、对原生态jdbc程序(单独使用jdbc开发)问题总结
2、mybatis框架原理
3、mybatis入门程序
4、mybatis开发dao两种方法
5、mybatis配置文件SqlMapConfig.xml
6、mybatis核心
7、mybatis的动态sql

1、原生态jdbc程序中问题总结

下面的代码,有很多问题,总结如下:

public class JdbcTest {
    
    public static void main(String[] args) {
        
        //数据库连接
        Connection connection = null;
        //预编译的Statement,使用预编译的Statement提高数据库性能
        PreparedStatement preparedStatement = null;
        //结果 集
        ResultSet resultSet = null;
        
        try {
            //加载数据库驱动
            Class.forName("com.mysql.jdbc.Driver");
            
            //通过驱动管理类获取数据库链接
            connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "mysql");
            //定义sql语句 ?表示占位符
            String sql = "select * from user where username = ?";
            //获取预处理statement
            preparedStatement = connection.prepareStatement(sql);
            //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
            preparedStatement.setString(1, "王五");
            //向数据库发出sql执行查询,查询出结果集
            resultSet =  preparedStatement.executeQuery();
            //遍历查询结果集
            while(resultSet.next()){
                System.out.println(resultSet.getString("id")+"  "+resultSet.getString("username"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            //释放资源
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(preparedStatement!=null){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }


    }
}

1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。
设想:使用数据库连接池管理数据库连接。

2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。
设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
设想:将sql语句及占位符号和参数全部配置在xml中。

4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。
设想:将查询的结果集,自动映射成java对象。

2、mybatis框架

2-1 mybatis是什么?

mybatis是一个持久层的框架,是apache下的顶级项目。

mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。

mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

2-2 mybatis框架

Mybatis----(1)_第1张图片
image.png

2-3 mybatis使用步骤(基础方式1)

Mybatis----(1)_第2张图片
image.png

1 读取SqlMapConfig.xml文件,其中配置了Mybatis的基本信息

private SqlSessionFactory sqlSessionFactory;

    // 此方法是在执行testFindUserById之前执行
    @Before
    public void setUp() throws Exception {
        // 创建sqlSessionFactory

        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 创建会话工厂,传入mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);
    }

2 配置mybatis的运行环境,数据源、事务等。


    
    
        
        
    


    
    
        
            
            
            
            
                
                
                
                
            
        
    


    
        
    


3 新建xml的sql对象



    
    

    
    


    
        
            SELECT LAST_INSERT_ID()
        
        insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
   


    
        delete from user where id=#{id}
    


    
        update user set sex=#{sex}
        where id=#{id}
    


4 定义接口和实现类

接口

public interface UserDao {

    //根据id查询用户信息
    public User findUserById(int id) throws Exception;

    //根据用户名列查询用户列表
    public List findUserByName(String name) throws Exception;

    //添加用户信息
    public void insertUser(User user) throws Exception;

    //删除用户信息
    public void deleteUser(int id) throws Exception;


    public void updateUser(User user) throws Exception;
}

实现类

// 需要向dao实现类中注入SqlSessionFactory
    // 这里通过构造方法注入
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }


    public User findUserById(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

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

        // 释放资源
        sqlSession.close();

        return user;
    }

    public List findUserByName(String name) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        List list = sqlSession.selectList("test.findUserByName", name);

        // 释放资源
        sqlSession.close();

        return list;
    }

    public void insertUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //执行插入操作
        sqlSession.insert("test.insertUser", user);

        // 提交事务
        sqlSession.commit();

        // 释放资源
        sqlSession.close();
    }

    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //执行插入操作
        sqlSession.delete("test.deleteUser", id);

        // 提交事务
        sqlSession.commit();

        // 释放资源
        sqlSession.close();
    }

    public void updateUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //执行插入操作
        sqlSession.update("test.updateUser", user);

        // 提交事务
        sqlSession.commit();

        // 释放资源
        sqlSession.close();
    }

3 mybatis使用方式(2)---- mapper代理

可以发现上述的接口实现类中存在大量的重复代码

所以Mybatis还提供直接通过xml来执行的sql语句的方式

1 测试类代码

 @Test
    public void findUserId() throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //调用userMapper的方法
        User user = userMapper.findUserId(1);
        
        System.out.println(user);
    }

    


上面的测试类代码是可以直接通过匹配xml中的id调用xml的sql语句执行查询的
User user = userMapper.findUserId(1);
,简化了实现类的书写。

开发规范:

1、在mapper.xml中namespace等于mapper接口地址
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

总结:
以上开发规范主要是对下边的代码进行统一生成:

User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);

4 SqlMapConfig.xml的配置

mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)

4-1 properties属性

可将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。
在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。

将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties。

    
    
        
        
    

建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX

4-2 settings全局参数配置

mybatis框架在运行时可以调整一些运行参数。
比如:开启二级缓存、开启延迟加载。。

全局参数将会影响mybatis的运行行为。

4-3 typeAliases(别名)重点

在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。

如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。


    
        
        
         
        
        
        
    

4-4 mappers(映射配置)

1 通过resource加载单个映射文件

2 通过mapper接口加载单个mapper

3 批量加载mapper(推荐使用)


        
        
        
        
        
        
        
        
        
        
    

5 输入映射(parameterType)和输出映射(resultType)

输入映射:

通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型。

注意:
1、使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
2、如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
3、只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象,不一致的属性的值为null。

输出映射:

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象,不一致的属性的值为null。

    
    
    @Test
    public void testFindUserList() throws Exception {
        
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        //由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
//      userCustom.setSex("1");
        userCustom.setUsername("小明");
        //传入多个id
        List ids = new ArrayList();
        ids.add(1);
        ids.add(10);
        ids.add(16);
        //将ids通过userQueryVo传入statement中
        userQueryVo.setIds(ids);
        userQueryVo.setUserCustom(userCustom);
        //调用userMapper的方法
        
        List list = userMapper.findUserList(userQueryVo);
        
        System.out.println(list);       
    }

6 动态sql

mybatis核心。对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。

nobibi,show you my code

 @Test
    public void findUserCount() throws Exception  {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //创建UserMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //创建包装对象,设置查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("张三丰");
        userQueryVo.setUserCustom(userCustom);

        int count = userMapper.findUserCount(userQueryVo);

        System.out.println(count);
    }

    
        
          
              and user.sex = #{userCustom.sex}
          
            
                and user.username LIKE '%${userCustom.username}%'
            
        
    

    

感觉这个功能很NP,要善用。

你可能感兴趣的:(Mybatis----(1))