MyBatis----06----连接池&&注解开发

1. MyBatis中的连接池的使用

1.1 MyBatis中自带的连接池配置

<!-- 数据源配置,使用连接池 type:数据源类型 POOLED:使用连接池作为数据库,将会用PooledDataSourceFactory作为提供连接池的类 INPOOLED:不使用连接池作为数据库,将会有UnpooledDataSourceFactory作为连接池的类 JNDI:不做了解 --> <dataSource type="POOLED"> <!-- 四大连接信息配置--> <property name="driver" value="${driverClass}"/> <property name="url" value="${jdbcUrl}"/> <property name="username" value="com.wenyibi.futuremail.model.User@654b5f68"/> <property name="password" value="${password}"/> </dataSource> 

在实际开发中,不管是POLOLED还是UNPOOLED都不适用;
实际开发肯定是要用连接池的,所以排除UNPOOLED;
MyBatis自带的连接池设计较为简单,并不适合大型项目开发;
那么我们如何替换MyBtis中的连接池呢?

1.2 使用c3p0替换MyBatis连接池

  • 引入c3p0连接池
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.5</version> </dependency> 
  • 自定义连接池工厂继承UnpooledDataSourceFactory
//自定义C3P0连接工厂 public class C3p0DataSourceFactory extends UnpooledDataSourceFactory { public C3p0DataSourceFactory(){ //使用C3P0数据源 this.dataSource = new ComboPooledDataSource(); } } 
  • 在MyBatis中配置使用自定义的连接池工厂
<!-- 数据源配置,使用连接池 type:数据源类型 POOLED:使用连接池作为数据库,将会用PooledDataSourceFactory作为提供连接池的类 INPOOLED:不使用连接池作为数据库,将会有UnpooledDataSourceFactory作为连接池的类 JNDI:不做了解 填写完整的类名:指定某个自定义连接池工厂 --> <dataSource type="com.leo.datasource.C3p0DataSourceFactory"> <!-- 四大连接信息配置 注意:不同的连接池参数的建是不同的,注意检查 --> <property name="driverClass" value="${driverClass}"/> <property name="jdbcUrl" value="${jdbcUrl}"/> <property name="user" value="com.wenyibi.futuremail.model.User@654b5f68"/> <property name="password" value="${password}"/> </dataSource> 

2. 注解开发MyBatis

我们之前使用MyBatis时,SQL语句都是写在XML文件中的,但是写在XML中并不是唯一的方式。
MyBatis还支持将SQL语句下载接口方法的注解上。
使用注解来配置SQL,不需要维护额外的配置文件,从而提高开发效率。
但是需要注意的是,MyBatis设计的初衷上来说,作者就是希望将SQL从代码中抽取出来,解耦到配置中,注解方式或多或少有些违背初衷。
其次,注解开发动态SQL查询,以及复杂SQL查询时,注解方式相比XML反而更加麻烦复杂,所以注解开发只适用于SQL语句相对较为简单的场景

2.1 注解开发准备工作

使用注解开发,首先在著配置文件中引入注册接口:

<!-- 方式2:通过Mapper类指定Mapper.xml配置文件 该方式MyBatis会自动从指定类所在包下查询与接口相同的XML 同时该方式支持注解 --> <mapper class="com.leo.mapper.UserMapper" /> 

2.2 单表CRUD演示

public interface UserMapper { //@Select:指定查询语句的注解,相当于xml中的<select>元素 @Select("select * from t_user where id = #{id}") User findById(int id); @Update("update t_user set name = #{param2} where id =#{param1}") void update(int id,String name); @Insert("insert into t_user values(null,#{name},#{password})") int save(User user); @Delete("delete from t_user where id = #{id}") int delete(int id); } 

保存时获得主键值:

  • 方式1:适用于主键自增
@Insert("insert into t_user values(null,#{name},#{password})") /** * 适用于主键自增 * useGeneratedKeys:指定是否需要生成保存生成得键值 * keyProperty:将主键生成值存入到实体的那个属性中 */ @Options(useGeneratedKeys = true,keyProperty = "id") int save(User user); 
  • 方式2:适用于任何数据情况
@Insert("insert into t_user values(null,#{name},#{password})") /** * @SelectKey:相当于之前的<selectKey/>元素 * ststement:填写获得插入记录主键值的SQL * keyColumn:填写主键列名 * keyProperty:填写主键属性名 * before:实行ststement语句时机,是否再insert语句之前 * resultType:主键值的类型 */ @SelectKey(statement = "select LAST_INSERT_ID()",keyColumn = "id",keyProperty = "id",before = false,resultType = Integer.class) int save2(User user); 

注意:不同的数据库中statement属性指定的语句是不同的,需要进行修改。

2.3 多表CRUD演示

2.3.1 一对多 | 多对多

案例:一个用户下有多个账户信息
UserMapper中:根据用户找到用户下的所有账户

//通过User查询与User关联的Account /** * @Results:相当于<resultMap>,用于映射对象与查询结果 * id:指定当前映射的属性是否为主键属性,默认值是false * column:指定列名 * property:指定对应的属性名 * many:该属性属于一对多属性 * @Many:一对多映射属性配置 * select:一对多的关联数据从哪个查询中获取 * FetchType:抓取策略 * LAZY:延迟加载 * EAGER:立即加载 * * 如果结果集中的列名与属性名是对应的,那么我们无需配置映射。 */ @Results({ @Result(id = true,column = "id" ,property = "id"), @Result(id = false,column = "name",property = "name"), @Result(column = "password",property = "password"), //一对多关联配置 @Result(column = "id",property = "accounts",many = @Many(select = "com.leo.mapper.AccountMapper.findByUid",fetchType = FetchType.LAZY)) }) @Select("select * from t_user where id = #{id}") User findById2(int id); } 

AccountMapper中:

//根据用户id,查询用户关联的账户 @Select("select * from account where uid = #{uid}") List<Account> findByUid(int uid); 

2.3.2 多对一 | 一对一

案例:一个账户对应唯一一个用户
AccountMapper中: 根据账户找到账户关联的用户

//根据id查询account @Select("select * from account where id = #{id}") //@One:表达一对一或多对一的关联关系 @Results( @Result(column = "uid",property = "user",one = @One(select = "com.leo.mapper.UserMapper.findById",fetchType = FetchType.LAZY)) ) Account findById(int id); 

UserMapper中:

//@Select:指定查询语句的注解,相当于xml中的<select>元素 @Select("select * from t_user where id = #{id}") User findById(int id);